diff options
Diffstat (limited to 'omegalib')
105 files changed, 0 insertions, 35538 deletions
diff --git a/omegalib/CMakeLists.txt b/omegalib/CMakeLists.txt deleted file mode 100644 index 501d67a..0000000 --- a/omegalib/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(omegalib) - -if(NOT DEFINED ROSEHOME) - message( FATAL_ERROR "ROSEHOME is not set, try use -DROSEHOME" ) -endif() -if (NOT DEFINED BOOSTHOME) - message( FATAL_ERROR "BOOSTHOME is not set, try use -DBOOSTHOME" ) -endif() - -set(OMEGAROOT ${PROJECT_SOURCE_DIR}) - -add_subdirectory(omega) -add_subdirectory(codegen) diff --git a/omegalib/LICENSE b/omegalib/LICENSE deleted file mode 100644 index f0fbe69..0000000 --- a/omegalib/LICENSE +++ /dev/null @@ -1,705 +0,0 @@ -Omega+ and CodeGen+ -Copyright (C) 2005-2011 Chun Chen -All rights reserved. - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. 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 -them 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 prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. 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. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey 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; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - 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. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -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. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - 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 -state 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 3 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, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program 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, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<http://www.gnu.org/licenses/>. - - The GNU 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 Lesser General -Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. - -============================================================================== - -The Omega Project -Copyright (C) 1994-2000 by the Omega Project -All rights reserved. - -NOTICE: This software is provided ``as is'', without any -warranty, including any implied warranty for merchantability or -fitness for a particular purpose. Under no circumstances shall -the Omega Project or its agents be liable for any use of, misuse -of, or inability to use this software, including incidental and -consequential damages. - -License is hereby given to use, modify, and redistribute this -software, in whole or in part, for any purpose, commercial or -non-commercial, provided that the user agrees to the terms of this -copyright notice, including disclaimer of warranty, and provided -that this copyright notice, including disclaimer of warranty, is -preserved in the source code and documentation of anything derived -from this software. Any redistributor of this software or -anything derived from this software assumes responsibility for -ensuring that any parties to whom such a redistribution is made -are fully aware of the terms of this license and disclaimer. - -The Omega project can be contacted at omega@cs.umd.edu -or http://www.cs.umd.edu/projects/omega diff --git a/omegalib/codegen/CMakeLists.txt b/omegalib/codegen/CMakeLists.txt deleted file mode 100644 index 79bdcb4..0000000 --- a/omegalib/codegen/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -set(CG_SRC - src/codegen.cc - src/CG.cc - src/CG_stringBuilder.cc - src/CG_utils.cc - - src/rose_attributes.cc - src/CG_roseBuilder.cc - src/CG_roseRepr.cc - ) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings") - -include_directories( - include - ${OMEGAROOT}/omega/include - ${ROSEHOME}/include/rose - ${BOOSTHOME}/include - ) - -add_library(codegen - ${CG_SRC} - ) - -add_dependencies(codegen omega) - -install(TARGETS codegen - ARCHIVE DESTINATION lib) -install(DIRECTORY include - DESTINATION .) diff --git a/omegalib/codegen/include/code_gen/CG.h b/omegalib/codegen/include/code_gen/CG.h deleted file mode 100644 index ce56768..0000000 --- a/omegalib/codegen/include/code_gen/CG.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef _CG_H -#define _CG_H - -#include <omega/Relation.h> -#include <basic/BoolSet.h> -#include <code_gen/CG_outputBuilder.h> -#include <vector> - -namespace omega { - -class CodeGen; - -struct CG_result { - CodeGen *codegen_; - BoolSet<> active_; - - CG_result() { codegen_ = NULL; } - virtual ~CG_result() { /* not responsible for codegen_ */ } - - virtual CG_result *recompute(const BoolSet<> &parent_active, const Relation &known, const Relation &restriction) = 0; - virtual int populateDepth() = 0; - virtual std::pair<CG_result *, Relation> liftOverhead(int depth, bool propagate_up) = 0; - virtual Relation hoistGuard() = 0; - virtual void removeGuard(const Relation &guard) = 0; - virtual CG_outputRepr *printRepr(int indent, CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const = 0; - CG_outputRepr *printRepr(CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts) const; - std::string printString() const; - int num_level() const; - virtual CG_result *clone() const = 0; - virtual void dump(int indent) const {} - void dump() { dump(0); } -}; - - -struct CG_split: public CG_result { - std::vector<Relation> restrictions_; - std::vector<CG_result *> clauses_; - - CG_split(CodeGen *codegen, const BoolSet<> &active, const std::vector<Relation> &restrictions, const std::vector<CG_result *> &clauses) { - codegen_ = codegen; - active_ = active; - restrictions_ = restrictions; - clauses_ = clauses; - } - ~CG_split() { - for (int i = 0; i < clauses_.size(); i++) - delete clauses_[i]; - } - - CG_result *recompute(const BoolSet<> &parent_active, const Relation &known, const Relation &restriction); - int populateDepth(); - std::pair<CG_result *, Relation> liftOverhead(int depth, bool propagate_up); - Relation hoistGuard(); - void removeGuard(const Relation &guard); - CG_outputRepr *printRepr(int indent, CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const; - CG_result *clone() const; - void dump(int indent) const; - -private: - std::vector<CG_result *> findNextLevel() const; -}; - - -struct CG_loop: public CG_result { - int level_; - CG_result *body_; - - Relation known_; - Relation restriction_; - Relation bounds_; - Relation guard_; - bool needLoop_; - int depth_; - - CG_loop(CodeGen *codegen, const BoolSet<> &active, int level, CG_result *body) { - codegen_ = codegen; - active_ = active; - level_ = level; - body_ = body; - } - ~CG_loop() { delete body_; } - - CG_result *recompute(const BoolSet<> &parent_active, const Relation &known, const Relation &restriction); - int populateDepth(); - std::pair<CG_result *, Relation> liftOverhead(int depth, bool propagate_up); - Relation hoistGuard(); - void removeGuard(const Relation &guard); - CG_outputRepr *printRepr(int indent, CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const; - CG_outputRepr *printRepr(bool do_print_guard, int indent, CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const; - CG_result *clone() const; - void dump(int indent) const; -}; - - - -struct CG_leaf: public CG_result { - Relation known_; - std::map<int, Relation> guards_; - - CG_leaf(CodeGen *codegen, const BoolSet<> &active) { - codegen_ = codegen; - active_ = active; - } - ~CG_leaf() {} - - CG_result *recompute(const BoolSet<> &parent_active, const Relation &known, const Relation &restriction); - int populateDepth() { return 0; } - std::pair<CG_result *, Relation> liftOverhead(int depth, bool propagate_up); - Relation hoistGuard(); - void removeGuard(const Relation &guard); - CG_outputRepr *printRepr(int indent, CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const; - CG_result *clone() const; - void dump(int indent) const; -}; - -} - -#endif diff --git a/omegalib/codegen/include/code_gen/CG_outputBuilder.h b/omegalib/codegen/include/code_gen/CG_outputBuilder.h deleted file mode 100644 index 19dc440..0000000 --- a/omegalib/codegen/include/code_gen/CG_outputBuilder.h +++ /dev/null @@ -1,161 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - abstract base class of comiler IR code builder - - Notes: - All "CG_outputRepr *" parameters are consumed inside the the function - unless explicitly stated otherwise, i.e., not valid after the call. - Parameter "indent" normally not used except it is used in unstructured - string output for correct indentation. - - History: - 04/17/96 created - Lei Zhou - 05/02/08 clarify integer floor/mod/ceil definitions, -chen - 05/31/08 use virtual clone to implement CreateCopy, -chun - 08/05/10 clarify NULL parameter allowance, -chun -*****************************************************************************/ - -#ifndef _CG_OUTPUTBUILDER_H -#define _CG_OUTPUTBUILDER_H - -#include <code_gen/CG_outputRepr.h> - -#include <string> -#include <vector> - -namespace omega { - -//! abstract base class of comiler IR code builder -class CG_outputBuilder { -public: - CG_outputBuilder() {} - virtual ~CG_outputBuilder() {} - - //! substitute variables in stmt - virtual CG_outputRepr *CreateSubstitutedStmt(int indent, CG_outputRepr *stmt, - const std::vector<std::string> &vars, - std::vector<CG_outputRepr *> &subs) const = 0; - - //! assignment stmt generation - virtual CG_outputRepr *CreateAssignment(int indent, CG_outputRepr *lhs, - CG_outputRepr *rhs) const = 0; - - //! function invocation generation - virtual CG_outputRepr *CreateInvoke(const std::string &funcName, - std::vector<CG_outputRepr *> &argList) const = 0; - - //! comment generation - virtual CG_outputRepr *CreateComment(int indent, - const std::string &commentText) const = 0; - - //! Attribute generation - virtual CG_outputRepr* CreateAttribute(CG_outputRepr *control, - const std::string &commentText) const = 0; - //! Pragma Attribute - virtual CG_outputRepr* CreatePragmaAttribute(CG_outputRepr *scopeStmt, int looplevel, const std::string &pragmaText) const = 0; - - //! Prefetch Attribute - virtual CG_outputRepr* CreatePrefetchAttribute(CG_outputRepr *scopeStmt, int looplevel, const std::string &arrName, int hint) const = 0; - - //! generate if stmt, true/false stmt can be NULL but not the condition - virtual CG_outputRepr *CreateIf(int indent, CG_outputRepr *guardCondition, - CG_outputRepr *true_stmtList, - CG_outputRepr *false_stmtList) const = 0; - - //! generate loop inductive variable (loop control structure) - virtual CG_outputRepr *CreateInductive(CG_outputRepr *index, - CG_outputRepr *lower, - CG_outputRepr *upper, - CG_outputRepr *step) const = 0; - - //! generate loop stmt from loop control and loop body, NULL parameter allowed - virtual CG_outputRepr *CreateLoop(int indent, CG_outputRepr *control, - CG_outputRepr *stmtList) const = 0; - - //! copy operation, NULL parameter allowed. - /*! - * this function makes pointer handling uniform regardless NULL status - */ - virtual CG_outputRepr *CreateCopy(CG_outputRepr *original) const { - if (original == NULL) - return NULL; - else - return original->clone(); - } - - //! basic integer number creation - virtual CG_outputRepr *CreateInt(int num) const = 0; - virtual bool isInteger(CG_outputRepr *op) const = 0; - - - //! basic identity/variable creation - virtual CG_outputRepr *CreateIdent(const std::string &varName) const = 0; - - //! Addition operations, NULL parameter means 0, - virtual CG_outputRepr *CreatePlus(CG_outputRepr *lop, CG_outputRepr *rop) const = 0; - //! Subtraction operations, NULL parameter means 0, - virtual CG_outputRepr *CreateMinus(CG_outputRepr *lop, CG_outputRepr *rop) const = 0; - //! Multiplication operations, NULL parameter means 0, - virtual CG_outputRepr *CreateTimes(CG_outputRepr *lop, CG_outputRepr *rop) const = 0; - //! Division operations, NULL parameter means 0, - /*! - * integer division truncation method undefined, only use when lop is known - * to be multiple of rop, otherwise use integer floor instead - */ - virtual CG_outputRepr *CreateDivide(CG_outputRepr *lop, CG_outputRepr *rop) const { - return CreateIntegerFloor(lop, rop); - } - - //! integer floor functions, NULL parameter means 0 - /*! - * second parameter must be postive (i.e. b > 0 below), otherwise function undefined - * - * floor(a, b) - * * = a/b if a >= 0 - * * = (a-b+1)/b if a < 0 - */ - virtual CG_outputRepr *CreateIntegerFloor(CG_outputRepr *lop, CG_outputRepr *rop) const = 0; - //! integer mod functions, NULL parameter means 0 - /*! - * second parameter must be postive (i.e. b > 0 below), otherwise function undefined - * - * mod(a, b) = a-b*floor(a, b) where result must lie in range [0,b) - */ - virtual CG_outputRepr *CreateIntegerMod(CG_outputRepr *lop, CG_outputRepr *rop) const { - CG_outputRepr *lop2 = CreateCopy(lop); - CG_outputRepr *rop2 = CreateCopy(rop); - return CreateMinus(lop2, CreateTimes(rop2, CreateIntegerFloor(lop, rop))); - } - //! integer ceil functions, NULL parameter means 0 - /*! - * second parameter must be postive (i.e. b > 0 below), otherwise function undefined - * - * ceil(a, b) = -floor(-a, b) or floor(a+b-1, b) or floor(a-1, b)+1 - */ - virtual CG_outputRepr *CreateIntegerCeil(CG_outputRepr *lop, CG_outputRepr *rop) const { - return CreateMinus(NULL, CreateIntegerFloor(CreateMinus(NULL, lop), rop)); - } - - //! binary logical operation, NULL parameter means TRUE - virtual CG_outputRepr *CreateAnd(CG_outputRepr *lop, CG_outputRepr *rop) const = 0; - - //! binary conditional Greater than or equal to - virtual CG_outputRepr *CreateGE(CG_outputRepr *lop, CG_outputRepr *rop) const { - return CreateLE(rop, lop); - } - //! binary conditional Less than or equal to - virtual CG_outputRepr *CreateLE(CG_outputRepr *lop, CG_outputRepr *rop) const = 0; - //! binary conditional equal to - virtual CG_outputRepr *CreateEQ(CG_outputRepr *lop, CG_outputRepr *rop) const = 0; - - //! join stmts together, NULL parameter allowed - virtual CG_outputRepr *StmtListAppend(CG_outputRepr *list1, CG_outputRepr *list2) const = 0; -}; - -} - -#endif diff --git a/omegalib/codegen/include/code_gen/CG_outputRepr.h b/omegalib/codegen/include/code_gen/CG_outputRepr.h deleted file mode 100644 index 0897007..0000000 --- a/omegalib/codegen/include/code_gen/CG_outputRepr.h +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - abstract base class of compiler IR code wrapper - - Notes: - - History: - 04/17/96 - Lei Zhou - created -*****************************************************************************/ - -#ifndef _CG_OUTPUTREPR_H -#define _CG_OUTPUTREPR_H - -namespace omega { - -class CG_outputRepr { -public: - CG_outputRepr() {} - //! shallow delete - virtual ~CG_outputRepr() { } - virtual CG_outputRepr *clone() const = 0; - //! delete actual IR code wrapped inside - virtual void clear() { } - virtual void dump() const {} -}; - -} - -#endif diff --git a/omegalib/codegen/include/code_gen/CG_roseBuilder.h b/omegalib/codegen/include/code_gen/CG_roseBuilder.h deleted file mode 100644 index 5dad663..0000000 --- a/omegalib/codegen/include/code_gen/CG_roseBuilder.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef CG_roseBuilder_h -#define CG_roseBuilder_h - -#include <basic/Tuple.h> -#include <code_gen/rose_attributes.h> -#include <code_gen/CG_outputBuilder.h> -#include <code_gen/CG_roseRepr.h> -#include <string> - -namespace omega { - -class CG_roseBuilder : public CG_outputBuilder { -public: - CG_roseBuilder(int isFortran, SgGlobal* global, SgGlobal* global_scope, SgSymbolTable* symtab1, SgSymbolTable* symtab2, SgNode* root); - ~CG_roseBuilder(); - - //! substitute variables in stmt - CG_outputRepr *CreateSubstitutedStmt(int indent, CG_outputRepr *stmt, - const std::vector<std::string> &vars, - std::vector<CG_outputRepr *> &subs) const; - - - - //! assignment generation - CG_outputRepr* CreateAssignment(int indent, CG_outputRepr* lhs, - CG_outputRepr* rhs) const; - - //! function invocation generation - CG_outputRepr* CreateInvoke(const std::string &funcName, - std::vector<CG_outputRepr *> &argList) const; - - //! comment generation - CG_outputRepr* CreateComment(int indent, const std::string &commentText) const; - //! Attribute generation - CG_outputRepr* CreateAttribute(CG_outputRepr *control, - const std::string &commentText) const; - //! Pragma Attribute - CG_outputRepr* CreatePragmaAttribute(CG_outputRepr *scopeStmt, int looplevel, - const std::string &pragmaText) const; - - //! Prefetch Attribute - CG_outputRepr* CreatePrefetchAttribute(CG_outputRepr *scopeStmt, int looplevel, - const std::string &arrName, int hint) const; - - //! if stmt gen operations - CG_outputRepr* CreateIf(int indent, CG_outputRepr* guardCondition, - CG_outputRepr* true_stmtList, CG_outputRepr* false_stmtList) const; - - //! inductive variable generation, to be used in CreateLoop as control - CG_outputRepr* CreateInductive(CG_outputRepr* index, - CG_outputRepr* lower, - CG_outputRepr* upper, - CG_outputRepr* step) const; - - //! loop stmt generation - CG_outputRepr* CreateLoop(int indent, CG_outputRepr* control, - CG_outputRepr* stmtList) const; - - CG_outputRepr* CreateInt(int num ) const; - bool isInteger(CG_outputRepr *op) const; - CG_outputRepr* CreateIdent(const std::string &varName) const; - - //! binary arithmetic operations - CG_outputRepr* CreatePlus(CG_outputRepr* lop, CG_outputRepr* rop) const; - CG_outputRepr* CreateMinus(CG_outputRepr* lop, CG_outputRepr* rop) const; - CG_outputRepr* CreateTimes(CG_outputRepr* lop, CG_outputRepr* rop) const; - CG_outputRepr* CreateIntegerFloor(CG_outputRepr* lop, CG_outputRepr* rop) const; - CG_outputRepr* CreateIntegerMod(CG_outputRepr* lop, CG_outputRepr* rop) const; - - //! binary logical operations - CG_outputRepr* CreateAnd(CG_outputRepr* lop, CG_outputRepr* rop) const; - - //--------------------------------------------------------------------------- - // binary relational operations - //--------------------------------------------------------------------------- - // CG_outputRepr* CreateGE(CG_outputRepr*, CG_outputRepr*) const; - CG_outputRepr* CreateLE(CG_outputRepr* lop, CG_outputRepr* rop) const; - CG_outputRepr* CreateEQ(CG_outputRepr* lop, CG_outputRepr* rop) const; - - //--------------------------------------------------------------------------- - // stmt list gen operations - //--------------------------------------------------------------------------- - CG_outputRepr* - StmtListAppend(CG_outputRepr* list1, CG_outputRepr* list2) const; - - CG_outputRepr* CreateDim3(const char* varName, CG_outputRepr* arg1, CG_outputRepr* arg2, CG_outputRepr* arg3 = NULL) const; - - // Manu:: added for fortran support - bool isInputFortran() const; - -private: - SgSymbolTable *symtab_; - SgSymbolTable *symtab2_; - SgNode* root_; - SgGlobal* global_; - SgGlobal* global_scope; - int isFortran; // Manu:: added for fortran support -}; - -extern char *k_ocg_comment; -std::vector<SgVarRefExp *>substitute(SgNode *tnl, const SgVariableSymbol *sym, SgExpression *expr,SgNode* root) ; - - - - -} // namespace - -#endif diff --git a/omegalib/codegen/include/code_gen/CG_roseRepr.h b/omegalib/codegen/include/code_gen/CG_roseRepr.h deleted file mode 100644 index 28553e7..0000000 --- a/omegalib/codegen/include/code_gen/CG_roseRepr.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef CG_roseRepr_h -#define CG_roseRepr_h - -#include <code_gen/CG_outputRepr.h> -#include "rose.h" - -namespace omega { - -class CG_roseRepr : public CG_outputRepr { - friend class CG_roseBuilder; -public: - CG_roseRepr(); - CG_roseRepr(SgNode *tnl); - CG_roseRepr(SgExpression *exp); - CG_roseRepr(SgStatementPtrList* stmtlist); - - ~CG_roseRepr(); - CG_outputRepr *clone() const; - void clear(); - - SgNode* GetCode() const; - SgStatementPtrList* GetList() const; - SgExpression *GetExpression() const; - - - - - //--------------------------------------------------------------------------- - // Dump operations - //--------------------------------------------------------------------------- - void Dump() const; -private: - // only one of _tnl and _op would be active at any time, depending on - // whether it is building a statement list or an expression tree - SgNode *tnl_; - SgExpression *op_; - SgStatementPtrList *list_; - void DumpFileHelper(SgNode* node, FILE* fp) const; - //operand op_; -}; - - - -} // namespace - -#endif diff --git a/omegalib/codegen/include/code_gen/CG_stringBuilder.h b/omegalib/codegen/include/code_gen/CG_stringBuilder.h deleted file mode 100644 index 09d3503..0000000 --- a/omegalib/codegen/include/code_gen/CG_stringBuilder.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _CG_STRINGBUILDER_H -#define _CG_STRINGBUILDER_H - -#include <code_gen/CG_outputBuilder.h> -#include <code_gen/CG_stringRepr.h> - -namespace omega { - -class CG_stringBuilder: public CG_outputBuilder { -public: - CG_stringBuilder() {} - ~CG_stringBuilder() {} - bool isInteger(CG_outputRepr *op) const; - CG_stringRepr *CreateSubstitutedStmt(int indent, CG_outputRepr *stmt, const std::vector<std::string> &vars, std::vector<CG_outputRepr *> &subs) const; - CG_stringRepr *CreateAssignment(int indent, CG_outputRepr *lhs, CG_outputRepr *rhs) const; - CG_stringRepr *CreateInvoke(const std::string &funcName, std::vector<CG_outputRepr *> &argList) const; - CG_stringRepr *CreateComment(int indent, const std::string &commentText) const; - CG_stringRepr* CreateAttribute(CG_outputRepr *control, - const std::string &commentText) const; - CG_outputRepr *CreatePragmaAttribute(CG_outputRepr *scopeStmt, int looplevel, const std::string &pragmaText) const; - CG_outputRepr *CreatePrefetchAttribute(CG_outputRepr *scopeStmt, int looplevel, const std::string &arrName, int hint) const; - CG_stringRepr *CreateIf(int indent, CG_outputRepr *guardCondition, CG_outputRepr *true_stmtList, CG_outputRepr *false_stmtList) const; - CG_stringRepr *CreateInductive(CG_outputRepr *index, CG_outputRepr *lower, CG_outputRepr *upper, CG_outputRepr *step) const; - CG_stringRepr *CreateLoop(int indent, CG_outputRepr *control, CG_outputRepr *stmtList) const; - CG_stringRepr *CreateInt(int num) const; - CG_stringRepr *CreateIdent(const std::string &varName) const; - CG_stringRepr *CreatePlus(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateMinus(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateTimes(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateDivide(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateIntegerFloor(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateIntegerMod(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateIntegerCeil(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateAnd(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateGE(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateLE(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *CreateEQ(CG_outputRepr *lop, CG_outputRepr *rop) const; - CG_stringRepr *StmtListAppend(CG_outputRepr *list1, CG_outputRepr *list2) const; -}; - - -} - -#endif diff --git a/omegalib/codegen/include/code_gen/CG_stringRepr.h b/omegalib/codegen/include/code_gen/CG_stringRepr.h deleted file mode 100644 index a6df85d..0000000 --- a/omegalib/codegen/include/code_gen/CG_stringRepr.h +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - pseudo string code wrapper - - Notes: - - History: - 04/17/96 - Lei Zhou - created -*****************************************************************************/ - -#ifndef _CG_STRINGREPR_H -#define _CG_STRINGREPR_H - -#include <code_gen/CG_outputRepr.h> -#include <string> -#include <iostream> - -namespace omega { - -class CG_stringRepr: public CG_outputRepr { -private: - std::string s_; - -public: - CG_stringRepr() {} - CG_stringRepr(const std::string &s) { s_ = s; } - ~CG_stringRepr() {} - CG_outputRepr *clone() const { return new CG_stringRepr(s_); } - void dump() const { std::cout << s_ << std::endl; } - - //--------------------------------------------------------------------------- - // basic operation - //--------------------------------------------------------------------------- - std::string GetString() const { return s_; } -}; - -} - -#endif diff --git a/omegalib/codegen/include/code_gen/CG_utils.h b/omegalib/codegen/include/code_gen/CG_utils.h deleted file mode 100755 index a6128bc..0000000 --- a/omegalib/codegen/include/code_gen/CG_utils.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _CG_UTILS_H -#define _CG_UTILS_H - -#include <omega.h> -#include <code_gen/CG_outputBuilder.h> -#include <basic/BoolSet.h> -#include <vector> -#include <set> -#include <map> - -namespace omega { - -class CG_loop; - -CG_outputRepr *output_inequality_repr(CG_outputBuilder *ocg, const GEQ_Handle &inequality, Variable_ID v, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly, std::set<Variable_ID> excluded_floor_vars = std::set<Variable_ID>()); -CG_outputRepr *output_substitution_repr(CG_outputBuilder *ocg, const EQ_Handle &equality, Variable_ID v, bool apply_v_coef, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); -CG_outputRepr *output_upper_bound_repr(CG_outputBuilder *ocg, const GEQ_Handle &inequality, Variable_ID v, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); -CG_outputRepr *output_lower_bound_repr(CG_outputBuilder *ocg, const GEQ_Handle &inequality, Variable_ID v, const EQ_Handle &stride_eq, Variable_ID wc, const Relation &R, const Relation &known, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); - -CG_outputRepr *output_ident(CG_outputBuilder *ocg, const Relation &R, Variable_ID v, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); -std::pair<CG_outputRepr *, std::pair<CG_outputRepr *, int> > output_assignment(CG_outputBuilder *ocg, const Relation &R, int level, const Relation &known, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); -CG_outputRepr *output_loop(CG_outputBuilder *ocg, const Relation &R, int level, const Relation &known, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); -CG_outputRepr *output_guard(CG_outputBuilder *ocg, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); -std::vector<CG_outputRepr *> output_substitutions(CG_outputBuilder *ocg, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); - -bool bound_must_hit_stride(const GEQ_Handle &inequality, Variable_ID v, const EQ_Handle &stride_eq, Variable_ID wc, const Relation &bounds, const Relation &known); -std::pair<EQ_Handle, int> find_simplest_assignment(const Relation &R, Variable_ID v, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly = std::vector<std::pair<CG_outputRepr *, int> >()); -std::pair<bool, GEQ_Handle> find_floor_definition(const Relation &R, Variable_ID v, std::set<Variable_ID> excluded_floor_vars = std::set<Variable_ID>()); -std::pair<EQ_Handle, Variable_ID> find_simplest_stride(const Relation &R, Variable_ID v); -Variable_ID replicate_floor_definition(const Relation &R, const Variable_ID floor_var, Relation &r, F_Exists *f_exists, F_And *f_root, std::map<Variable_ID, Variable_ID> &exists_mapping); - -Relation pick_one_guard(const Relation &R, int level = 0); -CG_outputRepr *leaf_print_repr(BoolSet<> active, const std::map<int, Relation> &guards, - CG_outputRepr *guard_repr, const Relation &known, - int indent, CG_outputBuilder *ocg, const std::vector<int> &remap, - const std::vector<Relation> &xforms, const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); -CG_outputRepr *loop_print_repr(const std::vector<CG_loop *> &loops, int start, int end, - const Relation &guard, CG_outputRepr *guard_repr, - int indent, CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly); - -} - -#endif diff --git a/omegalib/codegen/include/code_gen/code_gen.h b/omegalib/codegen/include/code_gen/code_gen.h deleted file mode 100644 index abfab7c..0000000 --- a/omegalib/codegen/include/code_gen/code_gen.h +++ /dev/null @@ -1,47 +0,0 @@ -#if !defined(Already_Included_code_gen) -#define Already_Included_code_gen - -#include <basic/Tuple.h> -#include <omega/Relation.h> -#include <code_gen/CG.h> -#include <code_gen/CG_outputRepr.h> -#include <code_gen/CG_outputBuilder.h> - -namespace omega { - -typedef Tuple<int> IntTuple; -typedef Tuple<Relation> SetTuple; -typedef Tuple<SetTuple> SetTupleTuple; -typedef Tuple<Relation> RelTuple; -typedef Tuple<RelTuple> RelTupleTuple; - -CG_outputRepr *MMGenerateCode(CG_outputBuilder* ocg, - Tuple<Relation> &T, Tuple<Relation> &old_IS, - const Tuple<CG_outputRepr *> &stmt_content, - Relation &known, int effort=1); -std::string MMGenerateCode(Tuple<Relation> &T, Tuple<Relation> &old_IS, Relation &known, - int effort=1); - -//protonu-adding a new variant to keep Gabe's code happy -CG_outputRepr* MMGenerateCode(CG_outputBuilder* ocg, RelTuple &T, SetTuple &old_IS, - const Tuple<CG_outputRepr *> &stmt_content, Relation &known, - Tuple< IntTuple >& smtNonSplitLevels_, - std::vector< std::pair<int, std::string> > syncs_, - const Tuple< Tuple<std::string> >& loopIdxNames_, - int effort=1); -//end-protonu - -struct Polyhedra { - int last_level; - Tuple<Relation> transformations; - Relation known; - - Tuple<int> remap; // after initial iteration space's disjoint set splitting, the new statement number maps to old statement number - Tuple<Tuple<Relation> > projected_nIS; - - Polyhedra(const Tuple<Relation> &T, const Tuple<Relation> &old_IS, const Relation &known = Relation::Null()); - ~Polyhedra() {} -}; - -} -#endif diff --git a/omegalib/codegen/include/code_gen/codegen.h b/omegalib/codegen/include/code_gen/codegen.h deleted file mode 100755 index cb63bfd..0000000 --- a/omegalib/codegen/include/code_gen/codegen.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _CODEGEN_H -#define _CODEGEN_H - -#include <omega/Relation.h> -#include <code_gen/CG.h> -#include <code_gen/CG_outputBuilder.h> -#include <vector> -#include <string> - -namespace omega { - -class CodeGen { -public: - static const std::string loop_var_name_prefix; - static const int var_substitution_threshold; - -protected: - //! projected_IS_[level-1][new stmt#] - std::vector<std::vector<Relation> > projected_IS_; - //! transformations[original stmt#] - std::vector<Relation> xforms_; - //! no need to generate code for constraints satisfied in known - Relation known_; - //! map new stmt# to original stmt# - std::vector<int> remap_; - -public: - CodeGen(const std::vector<Relation> &xforms, const std::vector<Relation> &IS, const Relation &known = Relation::Null(), - std::vector< std::vector<int > > smtNonSplitLevels_ = std::vector< std::vector<int > >(), - std::vector< std::vector<std::string> > loopIdxNames_ = std::vector< std::vector<std::string> >(), - std::vector< std::pair<int, std::string> > syncs_ = std::vector< std::pair<int, std::string> >() - ); - ~CodeGen() {} - - CG_result *buildAST(int effort = 1); - int num_level() const { return projected_IS_.size(); } - -private: - CG_result *buildAST(int level, const BoolSet<> &active, bool split_on_const, const Relation &restriction); - - friend class CG_result; - friend class CG_split; - friend class CG_loop; - friend class CG_leaf; -}; - -} -#endif diff --git a/omegalib/codegen/include/code_gen/codegen_error.h b/omegalib/codegen/include/code_gen/codegen_error.h deleted file mode 100755 index 06ecc2b..0000000 --- a/omegalib/codegen/include/code_gen/codegen_error.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _CODEGEN_ERROR_H -#define _CODEGEN_ERROR_H - -#include <stdexcept> - -namespace omega { - -struct codegen_error: public std::runtime_error { - codegen_error(const std::string &msg): std::runtime_error("codegen error: " + msg) {} -}; - - -} -#endif - diff --git a/omegalib/codegen/include/code_gen/output_repr.h b/omegalib/codegen/include/code_gen/output_repr.h deleted file mode 100644 index 254e71b..0000000 --- a/omegalib/codegen/include/code_gen/output_repr.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef OUTPUT_REPR_H -#define OUTPUT_REPR_H - -#include <omega.h> -#include <code_gen/CG_outputBuilder.h> -#include <code_gen/CG_outputRepr.h> -#include <vector> -#include <set> - -namespace omega { -extern int last_level; - -CG_outputRepr* outputIdent(CG_outputBuilder* ocg, const Relation &R, Variable_ID v, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -std::pair<CG_outputRepr *, bool> outputAssignment(CG_outputBuilder *ocg, const Relation &R_, Variable_ID v, Relation &enforced, CG_outputRepr *&if_repr, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -std::pair<CG_outputRepr *, bool> outputBounds(CG_outputBuilder* ocg, const Relation &bounds, Variable_ID v, int indent, Relation &enforced, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -Tuple<CG_outputRepr*> outputSubstitution(CG_outputBuilder* ocg, const Relation &R, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -CG_outputRepr* outputStatement(CG_outputBuilder* ocg, CG_outputRepr *stmt, int indent, const Relation &mapping, const Relation &known, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -CG_outputRepr* outputGuard(CG_outputBuilder* ocg, const Relation &guards_in, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -CG_outputRepr* output_as_guard(CG_outputBuilder* ocg, const Relation &guards_in, Constraint_Handle e, bool is_equality, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -CG_outputRepr* output_EQ_strides(CG_outputBuilder* ocg, const Relation &guards_in, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -CG_outputRepr* output_GEQ_strides(CG_outputBuilder* ocg, const Relation &guards_in, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -CG_outputRepr *outputLBasRepr(CG_outputBuilder* ocg, const GEQ_Handle &g, Relation &bounds, Variable_ID v, coef_t stride, const EQ_Handle &strideEQ, Relation known, const std::vector<CG_outputRepr *> &assigned_on_the_fly); -CG_outputRepr *outputUBasRepr(CG_outputBuilder* ocg, const GEQ_Handle &g, Relation & bounds, Variable_ID v, - coef_t /*stride*/, // currently unused - const EQ_Handle &/*strideEQ*/, - const std::vector<CG_outputRepr *> &assigned_on_the_fly = std::vector<CG_outputRepr *>(last_level, static_cast<CG_outputRepr *>(NULL))); -CG_outputRepr* outputEasyBoundAsRepr(CG_outputBuilder* ocg, Relation &bounds, const Constraint_Handle &g, Variable_ID v, bool ignoreWC, int ceiling, const std::vector<CG_outputRepr *> &assigned_on_the_fly); - - -bool boundHitsStride(const GEQ_Handle &g, Variable_ID v, const EQ_Handle &strideEQ, coef_t /*stride, currently unused*/, Relation known); -Relation greatest_common_step(const Tuple<Relation> &I, const Tuple<int> &active, int level, const Relation &known = Relation::Null()); -bool findFloorInequality(Relation &r, Variable_ID v, GEQ_Handle &h, Variable_ID excluded); -Relation project_onto_levels(Relation R, int last_level, bool wildcards); -bool isSimpleStride(const EQ_Handle &g, Variable_ID v); -int countStrides(Conjunct *c, Variable_ID v, EQ_Handle &strideEQ, bool &simple); -bool hasBound(Relation r, int level, int UB); -bool find_any_constraint(int s, int level, Relation &kr, int direction, Relation &S, bool approx); -bool has_nonstride_EQ(Relation r, int level); -Relation pickOverhead(Relation r, int liftTo); -Relation minMaxOverhead(Relation r, int level); -int max_fs_arity(const Constraint_Handle &c); - - -} - -#endif diff --git a/omegalib/codegen/include/code_gen/rose_attributes.h b/omegalib/codegen/include/code_gen/rose_attributes.h deleted file mode 100644 index 9766f52..0000000 --- a/omegalib/codegen/include/code_gen/rose_attributes.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef ROSE_ATTRIBUTES_HH -#define ROSE_ATTRIBUTES_HH - -#include "rose.h" -#include <algorithm> -#include <string> -#include <vector> - -namespace omega { - -class CodeInsertion; - -typedef std::vector<CodeInsertion*> CodeInsertionPtrList; -typedef std::vector<CodeInsertion*>::iterator CodeInsertionPtrListItr; - -class CodeInsertion { -public: - int loop_level; - bool marked; - CodeInsertion(int looplevel) { this->loop_level = looplevel; marked = false; } - ~CodeInsertion() {} - virtual SgStatement* getStatement(SgScopeStatement* scopeStmt = NULL) = 0; -}; - -class PragmaInsertion : public CodeInsertion { -private: - std::string name; -public: - PragmaInsertion(int loop_level, const std::string &pragma) : CodeInsertion(loop_level) { this->name = std::string(pragma); } - ~PragmaInsertion() { } - virtual SgStatement* getStatement(SgScopeStatement* scopeStmt = NULL); -}; - -class MMPrefetchInsertion : public CodeInsertion { -private: - std::string arrName; - std::vector<std::string*> indecies; - std::vector<int> offsets; - int indexCount; - int cacheHint; - void initialize(const std::string& arrName, int hint); - void addDim(int offset); - void addDim(int offset, const std::string& indexer); - SgExpression* buildArrArg(SgScopeStatement* scopeStmt); - SgExpression* makeIndexExp(int dim, SgScopeStatement* scopeStmt); -public: - MMPrefetchInsertion(int loop_level, const std::string &arr, int hint) : CodeInsertion(loop_level) - { this->initialize(arr, hint); } - ~MMPrefetchInsertion() { } - virtual SgStatement* getStatement(SgScopeStatement* scopeStmt = NULL); -}; - -class CodeInsertionAttribute : public AstAttribute { -private: - std::vector<CodeInsertion*> code_insertions; -public: - CodeInsertionAttribute() { code_insertions = std::vector<CodeInsertion*>(); } - ~CodeInsertionAttribute() {} - - void add(CodeInsertion* ci) { code_insertions.push_back(ci); } - CodeInsertionPtrListItr begin() { return code_insertions.begin(); } - CodeInsertionPtrListItr end() { return code_insertions.end(); } - void remove(CodeInsertion* ci) { std::remove(code_insertions.begin(), code_insertions.end(), ci); } - int countCodeInsertions() { return code_insertions.size(); } -}; - -struct CodeInsertionMark { -public: - SgStatement* stmt; - CodeInsertion* ci; -}; - -class CodeInsertionVisitor : public AstPrePostProcessing { -private: - int loop_level; - std::vector<CodeInsertionMark*> ci_marks; - void markStmt(SgStatement* stmt, CodeInsertion* ci); -public: - void initialize(); - virtual void preOrderVisit(SgNode* n); - virtual void postOrderVisit(SgNode* n); - void insertCode(); -}; - -void postProcessRoseCodeInsertion(SgProject* proj); -void copyAttributes(SgNode* s, SgNode* d); -CodeInsertionAttribute* getOrCreateCodeInsertionAttribute(SgNode* node); - -} - -#endif diff --git a/omegalib/codegen/src/CG.cc b/omegalib/codegen/src/CG.cc deleted file mode 100644 index 42bd172..0000000 --- a/omegalib/codegen/src/CG.cc +++ /dev/null @@ -1,1163 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - CG node classes, used to build AST tree from polyhedra scanning. - - Notes: - Parameter "restriction" is always tighter than "known" since CG_split - node does not correspond to any code for enforcement. This property is - destroyed after hoistGuard since "restriction" is not used anymore. - CG node's children are guaranteed not to be NULL, either NULL child is - removed from the children or the parent node itself becomes NULL. - - History: - 04/20/96 printRepr added by D people. Lei Zhou - 10/24/06 hoistGuard added by chun - 08/03/10 collect CG classes into one place, by Chun Chen - 08/04/10 track dynamically substituted variables in printRepr, by chun - 04/02/11 rewrite the CG node classes, by chun - *****************************************************************************/ - -#include <typeinfo> -#include <assert.h> -#include <omega.h> -#include <code_gen/codegen.h> -#include <code_gen/CG.h> -#include <code_gen/CG_outputBuilder.h> -#include <code_gen/CG_stringBuilder.h> -#include <code_gen/CG_utils.h> -#include <code_gen/codegen_error.h> -#include <stack> -#include <string.h> - -namespace omega { - -extern std::vector<std::vector<int> > smtNonSplitLevels; -extern std::vector<std::vector<std::string> > loopIdxNames; //per stmt -extern std::vector<std::pair<int, std::string> > syncs; - -extern int checkLoopLevel; -extern int stmtForLoopCheck; -extern int upperBoundForLevel; -extern int lowerBoundForLevel; -extern bool fillInBounds; - -//----------------------------------------------------------------------------- -// Class: CG_result -//----------------------------------------------------------------------------- - -CG_outputRepr *CG_result::printRepr(CG_outputBuilder *ocg, - const std::vector<CG_outputRepr *> &stmts) const { - return printRepr(1, ocg, stmts, - std::vector<std::pair<CG_outputRepr *, int> >(num_level(), - std::make_pair(static_cast<CG_outputRepr *>(NULL), 0))); -} - -std::string CG_result::printString() const { - CG_stringBuilder ocg; - std::vector<CG_outputRepr *> stmts(codegen_->xforms_.size()); - for (int i = 0; i < stmts.size(); i++) - stmts[i] = new CG_stringRepr("s" + to_string(i)); - CG_stringRepr *repr = static_cast<CG_stringRepr *>(printRepr(&ocg, stmts)); - for (int i = 0; i < stmts.size(); i++) - delete stmts[i]; - - if (repr != NULL) { - std::string s = repr->GetString(); - delete repr; - return s; - } else - return std::string(); -} - -int CG_result::num_level() const { - return codegen_->num_level(); -} - -//----------------------------------------------------------------------------- -// Class: CG_split -//----------------------------------------------------------------------------- - -CG_result *CG_split::recompute(const BoolSet<> &parent_active, - const Relation &known, const Relation &restriction) { - active_ &= parent_active; - if (active_.empty()) { - delete this; - return NULL; - } - - - int i = 0; - while (i < restrictions_.size()) { - Relation new_restriction = Intersection(copy(restrictions_[i]), - copy(restriction)); - - new_restriction.simplify(2, 4); - //new_restriction.simplify(); - clauses_[i] = clauses_[i]->recompute(active_, copy(known), - new_restriction); - if (clauses_[i] == NULL) { - restrictions_.erase(restrictions_.begin() + i); - clauses_.erase(clauses_.begin() + i); - } else - i++; - } - - - if (restrictions_.size() == 0) { - delete this; - return NULL; - } else - return this; -} - -int CG_split::populateDepth() { - int max_depth = 0; - for (int i = 0; i < clauses_.size(); i++) { - int t = clauses_[i]->populateDepth(); - if (t > max_depth) - max_depth = t; - } - return max_depth; -} - -std::pair<CG_result *, Relation> CG_split::liftOverhead(int depth, - bool propagate_up) { - for (int i = 0; i < clauses_.size();) { - std::pair<CG_result *, Relation> result = clauses_[i]->liftOverhead( - depth, propagate_up); - if (result.first == NULL) - clauses_.erase(clauses_.begin() + i); - else { - clauses_[i] = result.first; - if (!result.second.is_obvious_tautology()) - return std::make_pair(this, result.second); - i++; - } - - } - - if (clauses_.size() == 0) { - delete this; - return std::make_pair(static_cast<CG_result *>(NULL), - Relation::True(num_level())); - } else - return std::make_pair(this, Relation::True(num_level())); -} - -Relation CG_split::hoistGuard() { - std::vector<Relation> guards; - for (int i = 0; i < clauses_.size(); i++) - guards.push_back(clauses_[i]->hoistGuard()); - - return SimpleHull(guards, true, true); -} - -void CG_split::removeGuard(const Relation &guard) { - for (int i = 0; i < clauses_.size(); i++) - clauses_[i]->removeGuard(guard); -} - -std::vector<CG_result *> CG_split::findNextLevel() const { - std::vector<CG_result *> result; - for (int i = 0; i < clauses_.size(); i++) { - CG_split *splt = dynamic_cast<CG_split *>(clauses_[i]); - if (splt != NULL) { - std::vector<CG_result *> t = splt->findNextLevel(); - result.insert(result.end(), t.begin(), t.end()); - } else - result.push_back(clauses_[i]); - } - - return result; -} - -CG_outputRepr *CG_split::printRepr(int indent, CG_outputBuilder *ocg, - const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const { - CG_outputRepr *stmtList = NULL; - std::vector<CG_result *> next_level = findNextLevel(); - - std::vector<CG_loop *> cur_loops; - for (int i = 0; i < next_level.size(); i++) { - CG_loop *lp = dynamic_cast<CG_loop *>(next_level[i]); - if (lp != NULL) { - cur_loops.push_back(lp); - } else { - stmtList = ocg->StmtListAppend(stmtList, - loop_print_repr(cur_loops, 0, cur_loops.size(), - Relation::True(num_level()), NULL, indent, ocg, - stmts, assigned_on_the_fly)); - stmtList = ocg->StmtListAppend(stmtList, - next_level[i]->printRepr(indent, ocg, stmts, - assigned_on_the_fly)); - cur_loops.clear(); - } - } - - stmtList = ocg->StmtListAppend(stmtList, - loop_print_repr(cur_loops, 0, cur_loops.size(), - Relation::True(num_level()), NULL, indent, ocg, stmts, - assigned_on_the_fly)); - return stmtList; -} - -CG_result *CG_split::clone() const { - std::vector<CG_result *> clauses(clauses_.size()); - for (int i = 0; i < clauses_.size(); i++) - clauses[i] = clauses_[i]->clone(); - return new CG_split(codegen_, active_, restrictions_, clauses); -} - -void CG_split::dump(int indent) const { - std::string prefix; - for (int i = 0; i < indent; i++) - prefix += " "; - std::cout << prefix << "SPLIT: " << active_ << std::endl; - for (int i = 0; i < restrictions_.size(); i++) { - std::cout << prefix << "restriction: "; - const_cast<CG_split *>(this)->restrictions_[i].print(); - clauses_[i]->dump(indent + 1); - } - -} - -//----------------------------------------------------------------------------- -// Class: CG_loop -//----------------------------------------------------------------------------- - -CG_result *CG_loop::recompute(const BoolSet<> &parent_active, - const Relation &known, const Relation &restriction) { - known_ = copy(known); - restriction_ = copy(restriction); - active_ &= parent_active; - - std::vector<Relation> Rs; - for (BoolSet<>::iterator i = active_.begin(); i != active_.end(); i++) { - Relation r = Intersection(copy(restriction), - copy(codegen_->projected_IS_[level_ - 1][*i])); - - //r.simplify(2, 4); - r.simplify(); - if (!r.is_upper_bound_satisfiable()) { - active_.unset(*i); - continue; - } - Rs.push_back(copy(r)); - } - - if (active_.empty()) { - delete this; - return NULL; - } - - Relation hull = SimpleHull(Rs, true, true); - - //hull.simplify(2,4); - - // check if actual loop is needed - std::pair<EQ_Handle, int> result = find_simplest_assignment(hull, - hull.set_var(level_)); - if (result.second < INT_MAX) { - needLoop_ = false; - - bounds_ = Relation(hull.n_set()); - F_Exists *f_exists = bounds_.add_and()->add_exists(); - F_And *f_root = f_exists->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping; - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(result.first); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - switch (v->kind()) { - case Input_Var: - h.update_coef(bounds_.input_var(v->get_position()), - cvi.curr_coef()); - break; - case Wildcard_Var: { - Variable_ID v2 = replicate_floor_definition(hull, v, bounds_, - f_exists, f_root, exists_mapping); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = bounds_.get_local(g); - else - v2 = bounds_.get_local(g, v->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h.update_const(result.first.get_const()); - bounds_.simplify(); - } - // loop iterates more than once, extract bounds now - else { - needLoop_ = true; - - bounds_ = Relation(hull.n_set()); - F_Exists *f_exists = bounds_.add_and()->add_exists(); - F_And *f_root = f_exists->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping; - - Relation b = Gist(copy(hull), copy(known), 1); - bool has_unresolved_bound = false; - - std::set<Variable_ID> excluded_floor_vars; - excluded_floor_vars.insert(b.set_var(level_)); - for (GEQ_Iterator e(b.single_conjunct()->GEQs()); e; e++) - if ((*e).get_coef(b.set_var(level_)) != 0) { - bool is_bound = true; - for (Constr_Vars_Iter cvi(*e, true); cvi; cvi++) { - std::pair<bool, GEQ_Handle> result = find_floor_definition( - b, cvi.curr_var(), excluded_floor_vars); - if (!result.first) { - is_bound = false; - has_unresolved_bound = true; - break; - } - } - - if (!is_bound) - continue; - - GEQ_Handle h = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - switch (v->kind()) { - case Input_Var: - h.update_coef(bounds_.input_var(v->get_position()), - cvi.curr_coef()); - break; - case Wildcard_Var: { - Variable_ID v2 = replicate_floor_definition(b, v, - bounds_, f_exists, f_root, exists_mapping); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = bounds_.get_local(g); - else - v2 = bounds_.get_local(g, v->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h.update_const((*e).get_const()); - } - - if (has_unresolved_bound) { - b = Approximate(b); - b.simplify(2, 4); - //Simplification of Hull - hull = Approximate(hull); - hull.simplify(2, 4); - //end : Anand - for (GEQ_Iterator e(b.single_conjunct()->GEQs()); e; e++) - if ((*e).get_coef(b.set_var(level_)) != 0) - f_root->add_GEQ(*e); - } - bounds_.simplify(); - hull.simplify(2,4); - // Since current SimpleHull does not support max() upper bound or min() lower bound, - // we have to forcefully split the loop when hull approximation does not return any bound. - bool has_lb = false; - bool has_ub = false; - for (GEQ_Iterator e = bounds_.single_conjunct()->GEQs(); e; e++) { - if ((*e).get_coef(bounds_.set_var(level_)) > 0) - has_lb = true; - else if ((*e).get_coef(bounds_.set_var(level_)) < 0) - has_ub = true; - if (has_lb && has_ub) - break; - } - - if (!has_lb) { - for (int i = 0; i < Rs.size(); i++) { - Relation r = Approximate(copy(Rs[i])); - r.simplify(2, 4); - for (GEQ_Iterator e = r.single_conjunct()->GEQs(); e; e++) - if ((*e).get_coef(r.input_var(level_)) > 0) { - Relation r2 = Relation::True(num_level()); - r2.and_with_GEQ(*e); - r2.simplify(); - std::vector<Relation> restrictions(2); - restrictions[0] = Complement(copy(r2)); - restrictions[0].simplify(); - restrictions[1] = r2; - std::vector<CG_result *> clauses(2); - clauses[0] = this; - clauses[1] = this->clone(); - CG_result *cgr = new CG_split(codegen_, active_, - restrictions, clauses); - cgr = cgr->recompute(active_, copy(known), - copy(restriction)); - return cgr; - } - } - for (int i = 0; i < Rs.size(); i++) { - Relation r = Approximate(copy(Rs[i])); - r.simplify(2, 4); - for (EQ_Iterator e = r.single_conjunct()->EQs(); e; e++) - if ((*e).get_coef(r.input_var(level_)) != 0) { - Relation r2 = Relation::True(num_level()); - r2.and_with_GEQ(*e); - r2.simplify(); - std::vector<Relation> restrictions(2); - if ((*e).get_coef(r.input_var(level_)) > 0) { - restrictions[0] = Complement(copy(r2)); - restrictions[0].simplify(); - restrictions[1] = r2; - } else { - restrictions[0] = r2; - restrictions[1] = Complement(copy(r2)); - restrictions[1].simplify(); - } - std::vector<CG_result *> clauses(2); - clauses[0] = this; - clauses[1] = this->clone(); - CG_result *cgr = new CG_split(codegen_, active_, - restrictions, clauses); - cgr = cgr->recompute(active_, copy(known), - copy(restriction)); - return cgr; - } - } - } else if (!has_ub) { - for (int i = 0; i < Rs.size(); i++) { - Relation r = Approximate(copy(Rs[i])); - r.simplify(2, 4); - for (GEQ_Iterator e = r.single_conjunct()->GEQs(); e; e++) - if ((*e).get_coef(r.input_var(level_)) < 0) { - Relation r2 = Relation::True(num_level()); - r2.and_with_GEQ(*e); - r2.simplify(); - std::vector<Relation> restrictions(2); - restrictions[1] = Complement(copy(r2)); - restrictions[1].simplify(); - restrictions[0] = r2; - std::vector<CG_result *> clauses(2); - clauses[0] = this; - clauses[1] = this->clone(); - CG_result *cgr = new CG_split(codegen_, active_, - restrictions, clauses); - cgr = cgr->recompute(active_, copy(known), - copy(restriction)); - return cgr; - } - } - for (int i = 0; i < Rs.size(); i++) { - Relation r = Approximate(copy(Rs[i])); - r.simplify(2, 4); - for (EQ_Iterator e = r.single_conjunct()->EQs(); e; e++) - if ((*e).get_coef(r.input_var(level_)) != 0) { - Relation r2 = Relation::True(num_level()); - r2.and_with_GEQ(*e); - r2.simplify(); - std::vector<Relation> restrictions(2); - if ((*e).get_coef(r.input_var(level_)) > 0) { - restrictions[0] = Complement(copy(r2)); - restrictions[0].simplify(); - restrictions[1] = r2; - } else { - restrictions[0] = r2; - restrictions[1] = Complement(copy(r2)); - restrictions[1].simplify(); - } - std::vector<CG_result *> clauses(2); - clauses[0] = this; - clauses[1] = this->clone(); - CG_result *cgr = new CG_split(codegen_, active_, - restrictions, clauses); - cgr = cgr->recompute(active_, copy(known), - copy(restriction)); - return cgr; - } - } - } - - if (!has_lb && !has_ub) - throw codegen_error( - "can't find any bound at loop level " + to_string(level_)); - else if (!has_lb) - throw codegen_error( - "can't find lower bound at loop level " - + to_string(level_)); - else if (!has_ub) - throw codegen_error( - "can't find upper bound at loop level " - + to_string(level_)); - } - bounds_.copy_names(hull); - bounds_.setup_names(); - - // additional guard/stride condition extraction - if (needLoop_) { - Relation cur_known = Intersection(copy(bounds_), copy(known_)); - cur_known.simplify(); - hull = Gist(hull, copy(cur_known), 1); - - std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(hull, - hull.set_var(level_)); - if (result.second != NULL) - if (abs(result.first.get_coef(hull.set_var(level_))) == 1) { - F_Exists *f_exists = bounds_.and_with_and()->add_exists(); - F_And *f_root = f_exists->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping; - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(result.first); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - switch (v->kind()) { - case Input_Var: - h.update_coef(bounds_.input_var(v->get_position()), - cvi.curr_coef()); - break; - case Wildcard_Var: { - Variable_ID v2; - if (v == result.second) - v2 = f_exists->declare(); - else - v2 = replicate_floor_definition(hull, v, bounds_, - f_exists, f_root, exists_mapping); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = bounds_.get_local(g); - else - v2 = bounds_.get_local(g, v->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h.update_const(result.first.get_const()); - } else { - // since gist is not powerful enough on modular constraints for now, - // make an educated guess - coef_t stride = abs(result.first.get_coef(result.second)) - / gcd(abs(result.first.get_coef(result.second)), - abs( - result.first.get_coef( - hull.set_var(level_)))); - - Relation r1(hull.n_inp()); - F_Exists *f_exists = r1.add_and()->add_exists(); - F_And *f_root = f_exists->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping; - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(result.first); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - switch (v->kind()) { - case Input_Var: - h.update_coef(r1.input_var(v->get_position()), - cvi.curr_coef()); - break; - case Wildcard_Var: { - Variable_ID v2; - if (v == result.second) - v2 = f_exists->declare(); - else - v2 = replicate_floor_definition(hull, v, r1, - f_exists, f_root, exists_mapping); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = r1.get_local(g); - else - v2 = r1.get_local(g, v->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h.update_const(result.first.get_const()); - r1.simplify(); - - bool guess_success = false; - for (GEQ_Iterator e(bounds_.single_conjunct()->GEQs()); e; e++) - if ((*e).get_coef(bounds_.set_var(level_)) == 1) { - Relation r2(hull.n_inp()); - F_Exists *f_exists = r2.add_and()->add_exists(); - F_And *f_root = f_exists->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping; - EQ_Handle h = f_root->add_EQ(); - h.update_coef(f_exists->declare(), stride); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - switch (v->kind()) { - case Input_Var: - h.update_coef(r2.input_var(v->get_position()), - cvi.curr_coef()); - break; - case Wildcard_Var: { - Variable_ID v2 = replicate_floor_definition( - hull, v, r2, f_exists, f_root, - exists_mapping); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = r2.get_local(g); - else - v2 = r2.get_local(g, v->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h.update_const((*e).get_const()); - r2.simplify(); - - if (Gist(copy(r1), - Intersection(copy(cur_known), copy(r2)), 1).is_obvious_tautology() - && Gist(copy(r2), - Intersection(copy(cur_known), copy(r1)), - 1).is_obvious_tautology()) { - bounds_ = Intersection(bounds_, r2); - bounds_.simplify(); - guess_success = true; - break; - } - } - - // this is really a stride with non-unit coefficient for this loop variable - if (!guess_success) { - // TODO: for stride ax = b mod n it might be beneficial to - // generate modular linear equation solver code for - // runtime to get the starting position in printRepr, - // and stride would be n/gcd(|a|,n), thus this stride - // can be put into bounds_ too. - } - - } - - hull = Project(hull, hull.set_var(level_)); - hull.simplify(2, 4); - guard_ = Gist(hull, Intersection(copy(bounds_), copy(known_)), 1); - } - // don't generate guard for non-actual loop, postpone it. otherwise - // redundant if-conditions might be generated since for-loop semantics - // includes implicit comparison checking. -- by chun 09/14/10 - else - guard_ = Relation::True(num_level()); - guard_.copy_names(bounds_); - guard_.setup_names(); - - //guard_.simplify(); - // recursively down the AST - Relation new_known = Intersection(copy(known), - Intersection(copy(bounds_), copy(guard_))); - new_known.simplify(2, 4); - Relation new_restriction = Intersection(copy(restriction), - Intersection(copy(bounds_), copy(guard_))); - new_restriction.simplify(2, 4); - body_ = body_->recompute(active_, new_known, new_restriction); - if (body_ == NULL) { - delete this; - return NULL; - } else - return this; -} - -int CG_loop::populateDepth() { - int depth = body_->populateDepth(); - if (needLoop_) - depth_ = depth + 1; - else - depth_ = depth; - return depth_; -} - -std::pair<CG_result *, Relation> CG_loop::liftOverhead(int depth, - bool propagate_up) { - if (depth_ > depth) { - assert(propagate_up == false); - std::pair<CG_result *, Relation> result = body_->liftOverhead(depth, - false); - body_ = result.first; - return std::make_pair(this, Relation::True(num_level())); - } else { // (depth_ <= depth) - if (propagate_up) { - Relation r = pick_one_guard(guard_, level_); - if (!r.is_obvious_tautology()) - return std::make_pair(this, r); - } - - std::pair<CG_result *, Relation> result; - if (propagate_up || needLoop_) - result = body_->liftOverhead(depth, true); - else - result = body_->liftOverhead(depth, false); - body_ = result.first; - if (result.second.is_obvious_tautology()) - return std::make_pair(this, result.second); - - // loop is an assignment, replace this loop variable in overhead condition - if (!needLoop_) { - result.second = Intersection(result.second, copy(bounds_)); - result.second = Project(result.second, - result.second.set_var(level_)); - result.second.simplify(2, 4); - } - - - int max_level = 0; - bool has_wildcard = false; - bool direction = true; - for (EQ_Iterator e(result.second.single_conjunct()->EQs()); e; e++) - if ((*e).has_wildcards()) { - if (has_wildcard) - assert(false); - else - has_wildcard = true; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var()->kind() == Input_Var - && cvi.curr_var()->get_position() > max_level) - max_level = cvi.curr_var()->get_position(); - } else - assert(false); - - if (!has_wildcard) { - int num_simple_geq = 0; - for (GEQ_Iterator e(result.second.single_conjunct()->GEQs()); e; - e++) - if (!(*e).has_wildcards()) { - num_simple_geq++; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var()->kind() == Input_Var - && cvi.curr_var()->get_position() > max_level) { - max_level = cvi.curr_var()->get_position(); - direction = (cvi.curr_coef() < 0) ? true : false; - } - } else { - has_wildcard = true; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var()->kind() == Input_Var - && cvi.curr_var()->get_position() > max_level) { - max_level = cvi.curr_var()->get_position(); - } - } - assert( - (has_wildcard && num_simple_geq == 0) || (!has_wildcard && num_simple_geq == 1)); - } - - // check if this is the top loop level for splitting for this overhead - if (!propagate_up || (has_wildcard && max_level == level_ - 1) - || (!has_wildcard && max_level == level_)) { - std::vector<Relation> restrictions(2); - std::vector<CG_result *> clauses(2); - int saved_num_level = num_level(); - if (has_wildcard || direction) { - restrictions[1] = Complement(copy(result.second)); - restrictions[1].simplify(); - clauses[1] = this->clone(); - restrictions[0] = result.second; - clauses[0] = this; - } else { - restrictions[0] = Complement(copy(result.second)); - restrictions[0].simplify(); - clauses[0] = this->clone(); - restrictions[1] = result.second; - clauses[1] = this; - } - CG_result *cgr = new CG_split(codegen_, active_, restrictions, - clauses); - CG_result *new_cgr = cgr->recompute(active_, copy(known_), - copy(restriction_)); - new_cgr->populateDepth(); - assert(new_cgr==cgr); - if (static_cast<CG_split *>(new_cgr)->clauses_.size() == 1) - // infinite recursion detected, bail out - return std::make_pair(new_cgr, Relation::True(saved_num_level)); - else - return cgr->liftOverhead(depth, propagate_up); - } else - return std::make_pair(this, result.second); - } -} - -Relation CG_loop::hoistGuard() { - - Relation r = body_->hoistGuard(); - - // TODO: should bookkeep catched contraints in loop output as enforced and check if anything missing - // if (!Gist(copy(b), copy(enforced)).is_obvious_tautology()) { - // fprintf(stderr, "need to generate extra guard inside the loop\n"); - // } - - if (!needLoop_) - r = Intersection(r, copy(bounds_)); - r = Project(r, r.set_var(level_)); - r = Gist(r, copy(known_), 1); - - Relation eliminate_existentials_r; - Relation eliminate_existentials_known; - - eliminate_existentials_r = copy(r); - if (!r.is_obvious_tautology()) { - eliminate_existentials_r = Approximate(copy(r)); - eliminate_existentials_r.simplify(2,4); - eliminate_existentials_known = Approximate(copy(known_)); - eliminate_existentials_known.simplify(2,4); - - eliminate_existentials_r = Gist( eliminate_existentials_r, eliminate_existentials_known, 1); - } - - - if (!eliminate_existentials_r.is_obvious_tautology()) { - // if (!r.is_obvious_tautology()) { - body_->removeGuard(r); - guard_ = Intersection(guard_, copy(r)); - guard_.simplify(); - } - - return guard_; - - // return ifList; - // } - - -} - -void CG_loop::removeGuard(const Relation &guard) { - known_ = Intersection(known_, copy(guard)); - known_.simplify(); - - guard_ = Gist(guard_, copy(known_), 1); - guard_.copy_names(known_); - guard_.setup_names(); -} - -CG_outputRepr *CG_loop::printRepr(int indent, CG_outputBuilder *ocg, - const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const { - return printRepr(true, indent, ocg, stmts, assigned_on_the_fly); -} - -CG_outputRepr *CG_loop::printRepr(bool do_print_guard, int indent, - CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const { - CG_outputRepr *guardRepr; - if (do_print_guard) - guardRepr = output_guard(ocg, guard_, assigned_on_the_fly); - else - guardRepr = NULL; - - Relation cur_known = Intersection(copy(known_), copy(guard_)); - cur_known.simplify(); - if (needLoop_) { - - if (checkLoopLevel) - if (level_ == checkLoopLevel) - if (active_.get(stmtForLoopCheck)) - fillInBounds = true; - - CG_outputRepr *ctrlRepr = output_loop(ocg, bounds_, level_, cur_known, - assigned_on_the_fly); - - fillInBounds = false; - - CG_outputRepr *bodyRepr = body_->printRepr( - (guardRepr == NULL) ? indent + 1 : indent + 2, ocg, stmts, - assigned_on_the_fly); - CG_outputRepr * loopRepr; - - if (guardRepr == NULL) - loopRepr = ocg->CreateLoop(indent, ctrlRepr, bodyRepr); - else - loopRepr = ocg->CreateLoop(indent + 1, ctrlRepr, bodyRepr); - - if (!smtNonSplitLevels.empty()) { - bool blockLoop = false; - bool threadLoop = false; - bool sync = false; - int firstActiveStmt = -1; - for (int s = 0; s < active_.size(); s++) { - if (active_.get(s)) { - if (firstActiveStmt < 0) - firstActiveStmt = s; - //We assume smtNonSplitLevels is only used to mark the first of - //the block or thread loops to be reduced in CUDA-CHiLL. Here we - //place some comments to help with final code generation. - //int idx = smtNonSplitLevels[s].index(level_); - - if (s < smtNonSplitLevels.size()) { - if (smtNonSplitLevels[s].size() > 0) - if (smtNonSplitLevels[s][0] == level_) { - blockLoop = true; - } - //Assume every stmt marked with a thread loop index also has a block loop idx - if (smtNonSplitLevels[s].size() > 1) - if (smtNonSplitLevels[s][1] == level_) { - threadLoop = true; - } - } - } - } - if (blockLoop && threadLoop) { - fprintf(stderr, - "Warning, have %d level more than once in smtNonSplitLevels\n", - level_); - threadLoop = false; - } - std::string preferredIdx; - if (loopIdxNames.size() - && (level_ / 2) - 1 < loopIdxNames[firstActiveStmt].size()) - preferredIdx = loopIdxNames[firstActiveStmt][(level_ / 2) - 1]; - for (int s = 0; s < active_.size(); s++) { - if (active_.get(s)) { - for (int i = 0; i < syncs.size(); i++) { - if (syncs[i].first == s - && strcmp(syncs[i].second.c_str(), - preferredIdx.c_str()) == 0) { - sync = true; - //printf("FOUND SYNC\n"); - } - - } - } - - } - if (threadLoop || blockLoop || preferredIdx.length() != 0) { - char buf[1024]; - std::string loop; - if (blockLoop) - loop = "blockLoop "; - if (threadLoop) - loop = "threadLoop "; - if (preferredIdx.length() != 0 && sync) { - sprintf(buf, "~cuda~ %spreferredIdx: %s sync", loop.c_str(), - preferredIdx.c_str()); - } else if (preferredIdx.length() != 0) { - sprintf(buf, "~cuda~ %spreferredIdx: %s", loop.c_str(), - preferredIdx.c_str()); - } else { - sprintf(buf, "~cuda~ %s", loop.c_str()); - } - - - loopRepr = ocg->CreateAttribute(loopRepr, buf); - } - - } - if (guardRepr == NULL) - return loopRepr; - else - return ocg->CreateIf(indent, guardRepr, loopRepr, NULL); - } else { - std::pair<CG_outputRepr *, std::pair<CG_outputRepr *, int> > result = - output_assignment(ocg, bounds_, level_, cur_known, - assigned_on_the_fly); - guardRepr = ocg->CreateAnd(guardRepr, result.first); - - if (result.second.second < CodeGen::var_substitution_threshold) { - std::vector<std::pair<CG_outputRepr *, int> > atof = - assigned_on_the_fly; - atof[level_ - 1] = result.second; - CG_outputRepr *bodyRepr = body_->printRepr( - (guardRepr == NULL) ? indent : indent + 1, ocg, stmts, - atof); - delete atof[level_ - 1].first; - if (guardRepr == NULL) - return bodyRepr; - else - return ocg->CreateIf(indent, guardRepr, bodyRepr, NULL); - } else { - CG_outputRepr *assignRepr = ocg->CreateAssignment( - (guardRepr == NULL) ? indent : indent + 1, - output_ident(ocg, bounds_, - const_cast<CG_loop *>(this)->bounds_.set_var( - level_), assigned_on_the_fly), - result.second.first); - CG_outputRepr *bodyRepr = body_->printRepr( - (guardRepr == NULL) ? indent : indent + 1, ocg, stmts, - assigned_on_the_fly); - if (guardRepr == NULL) - return ocg->StmtListAppend(assignRepr, bodyRepr); - else - return ocg->CreateIf(indent, guardRepr, - ocg->StmtListAppend(assignRepr, bodyRepr), NULL); - } - - } -} - -CG_result *CG_loop::clone() const { - return new CG_loop(codegen_, active_, level_, body_->clone()); -} - -void CG_loop::dump(int indent) const { - std::string prefix; - for (int i = 0; i < indent; i++) - prefix += " "; - std::cout << prefix << "LOOP (level " << level_ << "): " << active_ - << std::endl; - std::cout << prefix << "known: "; - const_cast<CG_loop *>(this)->known_.print(); - std::cout << prefix << "restriction: "; - const_cast<CG_loop *>(this)->restriction_.print(); - std::cout << prefix << "bounds: "; - const_cast<CG_loop *>(this)->bounds_.print(); - std::cout << prefix << "guard: "; - const_cast<CG_loop *>(this)->guard_.print(); - body_->dump(indent + 1); -} - -//----------------------------------------------------------------------------- -// Class: CG_leaf -//----------------------------------------------------------------------------- - -CG_result* CG_leaf::recompute(const BoolSet<> &parent_active, - const Relation &known, const Relation &restriction) { - active_ &= parent_active; - known_ = copy(known); - - guards_.clear(); - for (BoolSet<>::iterator i = active_.begin(); i != active_.end(); i++) { - Relation r = Intersection( - copy(codegen_->projected_IS_[num_level() - 1][*i]), - copy(restriction)); - r.simplify(2, 4); - if (!r.is_upper_bound_satisfiable()) - active_.unset(*i); - else { - r = Gist(r, copy(known), 1); - if (!r.is_obvious_tautology()) { - guards_[*i] = r; - guards_[*i].copy_names(known); - guards_[*i].setup_names(); - } - } - } - - - if (active_.empty()) { - delete this; - return NULL; - } else - return this; -} - -std::pair<CG_result *, Relation> CG_leaf::liftOverhead(int depth, bool) { - if (depth == 0) - return std::make_pair(this, Relation::True(num_level())); - - for (std::map<int, Relation>::iterator i = guards_.begin(); - i != guards_.end(); i++) { - Relation r = pick_one_guard(i->second); - if (!r.is_obvious_tautology()) { - bool has_wildcard = false; - int max_level = 0; - for (EQ_Iterator e(r.single_conjunct()->EQs()); e; e++) { - if ((*e).has_wildcards()) - has_wildcard = true; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var()->kind() == Input_Var - && cvi.curr_var()->get_position() > max_level) - max_level = cvi.curr_var()->get_position(); - } - for (GEQ_Iterator e(r.single_conjunct()->GEQs()); e; e++) { - if ((*e).has_wildcards()) - has_wildcard = true; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var()->kind() == Input_Var - && cvi.curr_var()->get_position() > max_level) - max_level = cvi.curr_var()->get_position(); - } - - if (!(has_wildcard && max_level == codegen_->num_level())) - return std::make_pair(this, r); - } - } - - return std::make_pair(this, Relation::True(num_level())); -} - -Relation CG_leaf::hoistGuard() { - std::vector<Relation> guards; - for (BoolSet<>::iterator i = active_.begin(); i != active_.end(); i++) { - std::map<int, Relation>::iterator j = guards_.find(*i); - if (j == guards_.end()) { - Relation r = Relation::True(num_level()); - r.copy_names(known_); - r.setup_names(); - return r; - } else { - guards.push_back(j->second); - } - } - - return SimpleHull(guards, true, true); -} - -void CG_leaf::removeGuard(const Relation &guard) { - known_ = Intersection(known_, copy(guard)); - known_.simplify(); - - std::map<int, Relation>::iterator i = guards_.begin(); - while (i != guards_.end()) { - i->second = Gist(i->second, copy(known_), 1); - if (i->second.is_obvious_tautology()) - guards_.erase(i++); - else - ++i; - } -} - -CG_outputRepr *CG_leaf::printRepr(int indent, CG_outputBuilder *ocg, - const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) const { - return leaf_print_repr(active_, guards_, NULL, known_, indent, ocg, - codegen_->remap_, codegen_->xforms_, stmts, assigned_on_the_fly); -} - -CG_result *CG_leaf::clone() const { - return new CG_leaf(codegen_, active_); -} - -void CG_leaf::dump(int indent) const { - std::string prefix; - for (int i = 0; i < indent; i++) - prefix += " "; - std::cout << prefix << "LEAF: " << active_ << std::endl; - std::cout << prefix << "known: "; - const_cast<CG_leaf *>(this)->known_.print(); - for (std::map<int, Relation>::const_iterator i = guards_.begin(); - i != guards_.end(); i++) { - std::cout << prefix << "guard #" << i->first << ":"; - const_cast<Relation &>(i->second).print(); - } -} - -} diff --git a/omegalib/codegen/src/CG_roseBuilder.cc b/omegalib/codegen/src/CG_roseBuilder.cc deleted file mode 100644 index 7e12634..0000000 --- a/omegalib/codegen/src/CG_roseBuilder.cc +++ /dev/null @@ -1,1093 +0,0 @@ -/***************************************************************************** - Copyright (C) 2008 University of Southern California - Copyright (C) 2009-2010 University of Utah - All Rights Reserved. - - Purpose: - generate suif code for omega - - Notes: - - History: - 02/01/06 created by Chun Chen - *****************************************************************************/ - -#include <stack> -#include <code_gen/CG_roseBuilder.h> -#include <string> - -struct ir_error: public std::runtime_error { - ir_error(const std::string &msg) : - std::runtime_error(msg) { - } -}; - -using namespace SageBuilder; -using namespace SageInterface; -using namespace OmpSupport; - -namespace omega { - -//----------------------------------------------------------------------------- -// make suif initilization happy -//----------------------------------------------------------------------------- -char *k_ocg_comment; - -CG_roseBuilder::CG_roseBuilder(int is_fortran, SgGlobal* global, SgGlobal* firstScope, - SgSymbolTable* symtab, SgSymbolTable* symtab2, SgNode* root) : - isFortran(is_fortran), global_(global), global_scope(firstScope), symtab_(symtab), symtab2_( - symtab2), root_(root) { -} - - -CG_roseBuilder::~CG_roseBuilder() { -} - -// Manu:: returns true if input is in fortran, else returns false -bool CG_roseBuilder::isInputFortran() const{ - if (isFortran) - return true; - else - return false; -} - -//----------------------------------------------------------------------------- -// place holder generation -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateSubstitutedStmt(int, CG_outputRepr *stmt, - const std::vector<std::string> &vars, std::vector<CG_outputRepr*> &subs) const { - - SgStatementPtrList* list = static_cast<CG_roseRepr *>(stmt)->list_; - SgNode *tnl; - SgStatement* statement; - if (list != NULL) { - delete stmt; - for (int i = 0; i < subs.size(); i++) { - if (subs[i] == NULL) - continue; - - CG_roseRepr *repr = static_cast<CG_roseRepr*>(subs[i]); - SgExpression* op = repr->op_; - - for (SgStatementPtrList::iterator it = (*list).begin(); - it != (*list).end(); it++) { - statement = (*it); - tnl = isSgNode(statement); - - int j; - int not_in_symtab_; - - not_in_symtab_ = 0; - - SgVariableSymbol *vs = symtab_->find_variable( - SgName(vars[i].c_str())); - - if (vs == NULL) { - - not_in_symtab_ = 1; - - vs = symtab2_->find_variable(SgName(vars[i].c_str())); - } - if (vs != NULL) { - - std::vector<SgVarRefExp *> array = substitute(tnl, - (const SgVariableSymbol*) vs, op, root_); - for (std::vector<SgVarRefExp *>::iterator it = - array.begin(); it != array.end(); it++) { - - if (isSgVarRefExp(op)) { - if (strcmp( - isSgVarRefExp(op)->get_symbol()->get_name().getString().c_str(), - vs->get_name().getString().c_str())) { - - (*it)->set_symbol( - isSgVarRefExp(op)->get_symbol()); - - } - } else if (isSgExpression(op)) { - - if (isSgBinaryOp((*it)->get_parent())) - isSgBinaryOp((*it)->get_parent())->replace_expression( - *it, op); - else if (isSgUnaryOp((*it)->get_parent())) - isSgUnaryOp((*it)->get_parent())->replace_expression( - *it, op); - else if (isSgExprListExp((*it)->get_parent())) - isSgExprListExp((*it)->get_parent())->replace_expression( - *it, op); - else - throw ir_error("unrecognized expression type"); - } - - } - } - - } - - delete repr; - subs[i] = NULL; - - if (subs[i] != NULL) - throw ir_error("not freed properly"); - - } - - return new CG_roseRepr(list); - - } else { - tnl = static_cast<CG_roseRepr *>(stmt)->tnl_; - - if (tnl == NULL) - throw ir_error("both list and tnl are null!!"); - - delete stmt; - int j; - int not_in_symtab_; - for (int i = 0; i < subs.size(); i++) { - if (subs[i] == NULL) - continue; - not_in_symtab_ = 0; - - - CG_roseRepr *repr = static_cast<CG_roseRepr*>(subs[i]); - SgExpression* op = repr->op_; - delete repr; - subs[i] = NULL; - - SgVariableSymbol *vs = symtab_->find_variable( - SgName(vars[i].c_str())); - - if (vs == NULL) { - - not_in_symtab_ = 1; - - vs = symtab2_->find_variable(SgName(vars[i].c_str())); - } - if (vs != NULL) { - std::vector<SgVarRefExp *> array = substitute(tnl, vs, op, - root_); - - if (not_in_symtab_ && isSgVarRefExp(op)) { - if (strcmp( - isSgVarRefExp(op)->get_symbol()->get_name().getString().c_str(), - vs->get_name().getString().c_str())) { - } - } - - for (std::vector<SgVarRefExp *>::iterator j = array.begin(); - j != array.end(); j++) { - - if (isSgVarRefExp(op)) { - if (strcmp( - isSgVarRefExp(op)->get_symbol()->get_name().getString().c_str(), - vs->get_name().getString().c_str())) { - (*j)->set_symbol(isSgVarRefExp(op)->get_symbol()); - - } - } else if (isSgExpression(op)) { - - if (isSgBinaryOp((*j)->get_parent())) - isSgBinaryOp((*j)->get_parent())->replace_expression( - *j, op); - else if (isSgUnaryOp((*j)->get_parent())) - isSgUnaryOp((*j)->get_parent())->replace_expression( - *j, op); - else if (isSgExprListExp((*j)->get_parent())) { // Manu:: fortran indices are stored this way - isSgExprListExp((*j)->get_parent())->replace_expression(*j, op); - } - else - throw ir_error("unrecognized expression type"); - - } - - } - } - } - return new CG_roseRepr(tnl); - } - -} - -//----------------------------------------------------------------------------- -// assignment generation -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateAssignment(int, CG_outputRepr *lhs, - CG_outputRepr *rhs) const { - if (lhs == NULL || rhs == NULL) { - fprintf(stderr, "Code generation: Missing lhs or rhs\n"); - return NULL; - } - - SgExpression* src = static_cast<CG_roseRepr*>(rhs)->op_; - SgExpression* dst = static_cast<CG_roseRepr*>(lhs)->op_; - - SgExprStatement* ins = buildAssignStatement(dst, src); - src->set_parent(ins); - dst->set_parent(ins); - - SgStatementPtrList* new_list = new SgStatementPtrList; - - (*new_list).push_back(isSgStatement(ins)); - - delete lhs; - delete rhs; - - return new CG_roseRepr(new_list); - -} - -//----------------------------------------------------------------------------- -// function invocation generation -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateInvoke(const std::string &fname, - std::vector<CG_outputRepr *> &list) const { - - if (fname == std::string("max") || fname == std::string("min")) { - if (list.size() == 0) { - return NULL; - } else if (list.size() == 1) { - return list[0]; - } else { - int last = list.size() - 1; - SgExpression* op2 = static_cast<CG_roseRepr*>(list[last])->op_; - delete list[last]; - list.erase(list.end()-1); - CG_roseRepr *repr = static_cast<CG_roseRepr*>(CreateInvoke(fname, - list)); - SgExpression* op1 = repr->op_; - - - SgExpression *ins; - SgExprListExp* arg_list = buildExprListExp(); - appendExpression(arg_list, op1); - appendExpression(arg_list, op2); - SgVarRefExp* opaque_var; - - - if (fname == std::string("max")) { - opaque_var = buildOpaqueVarRefExp("__rose_gt", global_); - ins = isSgExpression(buildFunctionCallExp(opaque_var, arg_list)); - - // Manu:: fortran support - if (isInputFortran()) { - SgName fName("merge"); - SgTypeInt *retType = buildIntType(); - - SgExpression *cond = static_cast<CG_roseRepr *>(CreateLE(new CG_roseRepr(op2), new CG_roseRepr(op1)))->op_; - appendExpression(arg_list, cond); - ins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); - } - - } else { - opaque_var = buildOpaqueVarRefExp("__rose_lt", global_); - ins = isSgExpression(buildFunctionCallExp(opaque_var, arg_list)); - - // Manu:: fortran support - if (isInputFortran()) { - SgName fName("merge"); - SgTypeInt *retType = buildIntType(); - - SgExpression *cond = static_cast<CG_roseRepr *>(CreateLE(new CG_roseRepr(op1), new CG_roseRepr(op2)))->op_; - appendExpression(arg_list, cond); - ins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); - } - - } - - repr->op_ = ins; - return repr; - } - } else { - fprintf(stderr, - "Code generation: invoke function io_call not implemented\n"); - return NULL; - } - -} - -//----------------------------------------------------------------------------- -// comment generation -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateComment(int, - const std::string &commentText) const { - if (commentText == std::string("")) { - return NULL; - } - - SgLocatedNode *tnl = new SgLocatedNode(); - buildComment(tnl, "//omega_comment: " + commentText); - - return new CG_roseRepr(isSgNode(tnl)); - -} - -//----------------------------------------------------------------------------- -// if stmt gen operations -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateIf(int, CG_outputRepr *guardList, - CG_outputRepr *true_stmtList, CG_outputRepr *false_stmtList) const { - - if (true_stmtList == NULL && false_stmtList == NULL) { - delete guardList; - return NULL; - } else if (guardList == NULL) { - return StmtListAppend(true_stmtList, false_stmtList); - } - - SgExpression* header = static_cast<CG_roseRepr*>(guardList)->op_; - - SgStatementPtrList *then_part1, *else_part1; - SgStatement* then_part; - SgStatement* else_part; - SgBasicBlock* then_part2; - SgBasicBlock* else_part2; - if (true_stmtList != NULL) { - then_part1 = static_cast<CG_roseRepr*>(true_stmtList)->list_; - if (then_part1 != NULL) { - then_part = *((*then_part1).begin()); - - if ((*then_part1).size() > 1) { - then_part2 = buildBasicBlock(); - for (SgStatementPtrList::iterator it = (*then_part1).begin(); - it != (*then_part1).end(); it++) { - then_part2->append_statement(*it); - - } - then_part = isSgStatement(then_part2); - - } - } else { - // Manu:: fortran support (if part) - if (isInputFortran()) { - then_part2 = buildBasicBlock(); - then_part2->append_statement(isSgStatement(static_cast<CG_roseRepr*>(true_stmtList)->tnl_)); - then_part = isSgStatement(then_part2); - } else - then_part = isSgStatement(static_cast<CG_roseRepr*>(true_stmtList)->tnl_); - } - } else { - then_part = NULL; - } - if (false_stmtList != NULL) { - else_part1 = static_cast<CG_roseRepr*>(false_stmtList)->list_; - if (else_part1 != NULL) { - else_part = *((*else_part1).begin()); - if ((*else_part1).size() > 1) { - else_part2 = buildBasicBlock(); - for (SgStatementPtrList::iterator it2 = (*else_part1).begin(); - it2 != (*else_part1).end(); it2++) { - else_part2->append_statement(*it2); - - } - else_part = isSgStatement(else_part2); - - } - } else { - // Manu:: fortran support (if part) - if (isInputFortran()) { - else_part2 = buildBasicBlock(); - else_part2->append_statement(isSgStatement(static_cast<CG_roseRepr*>(false_stmtList)->tnl_)); - else_part = isSgStatement(else_part2); - } else - else_part = isSgStatement(static_cast<CG_roseRepr*>(false_stmtList)->tnl_); - } - } else { - else_part = NULL; - } - - SgIfStmt* ti = buildIfStmt(header, isSgStatement(then_part), - isSgStatement(else_part)); - - delete guardList; - delete true_stmtList; - delete false_stmtList; - - return new CG_roseRepr(isSgNode(ti)); - -} - -//----------------------------------------------------------------------------- -// inductive variable generation, to be used in CreateLoop as control -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateInductive(CG_outputRepr *index, - CG_outputRepr *lower, CG_outputRepr *upper, CG_outputRepr *step) const { - - if (index == NULL || lower == NULL || upper == NULL) { - fprintf(stderr, - "Code generation: something wrong in CreateInductive\n"); - return NULL; - } - - if (step == NULL) - step = new CG_roseRepr(isSgExpression(buildIntVal(1))); - - SgVarRefExp *index_sym = isSgVarRefExp( - static_cast<CG_roseRepr*>(index)->op_); - SgExpression* lower_bound = static_cast<CG_roseRepr*>(lower)->op_; - SgExpression* upper_bound = static_cast<CG_roseRepr*>(upper)->op_; - SgExpression* step_size = static_cast<CG_roseRepr*>(step)->op_; - - SgStatement* for_init_stmt = buildAssignStatement(index_sym, lower_bound); - SgLessOrEqualOp* cond = buildLessOrEqualOp(index_sym, upper_bound); - SgExprStatement* test = buildExprStatement(cond); - SgPlusAssignOp* increment = buildPlusAssignOp(index_sym, step_size); - SgForStatement *for_stmt = buildForStatement(for_init_stmt, - isSgStatement(test), increment, NULL); - - delete index; - delete lower; - delete upper; - delete step; - - - // Manu - if (isInputFortran()) { - SgFortranDo * forStmt=new SgFortranDo(Sg_File_Info::generateDefaultFileInfoForTransformationNode()); - forStmt->set_has_end_statement(true); - forStmt->set_bound(upper_bound); - forStmt->set_increment(step_size); - forStmt->set_initialization(isSgExprStatement(for_init_stmt)->get_expression()); - return new CG_roseRepr(isSgNode(forStmt)); - } else { - - return new CG_roseRepr(isSgNode(for_stmt)); - - } - -} - -//----------------------------------------------------------------------------- -// Attribute Creation -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateAttribute(CG_outputRepr *control, - const std::string &commentText) const { - - SgNode *tnl = static_cast<CG_roseRepr*>(control)->tnl_; - - tnl->setAttribute("omega_comment", new AstTextAttribute(commentText)); - - return static_cast<CG_roseRepr*>(control); - -} - -//----------------------------------------------------------------------------- -// Pragma Attribute -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreatePragmaAttribute(CG_outputRepr *stmt, int looplevel, const std::string &pragmaText) const { - SgNode *tnl = static_cast<CG_roseRepr*>(stmt)->tnl_; - CodeInsertionAttribute* attr = NULL; - if (!tnl->attributeExists("code_insertion")) { - attr = new CodeInsertionAttribute(); - tnl->setAttribute("code_insertion", attr); - } - else { - attr = static_cast<CodeInsertionAttribute*>(tnl->getAttribute("code_insertion")); - } - attr->add(new PragmaInsertion(looplevel, pragmaText)); - return stmt; -} - -//----------------------------------------------------------------------------- -// Prefetch Attribute -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreatePrefetchAttribute(CG_outputRepr* stmt, int looplevel, const std::string &arrName, int hint) const { - SgNode *tnl = static_cast<CG_roseRepr*>(stmt)->tnl_; - CodeInsertionAttribute *attr = getOrCreateCodeInsertionAttribute(tnl); - attr->add(new MMPrefetchInsertion(looplevel, arrName, hint)); -} - -//----------------------------------------------------------------------------- -// loop stmt generation -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateLoop(int, CG_outputRepr *control, - CG_outputRepr *stmtList) const { - if (stmtList == NULL) { - delete control; - return NULL; - } else if (control == NULL) { - fprintf(stderr, "Code generation: no inductive for this loop\n"); - return stmtList; - } - - SgNode *tnl = static_cast<CG_roseRepr*>(control)->tnl_; - SgForStatement *tf = isSgForStatement(tnl); - - // Manu :: fortran support - SgFortranDo *tfd = NULL; - if (isInputFortran()) { - tfd = isSgFortranDo(tnl); - } - SgStatementPtrList * body = static_cast<CG_roseRepr*>(stmtList)->list_; - - if (body != NULL) { - if (!((*body).empty())) { - if ((*body).size() == 1) { - if (!isInputFortran()) { // Manu:: added if-else for fortran support - tf->set_loop_body(*((*body).begin())); - (*((*body).begin()))->set_parent(tf); - } else { - SgBasicBlock* bb1 = buildBasicBlock(); - bb1->set_parent(tfd); - bb1->append_statement(*((*body).begin())); - tfd->set_body(bb1); - } - } else { - // Manu:: support for fortran label (do - continue) - SgName *sname = NULL; - - SgBasicBlock* bb = buildBasicBlock(); - if (!isInputFortran()) - bb->set_parent(tf); - else - bb->set_parent(tfd); - for (SgStatementPtrList::iterator it = (*body).begin(); - it != (*body).end(); it++) { - bb->append_statement(*it); - (*it)->set_parent(bb); - } - if (!isInputFortran()) - tf->set_loop_body(bb); - else { - tfd->set_body(bb); - } - } - } - } else { - SgNode* tnl2 = static_cast<CG_roseRepr*>(stmtList)->tnl_; - - if (tnl2 != NULL) { - if (!isInputFortran()) { - tf->set_loop_body(isSgStatement(tnl2)); - tnl2->set_parent(tf); - } else { - SgBasicBlock* bb1 = buildBasicBlock(); - bb1->set_parent(tfd); - bb1->append_statement(isSgStatement(tnl2)); - tfd->set_body(bb1); - tnl2->set_parent(bb1); - } - } - } - - delete stmtList; - - return control; -} - -//----------------------------------------------------------------------------- -// basic int, identifier gen operations -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateInt(int _i) const { - return new CG_roseRepr(isSgExpression(buildIntVal(_i))); -} -bool CG_roseBuilder::isInteger(CG_outputRepr *op) const{ - - SgExpression *op1 = static_cast<CG_roseRepr *>(op)->op_; - - if(op1) - if(isSgIntVal(op1)) - return true; - - return false; -} -CG_outputRepr* CG_roseBuilder::CreateIdent(const std::string &_s) const { - - SgVariableSymbol *vs = symtab_->find_variable(SgName(_s.c_str())); - SgVariableSymbol *vs2 = symtab2_->find_variable(SgName(_s.c_str())); - - if (vs == NULL && vs2 == NULL) { - - SgVariableDeclaration* defn = buildVariableDeclaration( - SgName(_s.c_str()), buildIntType()); - SgInitializedNamePtrList& variables = defn->get_variables(); - SgInitializedNamePtrList::const_iterator i = variables.begin(); - SgInitializedName* initializedName = *i; - vs = new SgVariableSymbol(initializedName); - prependStatement(defn, isSgScopeStatement(root_)); - - vs->set_parent(symtab2_); - symtab2_->insert(SgName(_s.c_str()), vs); - return new CG_roseRepr(isSgExpression(buildVarRefExp(vs))); - - } - - /* May have problem */ - - if (!isSgExpression(buildVarRefExp(SgName(_s.c_str())))) - throw ir_error("error in Create ident!!"); - if (vs2 != NULL) - return new CG_roseRepr(isSgExpression(buildVarRefExp(vs2))); - - return new CG_roseRepr(isSgExpression(buildVarRefExp(vs))); - -} - -//----------------------------------------------------------------------------- -// binary arithmetic operations -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreatePlus(CG_outputRepr *lop, - CG_outputRepr *rop) const { - if (rop == NULL) { - return lop; - } else if (lop == NULL) { - return rop; - } - - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - SgAddOp *ins = buildAddOp(op1, op2); - op1->set_parent(ins); - op2->set_parent(ins); - delete lop; - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - -} - -CG_outputRepr* CG_roseBuilder::CreateMinus(CG_outputRepr *lop, - CG_outputRepr *rop) const { - if (rop == NULL) { - return lop; /* May Cause Problem */ - } else if (lop == NULL) { - SgExpression *op = static_cast<CG_roseRepr*>(rop)->op_; - SgMinusOp *ins = buildMinusOp(op); - - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - } else { - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - SgSubtractOp *ins = buildSubtractOp(op1, op2); - op1->set_parent(ins); - op2->set_parent(ins); - delete lop; - delete rop; - return new CG_roseRepr(isSgExpression(ins)); - } - -} - -CG_outputRepr* CG_roseBuilder::CreateTimes(CG_outputRepr *lop, - CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) { - if (rop != NULL) { - rop->clear(); - delete rop; - } - if (lop != NULL) { - lop->clear(); - delete lop; - } - return NULL; - } - - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - SgMultiplyOp *ins = buildMultiplyOp(op1, op2); - op1->set_parent(ins); - op2->set_parent(ins); - delete lop; - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - -} - -CG_outputRepr* CG_roseBuilder::CreateIntegerFloor(CG_outputRepr *lop, - CG_outputRepr *rop) const { - if (rop == NULL) { - fprintf(stderr, "Code generation: divide by NULL\n"); - return NULL; - } else if (lop == NULL) { - delete rop; - return NULL; - } - - // (6+5)*10 / 4 - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - // bugs in SUIF prevent use of correct io_divfloor - SgDivideOp *ins = buildDivideOp(op1, op2); - - delete lop; - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - -} - -CG_outputRepr* CG_roseBuilder::CreateIntegerMod(CG_outputRepr *lop, - CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) { - return NULL; - } - - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - // bugs in SUIF prevent use of correct io_mod - SgModOp *ins; - if (!isInputFortran()) { - ins = buildModOp(op1, op2); - delete lop; - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - } else { // Manu:: fortran mod is a function call and not an operator (f77 and f90) - SgExpression *fins; - SgName fName("MOD"); - SgExprListExp* arg_list = buildExprListExp(); - appendExpression(arg_list, op1); - appendExpression(arg_list, op2); - SgTypeInt *retType = buildIntType(); - fins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); - return new CG_roseRepr(isSgExpression(fins)); - } - -} - -//----------------------------------------------------------------------------- -// binary logical operations -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateAnd(CG_outputRepr *lop, - CG_outputRepr *rop) const { - - if (rop == NULL) - return lop; - else if (lop == NULL) - return rop; - - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - SgAndOp *ins = buildAndOp(op1, op2); - - delete lop; - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - -} - -//----------------------------------------------------------------------------- -// binary relational operations -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::CreateLE(CG_outputRepr *lop, - CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) { - return NULL; - } - - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - SgLessOrEqualOp *ins = buildLessOrEqualOp(op1, op2); - - delete lop; - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - -} - -CG_outputRepr* CG_roseBuilder::CreateEQ(CG_outputRepr *lop, - CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) { - return NULL; - } - - SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; - SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; - - SgEqualityOp *ins = buildEqualityOp(op1, op2); - - delete lop; - delete rop; - - return new CG_roseRepr(isSgExpression(ins)); - -} - -//----------------------------------------------------------------------------- -// stmt list gen operations -//----------------------------------------------------------------------------- -CG_outputRepr* CG_roseBuilder::StmtListAppend(CG_outputRepr *list1, - CG_outputRepr *list2) const { - - if (list2 == NULL) { - return list1; - } else if (list1 == NULL) { - return list2; - } - - SgStatementPtrList* new_list; - - SgStatementPtrList* tnl1 = static_cast<CG_roseRepr *>(list1)->list_; - SgStatementPtrList* tnl2 = static_cast<CG_roseRepr *>(list2)->list_; - SgNode* one = static_cast<CG_roseRepr *>(list1)->tnl_; - SgNode* two = static_cast<CG_roseRepr *>(list2)->tnl_; - - SgExpression* exp1 = static_cast<CG_roseRepr *>(list1)->op_; - SgExpression* exp2 = static_cast<CG_roseRepr *>(list2)->op_; - - if (exp1 || exp2) - throw ir_error("error in stmtlistappend!!"); - - if (tnl1 && one) - throw ir_error("error in stmtlistappend!!"); - - if (tnl2 && two) - throw ir_error("error in stmtlistappend!!"); - if ((tnl1 == NULL) && (tnl2 == NULL)) { - - if ((one != NULL) && (two != NULL)) { - - new_list = new SgStatementPtrList; - - (*new_list).push_back(isSgStatement(one)); - (*new_list).push_back(isSgStatement(two)); - - CG_roseRepr* new_rep = new CG_roseRepr(new_list); - - return static_cast<CG_outputRepr *>(new_rep); - - } else if ((one != NULL) && (two == NULL)) { - - return static_cast<CG_outputRepr *>(new CG_roseRepr(one)); - - } else if ((two != NULL) && (one == NULL)) { - return static_cast<CG_outputRepr *>(new CG_roseRepr(two)); - - } - - } else { - if ((tnl2 != NULL) && (tnl1 == NULL)) { - if (one == NULL) - return list2; - else { - new_list = new SgStatementPtrList; - (*new_list).push_back(isSgStatement(one)); - - for (SgStatementPtrList::iterator it = (*tnl2).begin(); - it != (*tnl2).end(); it++) { - (*new_list).push_back(*it); - - } - return static_cast<CG_outputRepr *>(new CG_roseRepr(new_list)); - } - } else if ((tnl1 != NULL) && (tnl2 == NULL)) { - if (two == NULL) - return list1; - else { - - (*tnl1).push_back(isSgStatement(two)); - return static_cast<CG_outputRepr *>(new CG_roseRepr(tnl1)); - - } - - } else if ((tnl1 != NULL) && (tnl2 != NULL)) { - - for (SgStatementPtrList::iterator it = (*tnl2).begin(); - it != (*tnl2).end(); it++) { - (*tnl1).push_back(*it); - - } - - return static_cast<CG_outputRepr *>(new CG_roseRepr(tnl1)); - } - - } - -} - - -CG_outputRepr* CG_roseBuilder::CreateDim3(const char* varName, CG_outputRepr* arg1, - CG_outputRepr* arg2, CG_outputRepr* arg3) const { - - SgFunctionSymbol * ctor_symbol = global_scope->lookup_function_symbol( - SgName("dim3")); - - SgExprListExp * ctor_args; - if(arg3 != NULL) - ctor_args = buildExprListExp(static_cast<CG_roseRepr*>(arg1)->op_, - static_cast<CG_roseRepr*>(arg2)->op_, static_cast<CG_roseRepr*>(arg3)->op_); - else - ctor_args = buildExprListExp(static_cast<CG_roseRepr*>(arg1)->op_, - static_cast<CG_roseRepr*>(arg2)->op_); - SgFunctionCallExp * dim3_func_call = buildFunctionCallExp( - buildFunctionRefExp(ctor_symbol->get_declaration()), ctor_args); - - char joined_str[20]; - - strcpy(joined_str, "dim3 "); - strcat(joined_str, varName); - - SgExprStatement* decl = buildAssignStatement( - buildOpaqueVarRefExp(joined_str, isSgScopeStatement(root_)), - dim3_func_call); - - SgStatementPtrList *tnl2 = new SgStatementPtrList; - - (*tnl2).push_back(decl); - return new CG_roseRepr(tnl2); - -} - -std::vector<SgVarRefExp *> substitute(SgNode *in, const SgVariableSymbol *sym, - SgExpression* expr, SgNode* root) { - - SgStatement* stmt; - SgExpression* op; - std::vector<SgVarRefExp *> arrays; - - if (in != NULL) { - if (stmt = isSgStatement(in)) { - if (isSgBasicBlock(stmt)) { - SgStatementPtrList& stmts = - isSgBasicBlock(stmt)->get_statements(); - for (int i = 0; i < stmts.size(); i++) { - stmts[i]->set_parent(stmt); - std::vector<SgVarRefExp *> a = substitute( - isSgNode(stmts[i]), sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } else if (isSgForStatement(stmt)) { - SgForStatement *tnf = isSgForStatement(stmt); - tnf->get_for_init_stmt()->set_parent(tnf); - tnf->get_test()->set_parent(tnf); - tnf->get_increment()->set_parent(tnf); - tnf->get_loop_body()->set_parent(tnf); - std::vector<SgVarRefExp *> a = substitute( - isSgNode(tnf->get_for_init_stmt()), sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a1 = substitute( - isSgNode(tnf->get_test()), sym, expr, root); - std::copy(a1.begin(), a1.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a2 = substitute( - isSgNode(tnf->get_increment()), sym, expr, root); - std::copy(a2.begin(), a2.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a3 = substitute( - isSgNode(tnf->get_loop_body()), sym, expr, root); - std::copy(a3.begin(), a3.end(), back_inserter(arrays)); - } else if (isSgFortranDo(stmt)) { // Manu:: fortran support - SgFortranDo *tnf = isSgFortranDo(stmt); - tnf->get_initialization()->set_parent(tnf); - tnf->get_bound()->set_parent(tnf); - tnf->get_increment()->set_parent(tnf); - tnf->get_body()->set_parent(tnf); - std::vector<SgVarRefExp *> a = substitute( - isSgNode(tnf->get_initialization()), sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a1 = substitute( - isSgNode(tnf->get_bound()), sym, expr, root); - std::copy(a1.begin(), a1.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a2 = substitute( - isSgNode(tnf->get_increment()), sym, expr, root); - std::copy(a2.begin(), a2.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a3 = substitute( - isSgNode(tnf->get_body()), sym, expr, root); - std::copy(a3.begin(), a3.end(), back_inserter(arrays)); - } else if (isSgForInitStatement(stmt)) { - - SgStatementPtrList& stmts = - isSgForInitStatement(stmt)->get_init_stmt(); - - for (SgStatementPtrList::iterator it = stmts.begin(); - it != stmts.end(); it++) { - std::vector<SgVarRefExp *> a = substitute(isSgNode(*it), - sym, expr, root); - - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } - else if (isSgVariableDeclaration(stmt)) { - if (SgExpression *init = - isSgVariableDeclaration(stmt)->get_variables().front()->get_initializer()) { - if (isSgAssignInitializer(init)) { - std::vector<SgVarRefExp *> a = substitute( - isSgAssignInitializer(init)->get_operand(), sym, - expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } - } else if (isSgIfStmt(stmt)) { - SgIfStmt* tni = isSgIfStmt(stmt); - std::vector<SgVarRefExp *> a = substitute( - isSgNode(tni->get_conditional()), sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a1 = substitute( - isSgNode(tni->get_true_body()), sym, expr, root); - std::copy(a1.begin(), a1.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a2 = substitute( - isSgNode(tni->get_false_body()), sym, expr, root); - std::copy(a2.begin(), a2.end(), back_inserter(arrays)); - } else if (isSgExprStatement(stmt)) { - (isSgExprStatement(stmt)->get_expression())->set_parent( - isSgExprStatement(stmt)); - std::vector<SgVarRefExp *> a = substitute( - isSgNode(isSgExprStatement(stmt)->get_expression()), - sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } - else { - op = isSgExpression(in); - std::string y = sym->get_name().getString(); - - if (isSgBinaryOp(op)) { - - isSgBinaryOp(op)->get_lhs_operand()->set_parent(op); - isSgBinaryOp(op)->get_rhs_operand()->set_parent(op); - - std::vector<SgVarRefExp *> a = substitute( - isSgBinaryOp(op)->get_lhs_operand(), sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - std::vector<SgVarRefExp *> a1 = substitute( - isSgBinaryOp(op)->get_rhs_operand(), sym, expr, root); - std::copy(a1.begin(), a1.end(), back_inserter(arrays)); - } else if (isSgUnaryOp(op)) { - std::vector<SgVarRefExp *> a = substitute( - isSgUnaryOp(op)->get_operand(), sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } else if (isSgVarRefExp(op)) { - std::string z = - isSgVarRefExp(op)->get_symbol()->get_name().getString(); - if (!strcmp(z.c_str(), y.c_str())) { - arrays.push_back(isSgVarRefExp(op)); - } - } - else if (isSgCallExpression(op)) { - SgExprListExp* exprs = isSgCallExpression(op)->get_args(); - SgExpressionPtrList &expr_list = exprs->get_expressions(); - - for (SgExpressionPtrList::iterator it = expr_list.begin(); - it != expr_list.end(); it++) { - std::vector<SgVarRefExp *> a = substitute(isSgNode(*it), - sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } else if (isSgExprListExp(op)) { // Manu:: fortran indices are stored this way - SgExpressionPtrList &expr_list = isSgExprListExp(op)->get_expressions(); - - for (SgExpressionPtrList::iterator it = expr_list.begin(); - it != expr_list.end(); it++) { - std::vector<SgVarRefExp *> a = substitute(isSgNode(*it), - sym, expr, root); - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - - } - - } - } - - return arrays; -} - -} // namespace diff --git a/omegalib/codegen/src/CG_roseRepr.cc b/omegalib/codegen/src/CG_roseRepr.cc deleted file mode 100644 index 9265ab0..0000000 --- a/omegalib/codegen/src/CG_roseRepr.cc +++ /dev/null @@ -1,125 +0,0 @@ -/***************************************************************************** - Copyright (C) 2008 University of Southern California. - All Rights Reserved. - - Purpose: - omega holder for suif implementaion - - Notes: - - History: - 02/01/06 - Chun Chen - created -*****************************************************************************/ - -#include <code_gen/CG_roseRepr.h> -#include <code_gen/rose_attributes.h> -#include <stdio.h> -#include <string.h> -#include <cstring> -namespace omega { - - - - -CG_roseRepr::CG_roseRepr(): tnl_(NULL), op_(NULL), list_(NULL){ - -} - -CG_roseRepr::CG_roseRepr(SgNode *tnl): tnl_(tnl), op_(NULL),list_(NULL) { -} - -CG_roseRepr::CG_roseRepr(SgExpression* op): tnl_(NULL), op_(op),list_(NULL){ -} -CG_roseRepr::CG_roseRepr(SgStatementPtrList* stmtlist):tnl_(NULL), op_(NULL), list_(stmtlist){ -} - -CG_roseRepr::~CG_roseRepr() { - // delete nothing here. operand or tree_node_list should already be - // grafted to other expression tree or statement list -} - -CG_outputRepr* CG_roseRepr::clone() const { - - if( tnl_ != NULL) { - SgTreeCopy tc; - SgNode *tnl = tnl_->copy(tc); - copyAttributes(tnl_, tnl); - - tnl->set_parent(tnl_->get_parent()); - return new CG_roseRepr(tnl); - } - else if(op_ != NULL) - { - SgTreeCopy tc1; - SgNode* op = isSgNode(op_)->copy(tc1); - copyAttributes(op_, op); - - op->set_parent(isSgNode(op_)->get_parent()); - return new CG_roseRepr(isSgExpression(op)); - } - else if(list_ != NULL) - { - SgStatementPtrList* list2 = new SgStatementPtrList; - - for(SgStatementPtrList::iterator it = (*list_).begin(); it != (*list_).end(); it++){ - SgTreeCopy tc3; - SgNode *tnl2 = isSgNode(*it)->copy(tc3); - copyAttributes(*it, tnl2); - - tnl2->set_parent(isSgNode(*it)->get_parent()); - - (*list2).push_back(isSgStatement(tnl2)); - } - return new CG_roseRepr(list2); - } - - return NULL; -} - -void CG_roseRepr::clear() { - if(tnl_ != NULL) { - delete tnl_; - tnl_ = NULL; - } -} - -SgNode* CG_roseRepr::GetCode() const { - return tnl_; -} - -SgStatementPtrList* CG_roseRepr::GetList() const { - return list_; -} - -SgExpression* CG_roseRepr::GetExpression() const { - return op_; -} -void CG_roseRepr::Dump() const { -SgNode* tnl = tnl_; -SgExpression* op = op_ ; - if(tnl != NULL) - DumpFileHelper(tnl, stdout); - else if(op != NULL) - DumpFileHelper(isSgNode(op), stdout); - -} - -void CG_roseRepr::DumpFileHelper(SgNode* node, FILE *fp) const{ - std::string x; - size_t numberOfSuccessors = node->get_numberOfTraversalSuccessors(); - if(numberOfSuccessors == 0){ - x = node->unparseToString (); - fprintf(fp, "%s", x.c_str()); - } - else{ - for (size_t idx = 0; idx < numberOfSuccessors; idx++) - { - SgNode *child = NULL; - child = node->get_traversalSuccessorByIndex(idx); - DumpFileHelper(child, fp); - } - -} -} - -} // namespace diff --git a/omegalib/codegen/src/CG_stringBuilder.cc b/omegalib/codegen/src/CG_stringBuilder.cc deleted file mode 100644 index 2f9286f..0000000 --- a/omegalib/codegen/src/CG_stringBuilder.cc +++ /dev/null @@ -1,487 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - generate pseudo string code - - Notes: - There is no need to check illegal NULL parameter and throw invalid_argument - in other IR interface implementation. They are for debugging purpose. - intMod implements modular function that returns positve remainder no matter - lop is postive or nagative and rop is guranteed to be positive here. - - History: - 04/17/96 - Lei Zhou - created - 08/31/09 add parenthesis to string operands, Chun Chen -*****************************************************************************/ - -#include <code_gen/CG_stringBuilder.h> -#include <code_gen/codegen_error.h> -#include <basic/util.h> -#include <string> -#include <stdexcept> -#include <ctype.h> -#include <string.h> - -namespace { - -std::string SafeguardString(const std::string &s, char op) { - int len = s.length(); - int paren_level = 0; - int num_plusminus = 0; - int num_mul = 0; - int num_div = 0; - for (int i = 0; i < len; i++) - switch (s[i]) { - case '(': - paren_level++; - break; - case ')': - paren_level--; - break; - case '+': - case '-': - if (paren_level == 0) - num_plusminus++; - break; - case '*': - if (paren_level == 0) - num_mul++; - break; - case '/': - if (paren_level == 0) - num_div++; - break; - default: - break; - } - - bool need_paren = false; - switch (op) { - case '-': - if (num_plusminus > 0) - need_paren = true; - break; - case '*': - if (num_plusminus > 0 || num_div > 0) - need_paren = true; - break; - case '/': - if (num_plusminus > 0 || num_div > 0 || num_mul > 0) - need_paren = true; - break; - default: - break; - } - - if (need_paren) - return "(" + s + ")"; - else - return s; -} - - -std::string GetIndentSpaces(int indent) { - std::string indentStr; - for (int i = 1; i < indent; i++) { - indentStr += " "; - } - return indentStr; -} - - -// A shortcut to extract the string enclosed in the CG_outputRepr and delete -// the original holder. -std::string GetString(omega::CG_outputRepr *repr) { - std::string result = static_cast<omega::CG_stringRepr *>(repr)->GetString(); - delete repr; - return result; -} - -} - - -namespace omega { - - - -//----------------------------------------------------------------------------- -// Class: CG_stringBuilder -//----------------------------------------------------------------------------- - -CG_stringRepr *CG_stringBuilder::CreateSubstitutedStmt(int indent, CG_outputRepr *stmt, - const std::vector<std::string> &vars, - std::vector<CG_outputRepr *> &subs) const { - std::string listStr = ""; - - for (int i = 0; i < subs.size(); i++) { - if (subs[i] == NULL) - listStr += "N/A"; - else - listStr += GetString(subs[i]); - if (i < subs.size() - 1) - listStr += ","; - } - - std::string stmtName = GetString(stmt); - std::string indentStr = GetIndentSpaces(indent); - - return new CG_stringRepr(indentStr + stmtName + "(" + listStr + ");\n"); -} - -CG_stringRepr *CG_stringBuilder::CreateAssignment(int indent, - CG_outputRepr *lhs, - CG_outputRepr *rhs) const { - if (lhs == NULL || rhs == NULL) - throw std::invalid_argument("missing lhs or rhs in assignment"); - - std::string lhsStr = GetString(lhs); - std::string rhsStr = GetString(rhs); - - std::string indentStr = GetIndentSpaces(indent); - - return new CG_stringRepr(indentStr + lhsStr + "=" + rhsStr + ";\n"); -} - - -CG_stringRepr *CG_stringBuilder::CreateInvoke(const std::string &funcName, - std::vector<CG_outputRepr *> &list) const { - std::string listStr = ""; - - for (int i = 0; i < list.size(); i++) { - listStr += GetString(list[i]); - if ( i < list.size()-1) - listStr += ","; - } - - return new CG_stringRepr(funcName + "(" + listStr + ")"); -} - - -CG_stringRepr *CG_stringBuilder::CreateComment(int indent, const std::string &commentText) const { - if (commentText == std::string("")) { - return NULL; - } - - std::string indentStr = GetIndentSpaces(indent); - - return new CG_stringRepr(indentStr + "// " + commentText + "\n"); -} - -CG_stringRepr* CG_stringBuilder::CreateAttribute(CG_outputRepr *control, - const std::string &commentText) const { - if (commentText == std::string("")) { - return static_cast<CG_stringRepr *> (control); - } - - std::string controlString = GetString(control); - - return new CG_stringRepr("// " + commentText + "\n" + controlString); - -} - -CG_outputRepr* CG_stringBuilder::CreatePragmaAttribute(CG_outputRepr *scopeStmt, int looplevel, const std::string &pragmaText) const { - // -- Not Implemented - return scopeStmt; -} - -CG_outputRepr* CG_stringBuilder::CreatePrefetchAttribute(CG_outputRepr* scopeStmt, int looplevel, const std::string& arrName, int hint) const { - // -- Not Implemented - return scopeStmt; -} - -CG_stringRepr *CG_stringBuilder::CreateIf(int indent, CG_outputRepr *guardList, - CG_outputRepr *true_stmtList, CG_outputRepr *false_stmtList) const { - if (guardList == NULL) - throw std::invalid_argument("missing if condition"); - - if (true_stmtList == NULL && false_stmtList == NULL) { - delete guardList; - return NULL; - } - - std::string guardListStr = GetString(guardList); - std::string indentStr = GetIndentSpaces(indent); - std::string s; - if (true_stmtList != NULL && false_stmtList == NULL) { - s = indentStr + "if (" + guardListStr + ") {\n" - + GetString(true_stmtList) - + indentStr + "}\n"; - } - else if (true_stmtList == NULL && false_stmtList != NULL) { - s = indentStr + "if !(" + guardListStr + ") {\n" - + GetString(false_stmtList) - + indentStr + "}\n"; - } - else { - s = indentStr + "if (" + guardListStr + ") {\n" - + GetString(true_stmtList) - + indentStr + "}\n" - + indentStr + "else {\n" - + GetString(false_stmtList) - + indentStr + "}\n"; - } - - return new CG_stringRepr(s); -} - - - -CG_stringRepr *CG_stringBuilder::CreateInductive(CG_outputRepr *index, - CG_outputRepr *lower, CG_outputRepr *upper, - CG_outputRepr *step) const { - if (index == NULL) - throw std::invalid_argument("missing loop index"); - if (lower == NULL) - throw std::invalid_argument("missing loop lower bound"); - if (upper == NULL) - throw std::invalid_argument("missing loop upper bound"); - if (step == NULL) - throw std::invalid_argument("missing loop step size"); - - std::string indexStr = GetString(index); - std::string lowerStr = GetString(lower); - std::string upperStr = GetString(upper); - - std::string doStr = "for(" + indexStr + " = " + lowerStr + "; " - + indexStr + " <= " + upperStr + "; " - + indexStr; - - std::string stepStr = GetString(step); - if (stepStr == to_string(1)) - doStr += "++"; - else - doStr += " += " + stepStr; - - doStr += ")"; - - return new CG_stringRepr(doStr); -} - - -CG_stringRepr *CG_stringBuilder::CreateLoop(int indent, CG_outputRepr *control, - CG_outputRepr *stmtList) const { - if (stmtList == NULL) { - delete control; - return NULL; - } - else if (control == NULL) - return static_cast<CG_stringRepr *>(stmtList); - - std::string ctrlStr = GetString(control); - std::string stmtStr = GetString(stmtList); - - std::string indentStr = GetIndentSpaces(indent); - - std::string s = indentStr + ctrlStr + " {\n" - + stmtStr - + indentStr + "}\n"; - - return new CG_stringRepr(s); -} - - - -CG_stringRepr *CG_stringBuilder::CreateInt(int num) const { - std::string s = to_string(num); - return new CG_stringRepr(s); -} - - - -bool CG_stringBuilder::isInteger(CG_outputRepr *op) const { - - char * cstr; - std::string s = GetString(op); - cstr = new char [s.size()+1]; - strcpy (cstr, s.c_str()); - int count = 0; - while(cstr[count] != '\n' && cstr[count] != '\0' ) - if( !isdigit(cstr[count])) - return false; - - - return true; -} - - - -CG_stringRepr *CG_stringBuilder::CreateIdent(const std::string &varName) const { - if (varName == std::string("")) { - return NULL; - } - - return new CG_stringRepr(varName); -} - - -CG_stringRepr *CG_stringBuilder::CreatePlus(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL) { - return static_cast<CG_stringRepr *>(lop); - } - else if (lop == NULL) { - return static_cast<CG_stringRepr *>(rop); - } - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(lopStr + "+" + ropStr); -} - - -CG_stringRepr *CG_stringBuilder::CreateMinus(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL) { - return static_cast<CG_stringRepr *>(lop); - } - else if (lop == NULL) { - std::string ropStr = GetString(rop); - return new CG_stringRepr("-" + SafeguardString(ropStr, '-')); - } - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(lopStr + "-" + SafeguardString(ropStr, '-')); -} - - -CG_stringRepr *CG_stringBuilder::CreateTimes(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) { - delete rop; - delete lop; - return NULL; - } - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(SafeguardString(lopStr, '*') + "*" + SafeguardString(ropStr, '*')); -} - - -CG_stringRepr *CG_stringBuilder::CreateDivide(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL) - throw codegen_error("integer division by zero"); - else if (lop == NULL) { - delete rop; - return NULL; - } - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(SafeguardString(lopStr, '/') + "/" + SafeguardString(ropStr, '/')); -} - - -CG_stringRepr *CG_stringBuilder::CreateIntegerFloor(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL) - throw codegen_error("integer division by zero"); - else if (lop == NULL) { - delete rop; - return NULL; - } - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr("intFloor(" + lopStr + "," + ropStr + ")"); -} - - -CG_stringRepr *CG_stringBuilder::CreateIntegerMod(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL) - throw codegen_error("integer modulo by zero"); - else if (lop == NULL) { - delete rop; - return NULL; - } - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr("intMod(" + lopStr + "," + ropStr + ")"); -} - -CG_stringRepr *CG_stringBuilder::CreateIntegerCeil(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == 0) - throw codegen_error("integer ceiling by zero"); - else if (lop == NULL) { - delete rop; - return NULL; - } - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr("intCeil(" + lopStr + "," + ropStr + ")"); -} - - -CG_stringRepr *CG_stringBuilder::CreateAnd(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL) - return static_cast<CG_stringRepr *>(lop); - else if (lop == NULL) - return static_cast<CG_stringRepr *>(rop); - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(lopStr + " && " + ropStr); -} - - -CG_stringRepr *CG_stringBuilder::CreateGE(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) - throw std::invalid_argument("missing operand in greater than equal comparison condition"); - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(lopStr + " >= " + ropStr); -} - - - -CG_stringRepr *CG_stringBuilder::CreateLE(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) - throw std::invalid_argument("missing operand in less than equal comparison condition"); - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(lopStr + " <= " + ropStr); -} - - - -CG_stringRepr *CG_stringBuilder::CreateEQ(CG_outputRepr *lop, CG_outputRepr *rop) const { - if (rop == NULL || lop == NULL) - throw std::invalid_argument("missing operand in equal comparison condition"); - - std::string lopStr = GetString(lop); - std::string ropStr = GetString(rop); - - return new CG_stringRepr(lopStr + " == " + ropStr); -} - - - -CG_stringRepr *CG_stringBuilder::StmtListAppend(CG_outputRepr *list1, CG_outputRepr *list2) const { - if (list2 == NULL) { - return static_cast<CG_stringRepr *>(list1); - } - else if (list1 == NULL) { - return static_cast<CG_stringRepr *>(list2); - } - - std::string list1Str = GetString(list1); - std::string list2Str = GetString(list2); - - return new CG_stringRepr(list1Str + list2Str); -} - -} diff --git a/omegalib/codegen/src/CG_utils.cc b/omegalib/codegen/src/CG_utils.cc deleted file mode 100755 index d3a5f71..0000000 --- a/omegalib/codegen/src/CG_utils.cc +++ /dev/null @@ -1,1735 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Utility functions for processing CG tree. - - Notes: - - History: - 07/19/07 when generating output variable substitutions for a mapping - relation, map it to each output to get correct equality, -chun - 07/29/10 when translating equality to assignment, generate appropriate - if-condition when necesssary, -chun -*****************************************************************************/ - -#include <typeinfo> -#include <omega.h> -#include <code_gen/CG.h> -#include <code_gen/CG_utils.h> -#include <code_gen/codegen_error.h> -#include <math.h> -#include <stack> - -namespace omega { - -int checkLoopLevel; -int stmtForLoopCheck; -int upperBoundForLevel; -int lowerBoundForLevel; -bool fillInBounds; - -//trick to static init checkLoopLevel to 0 -class JunkStaticInit{ public: JunkStaticInit(){ checkLoopLevel=0; fillInBounds=false;} }; -static JunkStaticInit junkInitInstance__; - - - - -namespace { - -Relation find_best_guard(const Relation &R, const BoolSet<> &active, const std::map<int, Relation> &guards) { - std::pair<int, int> best_cost = std::make_pair(0, 0); - Relation best_cond = Relation::True(R.n_set()); - - Relation r = copy(R); - int max_iter_count = 2*(r.single_conjunct()->n_EQs()) + r.single_conjunct()->n_GEQs(); - int iter_count = 0; - while (!r.is_obvious_tautology()) { - std::pair<int, int> cost = std::make_pair(0, 0); - Relation cond = pick_one_guard(r); - Relation complement_cond = Complement(copy(cond)); - complement_cond.simplify(); - for (BoolSet<>::const_iterator i = active.begin(); i != active.end(); i++) { - std::map<int, Relation>::const_iterator j = guards.find(*i); - if (j == guards.end()) - continue; - if (Must_Be_Subset(copy(j->second), copy(cond))) - cost.first++; - else if (Must_Be_Subset(copy(j->second), copy(complement_cond))) - cost.second++; - } - if (cost > best_cost) { - best_cost = cost; - best_cond = copy(cond); - } - r = Gist(r, cond, 1); - - if (iter_count > max_iter_count) - throw codegen_error("guard condition too complex to handle"); - - iter_count++; - } - - return best_cond; -} - - -Relation find_best_guard(const Relation &R, const std::vector<CG_loop *> &loops, int start, int end) { - std::pair<int, int> best_cost = std::make_pair(0, 0); - Relation best_cond = Relation::True(R.n_set()); - - Relation r = copy(R); - int max_iter_count = 2*(r.single_conjunct()->n_EQs()) + r.single_conjunct()->n_GEQs(); - int iter_count = 0; - while (!r.is_obvious_tautology()) { - std::pair<int, int> cost = std::make_pair(0, 0); - Relation cond = pick_one_guard(r); - int i = start; - for ( ; i < end; i++) { - if (Must_Be_Subset(copy(loops[i]->guard_), copy(cond))) - cost.first++; - else - break; - } - Relation complement_cond = Complement(copy(cond)); - complement_cond.simplify(); - for (int j = i; j < end; j++) - if (Must_Be_Subset(copy(loops[j]->guard_), copy(complement_cond))) - cost.second++; - else - break; - - if (cost > best_cost) { - best_cost = cost; - best_cond = copy(cond); - } - r = Gist(r, cond, 1); - - if (iter_count > max_iter_count) - throw codegen_error("guard condition too complex to handle"); - - iter_count++; - } - - return best_cond; -} - -} - -bool bound_must_hit_stride(const GEQ_Handle &inequality, Variable_ID v, const EQ_Handle &stride_eq, Variable_ID wc, const Relation &bounds, const Relation &known) { - assert(inequality.get_coef(v) != 0 && abs(stride_eq.get_coef(v)) == 1 && wc->kind() == Wildcard_Var && abs(stride_eq.get_coef(wc)) > 1); - - // if bound expression uses floor operation, bail out for now - // TODO: in the future, handle this - if (abs(inequality.get_coef(v)) != 1) - return false; - - coef_t stride = abs(stride_eq.get_coef(wc)); - - Relation r1(known.n_set()); - F_Exists *f_exists1 = r1.add_and()->add_exists(); - F_And *f_root1 = f_exists1->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping1; - EQ_Handle h1 = f_root1->add_EQ(); - Relation r2(known.n_set()); - F_Exists *f_exists2 = r2.add_and()->add_exists(); - F_And *f_root2 = f_exists2->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping2; - EQ_Handle h2 = f_root2->add_EQ(); - for (Constr_Vars_Iter cvi(inequality); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - switch (v->kind()) { - case Input_Var: - h1.update_coef(r1.input_var(v->get_position()), cvi.curr_coef()); - h2.update_coef(r2.input_var(v->get_position()), cvi.curr_coef()); - break; - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v1, v2; - if (g->arity() == 0) { - v1 = r1.get_local(g); - v2 = r2.get_local(g); - } - else { - v1 = r1.get_local(g, v->function_of()); - v2 = r2.get_local(g, v->function_of()); - } - h1.update_coef(v1, cvi.curr_coef()); - h2.update_coef(v2, cvi.curr_coef()); - break; - } - case Wildcard_Var: { - Variable_ID v1 = replicate_floor_definition(bounds, v, r1, f_exists1, f_root1, exists_mapping1); - Variable_ID v2 = replicate_floor_definition(bounds, v, r2, f_exists2, f_root2, exists_mapping2); - h1.update_coef(v1, cvi.curr_coef()); - h2.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h1.update_const(inequality.get_const()); - h1.update_coef(f_exists1->declare(), stride); - h2.update_const(inequality.get_const()); - r1.simplify(); - r2.simplify(); - - Relation all_known = Intersection(copy(bounds), copy(known)); - all_known.simplify(); - - if (Gist(r1, copy(all_known), 1).is_obvious_tautology()) { - Relation r3(known.n_set()); - F_Exists *f_exists3 = r3.add_and()->add_exists(); - F_And *f_root3 = f_exists3->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping3; - EQ_Handle h3 = f_root3->add_EQ(); - for (Constr_Vars_Iter cvi(stride_eq); cvi; cvi++) { - Variable_ID v= cvi.curr_var(); - switch (v->kind()) { - case Input_Var: - h3.update_coef(r3.input_var(v->get_position()), cvi.curr_coef()); - break; - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v3; - if (g->arity() == 0) - v3 = r3.get_local(g); - else - v3 = r3.get_local(g, v->function_of()); - h3.update_coef(v3, cvi.curr_coef()); - break; - } - case Wildcard_Var: - if (v == wc) - h3.update_coef(f_exists3->declare(), cvi.curr_coef()); - else { - Variable_ID v3 = replicate_floor_definition(bounds, v, r3, f_exists3, f_root3, exists_mapping3); - h3.update_coef(v3, cvi.curr_coef()); - } - break; - default: - assert(false); - } - } - h3.update_const(stride_eq.get_const()); - r3.simplify(); - - if (Gist(r3, Intersection(r2, all_known), 1).is_obvious_tautology()) - return true; - else - return false; - } - else - return false; -} - - -// -// output variable by its name, however if this variable need to be substituted, -// return the substitution. -// -CG_outputRepr *output_ident(CG_outputBuilder *ocg, const Relation &R, Variable_ID v, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - const_cast<Relation &>(R).setup_names(); // hack - - if (v->kind() == Input_Var) { - int pos = v->get_position(); - if (assigned_on_the_fly[pos-1].first != NULL) - return assigned_on_the_fly[pos-1].first->clone(); - else - return ocg->CreateIdent(v->name()); - } - else if (v->kind() == Global_Var) { - if (v->get_global_var()->arity() == 0) - return ocg->CreateIdent(v->name()); - else { - /* This should be improved to take into account the possible elimination - of the set variables. */ - int arity = v->get_global_var()->arity(); - std::vector<CG_outputRepr *> argList; - for(int i = 1; i <= arity; i++) - argList.push_back(ocg->CreateIdent(const_cast<Relation &>(R).input_var(i)->name())); - CG_outputRepr *call = ocg->CreateInvoke(v->get_global_var()->base_name(), argList); - return call; - } - } - else - assert(false); -} - - -// -// return pair<if condition, <assignment rhs, assignment cost> > -// -std::pair<CG_outputRepr *, std::pair<CG_outputRepr *, int> > output_assignment(CG_outputBuilder *ocg, const Relation &R, int level, const Relation &known, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - Variable_ID v = const_cast<Relation &>(R).set_var(level); - Conjunct *c = const_cast<Relation &>(R).single_conjunct(); - - std::pair<EQ_Handle, int> result = find_simplest_assignment(R, v, assigned_on_the_fly); - - if (result.second == INT_MAX) - return std::make_pair(static_cast<CG_outputRepr *>(NULL), std::make_pair(static_cast<CG_outputRepr *>(NULL), INT_MAX)); - - CG_outputRepr *if_repr = NULL; - CG_outputRepr *assign_repr = NULL; - // check whether to generate if-conditions from equality constraints - if (abs(result.first.get_coef(v)) != 1) { - Relation r(R.n_set()); - F_Exists *f_exists = r.add_and()->add_exists(); - F_And *f_root = f_exists->add_and(); - std::map<Variable_ID, Variable_ID> exists_mapping; - exists_mapping[v] = f_exists->declare(); - - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(result.first); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - if (cvi.curr_var() == v) - h.update_coef(exists_mapping[v], cvi.curr_coef()); - else - h.update_coef(r.set_var(cvi.curr_var()->get_position()), cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = cvi.curr_var()->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = r.get_local(g); - else - v2 = r.get_local(g, cvi.curr_var()->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Wildcard_Var: { - std::map<Variable_ID, Variable_ID>::iterator p = exists_mapping.find(cvi.curr_var()); - Variable_ID v2; - if (p == exists_mapping.end()) { - v2 = f_exists->declare(); - exists_mapping[cvi.curr_var()] = v2; - } - else - v2 = p->second; - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(0); - } - h.update_const(result.first.get_const()); - - for (EQ_Iterator e(c->EQs()); e; e++) - if (!((*e) == result.first)) { - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - assert(cvi.curr_var() != v); - h.update_coef(r.set_var(cvi.curr_var()->get_position()), cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = cvi.curr_var()->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = r.get_local(g); - else - v2 = r.get_local(g, cvi.curr_var()->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Wildcard_Var: { - std::map<Variable_ID, Variable_ID>::iterator p = exists_mapping.find(cvi.curr_var()); - Variable_ID v2; - if (p == exists_mapping.end()) { - v2 = f_exists->declare(); - exists_mapping[cvi.curr_var()] = v2; - } - else - v2 = p->second; - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(0); - } - h.update_const((*e).get_const()); - } - - for (GEQ_Iterator e(c->GEQs()); e; e++) { - GEQ_Handle h = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - h.update_coef(r.set_var(cvi.curr_var()->get_position()), cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = cvi.curr_var()->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = r.get_local(g); - else - v2 = r.get_local(g, cvi.curr_var()->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - case Wildcard_Var: { - std::map<Variable_ID, Variable_ID>::iterator p = exists_mapping.find(cvi.curr_var()); - Variable_ID v2; - if (p == exists_mapping.end()) { - v2 = f_exists->declare(); - exists_mapping[cvi.curr_var()] = v2; - } - else - v2 = p->second; - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(0); - } - h.update_const((*e).get_const()); - } - - r.simplify(); - if (!Gist(r, copy(known), 1).is_obvious_tautology()) { - CG_outputRepr *lhs = output_substitution_repr(ocg, result.first, v, false, R, assigned_on_the_fly); - if_repr = ocg->CreateEQ(ocg->CreateIntegerMod(lhs->clone(), ocg->CreateInt(abs(result.first.get_coef(v)))), ocg->CreateInt(0)); - assign_repr = ocg->CreateDivide(lhs, ocg->CreateInt(abs(result.first.get_coef(v)))); - } - else - assign_repr = output_substitution_repr(ocg, result.first, v, true, R, assigned_on_the_fly); - } - else - assign_repr = output_substitution_repr(ocg, result.first, v, true, R, assigned_on_the_fly); - - if (assign_repr == NULL) - assign_repr = ocg->CreateInt(0); - - return std::make_pair(if_repr, std::make_pair(assign_repr, result.second)); -} - - -// -// return NULL if 0 -// -CG_outputRepr *output_substitution_repr(CG_outputBuilder *ocg, const EQ_Handle &equality, Variable_ID v, bool apply_v_coef, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - const_cast<Relation &>(R).setup_names(); // hack - - coef_t a = equality.get_coef(v); - assert(a != 0); - - CG_outputRepr *repr = NULL; - for (Constr_Vars_Iter cvi(equality); cvi; cvi++) - if (cvi.curr_var() != v) { - CG_outputRepr *t; - if (cvi.curr_var()->kind() == Wildcard_Var) { - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, cvi.curr_var()); - if (!result.first) { - delete repr; - throw codegen_error("can't output non floor defined wildcard"); - } - t = output_inequality_repr(ocg, result.second, cvi.curr_var(), R, assigned_on_the_fly); - } - else - t = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly); - coef_t coef = cvi.curr_coef(); - - if (a > 0) { - if (coef > 0) { - if (coef == 1) - repr = ocg->CreateMinus(repr, t); - else - repr = ocg->CreateMinus(repr, ocg->CreateTimes(ocg->CreateInt(coef), t)); - } - else { // coef < 0 - if (coef == -1) - repr = ocg->CreatePlus(repr, t); - else - repr = ocg->CreatePlus(repr, ocg->CreateTimes(ocg->CreateInt(-coef), t)); - } - } - else { - if (coef > 0) { - if (coef == 1) - repr = ocg->CreatePlus(repr, t); - else - repr = ocg->CreatePlus(repr, ocg->CreateTimes(ocg->CreateInt(coef), t)); - } - else { // coef < 0 - if (coef == -1) - repr = ocg->CreateMinus(repr, t); - else - repr = ocg->CreateMinus(repr, ocg->CreateTimes(ocg->CreateInt(-coef), t)); - } - } - } - - int c = equality.get_const(); - if (a > 0) { - if (c > 0) - repr = ocg->CreateMinus(repr, ocg->CreateInt(c)); - else if (c < 0) - repr = ocg->CreatePlus(repr, ocg->CreateInt(-c)); - } - else { - if (c > 0) - repr = ocg->CreatePlus(repr, ocg->CreateInt(c)); - else if (c < 0) - repr = ocg->CreateMinus(repr, ocg->CreateInt(-c)); - } - - if (apply_v_coef && abs(a) != 1) - repr = ocg->CreateDivide(repr, ocg->CreateInt(abs(a))); - - return repr; -} - - -// -// original Substitutions class from omega can't handle integer -// division, this is new way. -// -std::vector<CG_outputRepr*> output_substitutions(CG_outputBuilder *ocg, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - std::vector<CG_outputRepr *> subs; - - for (int i = 1; i <= R.n_out(); i++) { - Relation mapping(R.n_out(), 1); - F_And *f_root = mapping.add_and(); - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.output_var(1), 1); - h.update_coef(mapping.input_var(i), -1); - Relation r = Composition(mapping, copy(R)); - r.simplify(); - - Variable_ID v = r.output_var(1); - CG_outputRepr *repr = NULL; - std::pair<EQ_Handle, int> result = find_simplest_assignment(r, v, assigned_on_the_fly); - if (result.second < INT_MAX) - repr = output_substitution_repr(ocg, result.first, v, true, r, assigned_on_the_fly); - else { - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, v); - if (result.first) - try { - repr = output_inequality_repr(ocg, result.second, v, R, assigned_on_the_fly); - } - catch (const codegen_error &) { - } - } - - subs.push_back(repr); - } - - return subs; -} - - -// -// handle floor definition wildcards in equality, the second in returned pair -// is the cost. -// -std::pair<EQ_Handle, int> find_simplest_assignment(const Relation &R, Variable_ID v, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - Conjunct *c = const_cast<Relation &>(R).single_conjunct(); - - int min_cost = INT_MAX; - EQ_Handle eq; - for (EQ_Iterator e(c->EQs()); e; e++) - if (!(*e).has_wildcards() && (*e).get_coef(v) != 0) { - int cost = 0; - - if (abs((*e).get_coef(v)) != 1) - cost += 4; // divide cost - - int num_var = 0; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var() != v) { - num_var++; - if (abs(cvi.curr_coef()) != 1) - cost += 2; // multiply cost - if (cvi.curr_var()->kind() == Global_Var && cvi.curr_var()->get_global_var()->arity() > 0) - cost += 10; // function cost - else if (cvi.curr_var()->kind() == Input_Var && - assigned_on_the_fly.size() >= cvi.curr_var()->get_position() && - assigned_on_the_fly[cvi.curr_var()->get_position()-1].first != NULL) - cost += assigned_on_the_fly[cvi.curr_var()->get_position()-1].second; // substitution cost on record - } - if ((*e).get_const() != 0) - num_var++; - if (num_var > 1) - cost += num_var - 1; // addition cost - - if (cost < min_cost) { - min_cost = cost; - eq = *e; - } - } - - if (min_cost < INT_MAX) - return std::make_pair(eq, min_cost); - - for (EQ_Iterator e(c->EQs()); e; e++) - if ((*e).has_wildcards() && (*e).get_coef(v) != 0) { - bool is_assignment = true; - for (Constr_Vars_Iter cvi(*e, true); cvi; cvi++) { - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, v); - if (!result.first) { - is_assignment = false; - break; - } - } - if (!is_assignment) - continue; - - int cost = 0; - - if (abs((*e).get_coef(v)) != 1) - cost += 4; // divide cost - - int num_var = 0; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var() != v) { - num_var++; - if (abs(cvi.curr_coef()) != 1) - cost += 2; // multiply cost - if (cvi.curr_var()->kind() == Wildcard_Var) - cost += 10; // floor operation cost - else if (cvi.curr_var()->kind() == Global_Var && cvi.curr_var()->get_global_var()->arity() > 0) - cost += 20; // function cost - else if (cvi.curr_var()->kind() == Input_Var && - assigned_on_the_fly.size() >= cvi.curr_var()->get_position() && - assigned_on_the_fly[cvi.curr_var()->get_position()-1].first != NULL) - cost += assigned_on_the_fly[cvi.curr_var()->get_position()-1].second; // substitution cost on record - } - if ((*e).get_const() != 0) - num_var++; - if (num_var > 1) - cost += num_var - 1; // addition cost - - if (cost < min_cost) { - min_cost = cost; - eq = *e; - } - } - - return std::make_pair(eq, min_cost); -} - - -// -// find floor definition for variable v, e.g. m-c <= 4v <= m, (c is -// constant and 0 <= c < 4). this translates to v = floor(m, 4) and -// return 4v<=m in this case. All wildcards in such inequality are -// also floor defined. -// -std::pair<bool, GEQ_Handle> find_floor_definition(const Relation &R, Variable_ID v, std::set<Variable_ID> excluded_floor_vars) { - Conjunct *c = const_cast<Relation &>(R).single_conjunct(); - - excluded_floor_vars.insert(v); - for (GEQ_Iterator e = c->GEQs(); e; e++) { - coef_t a = (*e).get_coef(v); - if (a >= -1) - continue; - a = -a; - - bool interested = true; - for (std::set<Variable_ID>::const_iterator i = excluded_floor_vars.begin(); i != excluded_floor_vars.end(); i++) - if ((*i) != v && (*e).get_coef(*i) != 0) { - interested = false; - break; - } - if (!interested) - continue; - - // check if any wildcard is floor defined - bool has_undefined_wc = false; - for (Constr_Vars_Iter cvi(*e, true); cvi; cvi++) - if (excluded_floor_vars.find(cvi.curr_var()) == excluded_floor_vars.end()) { - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, cvi.curr_var(), excluded_floor_vars); - if (!result.first) { - has_undefined_wc = true; - break; - } - } - if (has_undefined_wc) - continue; - - // find the matching upper bound for floor definition - for (GEQ_Iterator e2 = c->GEQs(); e2; e2++) - if ((*e2).get_coef(v) == a && (*e).get_const() + (*e2).get_const() < a) { - bool match = true; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if ((*e2).get_coef(cvi.curr_var()) != -cvi.curr_coef()) { - match = false; - break; - } - if (!match) - continue; - for (Constr_Vars_Iter cvi(*e2); cvi; cvi++) - if ((*e).get_coef(cvi.curr_var()) != -cvi.curr_coef()) { - match = false; - break; - } - if (match) - return std::make_pair(true, *e); - } - } - - return std::make_pair(false, GEQ_Handle()); -} - -// -// find the stride involving the specified variable, the stride -// equality can have other wildcards as long as they are defined as -// floor variables. -// -std::pair<EQ_Handle, Variable_ID> find_simplest_stride(const Relation &R, Variable_ID v) { - int best_num_var = INT_MAX; - coef_t best_coef; - EQ_Handle best_eq; - Variable_ID best_stride_wc; - for (EQ_Iterator e(const_cast<Relation &>(R).single_conjunct()->EQs()); e; e++) - if ((*e).has_wildcards() && (*e).get_coef(v) != 0) { - bool is_stride = true; - bool found_free = false; - int num_var = 0; - int num_floor = 0; - Variable_ID stride_wc; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - switch (cvi.curr_var()->kind()) { - case Wildcard_Var: { - bool is_free = true; - for (GEQ_Iterator e2(const_cast<Relation &>(R).single_conjunct()->GEQs()); e2; e2++) - if ((*e2).get_coef(cvi.curr_var()) != 0) { - is_free = false; - break; - } - if (is_free) { - if (found_free) - is_stride = false; - else { - found_free = true; - stride_wc = cvi.curr_var(); - } - } - else { - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, cvi.curr_var()); - if (result.first) - num_floor++; - else - is_stride = false; - } - break; - } - case Input_Var: - num_var++; - break; - default: - ; - } - - if (!is_stride) - break; - } - - if (is_stride) { - coef_t coef = abs((*e).get_coef(v)); - if (best_num_var == INT_MAX || coef < best_coef || - (coef == best_coef && num_var < best_num_var)) { - best_coef = coef; - best_num_var = num_var; - best_eq = *e; - best_stride_wc = stride_wc; - } - } - } - - if (best_num_var != INT_MAX) - return std::make_pair(best_eq, best_stride_wc); - else - return std::make_pair(EQ_Handle(), static_cast<Variable_ID>(NULL)); -} - -// -// convert relation to if-condition -// -CG_outputRepr *output_guard(CG_outputBuilder *ocg, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - assert(R.n_out()==0); - - CG_outputRepr *result = NULL; - Conjunct *c = const_cast<Relation &>(R).single_conjunct(); - - // e.g. 4i=5*j - for (EQ_Iterator e = c->EQs(); e; e++) - if (!(*e).has_wildcards()) { - CG_outputRepr *lhs = NULL; - CG_outputRepr *rhs = NULL; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - CG_outputRepr *v = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly); - coef_t coef = cvi.curr_coef(); - if (coef > 0) { - if (coef == 1) - lhs = ocg->CreatePlus(lhs, v); - else - lhs = ocg->CreatePlus(lhs, ocg->CreateTimes(ocg->CreateInt(coef), v)); - } - else { // coef < 0 - if (coef == -1) - rhs = ocg->CreatePlus(rhs, v); - else - rhs = ocg->CreatePlus(rhs, ocg->CreateTimes(ocg->CreateInt(-coef), v)); - } - } - coef_t c = (*e).get_const(); - - CG_outputRepr *term; - if (lhs == NULL) - term = ocg->CreateEQ(rhs, ocg->CreateInt(c)); - else { - if (c > 0) - rhs = ocg->CreateMinus(rhs, ocg->CreateInt(c)); - else if (c < 0) - rhs = ocg->CreatePlus(rhs, ocg->CreateInt(-c)); - else if (rhs == NULL) - rhs = ocg->CreateInt(0); - term = ocg->CreateEQ(lhs, rhs); - } - result = ocg->CreateAnd(result, term); - } - - // e.g. i>5j - for (GEQ_Iterator e = c->GEQs(); e; e++) - if (!(*e).has_wildcards()) { - CG_outputRepr *lhs = NULL; - CG_outputRepr *rhs = NULL; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - CG_outputRepr *v = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly); - coef_t coef = cvi.curr_coef(); - if (coef > 0) { - if (coef == 1) - lhs = ocg->CreatePlus(lhs, v); - else - lhs = ocg->CreatePlus(lhs, ocg->CreateTimes(ocg->CreateInt(coef), v)); - } - else { // coef < 0 - if (coef == -1) - rhs = ocg->CreatePlus(rhs, v); - else - rhs = ocg->CreatePlus(rhs, ocg->CreateTimes(ocg->CreateInt(-coef), v)); - } - } - coef_t c = (*e).get_const(); - - CG_outputRepr *term; - if (lhs == NULL) - term = ocg->CreateLE(rhs, ocg->CreateInt(c)); - else { - if (c > 0) - rhs = ocg->CreateMinus(rhs, ocg->CreateInt(c)); - else if (c < 0) - rhs = ocg->CreatePlus(rhs, ocg->CreateInt(-c)); - else if (rhs == NULL) - rhs = ocg->CreateInt(0); - term = ocg->CreateGE(lhs, rhs); - } - result = ocg->CreateAnd(result, term); - } - - // e.g. 4i=5j+4alpha - for (EQ_Iterator e = c->EQs(); e; e++) - if ((*e).has_wildcards()) { - Variable_ID wc; - int num_wildcard = 0; - int num_positive = 0; - int num_negative = 0; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - if (cvi.curr_var()->kind() == Wildcard_Var) { - num_wildcard++; - wc = cvi.curr_var(); - } - else { - if (cvi.curr_coef() > 0) - num_positive++; - else - num_negative++; - } - } - - if (num_wildcard > 1) { - delete result; - throw codegen_error("Can't generate equality condition with multiple wildcards"); - } - int sign = (num_positive>=num_negative)?1:-1; - - CG_outputRepr *lhs = NULL; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - if (cvi.curr_var() != wc) { - CG_outputRepr *v = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly); - coef_t coef = cvi.curr_coef(); - if (sign == 1) { - if (coef > 0) { - if (coef == 1) - lhs = ocg->CreatePlus(lhs, v); - else - lhs = ocg->CreatePlus(lhs, ocg->CreateTimes(ocg->CreateInt(coef), v)); - } - else { // coef < 0 - if (coef == -1) - lhs = ocg->CreateMinus(lhs, v); - else - lhs = ocg->CreateMinus(lhs, ocg->CreateTimes(ocg->CreateInt(-coef), v)); - } - } - else { - if (coef > 0) { - if (coef == 1) - lhs = ocg->CreateMinus(lhs, v); - else - lhs = ocg->CreateMinus(lhs, ocg->CreateTimes(ocg->CreateInt(coef), v)); - } - else { // coef < 0 - if (coef == -1) - lhs = ocg->CreatePlus(lhs, v); - else - lhs = ocg->CreatePlus(lhs, ocg->CreateTimes(ocg->CreateInt(-coef), v)); - } - } - } - } - coef_t c = (*e).get_const(); - if (sign == 1) { - if (c > 0) - lhs = ocg->CreatePlus(lhs, ocg->CreateInt(c)); - else if (c < 0) - lhs = ocg->CreateMinus(lhs, ocg->CreateInt(-c)); - } - else { - if (c > 0) - lhs = ocg->CreateMinus(lhs, ocg->CreateInt(c)); - else if (c < 0) - lhs = ocg->CreatePlus(lhs, ocg->CreateInt(-c)); - } - - lhs = ocg->CreateIntegerMod(lhs, ocg->CreateInt(abs((*e).get_coef(wc)))); - CG_outputRepr *term = ocg->CreateEQ(lhs, ocg->CreateInt(0)); - result = ocg->CreateAnd(result, term); - } - - // e.g. 4alpha<=i<=5alpha - for (GEQ_Iterator e = c->GEQs(); e; e++) - if ((*e).has_wildcards()) { - Variable_ID wc; - int num_wildcard = 0; - for (Constr_Vars_Iter cvi(*e, true); cvi; cvi++) - if (num_wildcard == 0) { - wc = cvi.curr_var(); - num_wildcard = 1; - } - else - num_wildcard++; - - if (num_wildcard > 1) { - delete result; - // e.g. c*alpha - x >= 0 (*) - // -d*alpha + y >= 0 (*) - // e1*alpha + f1*beta + g1 >= 0 (**) - // e2*alpha + f2*beta + g2 >= 0 (**) - // ... - // TODO: should generate a testing loop for alpha using its lower and - // upper bounds from (*) constraints and do the same if-condition test - // for beta from each pair of opposite (**) constraints as above, - // and exit the loop when if-condition satisfied. - throw codegen_error("Can't generate multiple wildcard GEQ guards right now"); - } - - coef_t c = (*e).get_coef(wc); - int sign = (c>0)?1:-1; - - GEQ_Iterator e2 = e; - e2++; - for ( ; e2; e2++) { - coef_t c2 = (*e2).get_coef(wc); - if (c2 == 0) - continue; - int sign2 = (c2>0)?1:-1; - if (sign != -sign2) - continue; - int num_wildcard2 = 0; - for (Constr_Vars_Iter cvi(*e2, true); cvi; cvi++) - num_wildcard2++; - if (num_wildcard2 > 1) - continue; - - GEQ_Handle lb, ub; - if (sign == 1) { - lb = (*e); - ub = (*e2); - } - else { - lb = (*e2); - ub = (*e); - } - - CG_outputRepr *lhs = NULL; - for (Constr_Vars_Iter cvi(lb); cvi; cvi++) - if (cvi.curr_var() != wc) { - CG_outputRepr *v = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly); - coef_t coef = cvi.curr_coef(); - if (coef > 0) { - if (coef == 1) - lhs = ocg->CreateMinus(lhs, v); - else - lhs = ocg->CreateMinus(lhs, ocg->CreateTimes(ocg->CreateInt(coef), v)); - } - else { // coef < 0 - if (coef == -1) - lhs = ocg->CreatePlus(lhs, v); - else - lhs = ocg->CreatePlus(lhs, ocg->CreateTimes(ocg->CreateInt(-coef), v)); - } - } - coef_t c = lb.get_const(); - if (c > 0) - lhs = ocg->CreateMinus(lhs, ocg->CreateInt(c)); - else if (c < 0) - lhs = ocg->CreatePlus(lhs, ocg->CreateInt(-c)); - - CG_outputRepr *rhs = NULL; - for (Constr_Vars_Iter cvi(ub); cvi; cvi++) - if (cvi.curr_var() != wc) { - CG_outputRepr *v = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly); - coef_t coef = cvi.curr_coef(); - if (coef > 0) { - if (coef == 1) - rhs = ocg->CreatePlus(rhs, v); - else - rhs = ocg->CreatePlus(rhs, ocg->CreateTimes(ocg->CreateInt(coef), v)); - } - else { // coef < 0 - if (coef == -1) - rhs = ocg->CreateMinus(rhs, v); - else - rhs = ocg->CreateMinus(rhs, ocg->CreateTimes(ocg->CreateInt(-coef), v)); - } - } - c = ub.get_const(); - if (c > 0) - rhs = ocg->CreatePlus(rhs, ocg->CreateInt(c)); - else if (c < 0) - rhs = ocg->CreateMinus(rhs, ocg->CreateInt(-c)); - - rhs = ocg->CreateIntegerFloor(rhs, ocg->CreateInt(-ub.get_coef(wc))); - rhs = ocg->CreateTimes(ocg->CreateInt(lb.get_coef(wc)), rhs); - CG_outputRepr *term = ocg->CreateLE(lhs, rhs); - result = ocg->CreateAnd(result, term); - } - } - - return result; -} - - -// -// return NULL if 0 -// -CG_outputRepr *output_inequality_repr(CG_outputBuilder *ocg, const GEQ_Handle &inequality, Variable_ID v, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly, std::set<Variable_ID> excluded_floor_vars) { - const_cast<Relation &>(R).setup_names(); // hack - - coef_t a = inequality.get_coef(v); - assert(a != 0); - excluded_floor_vars.insert(v); - - CG_outputRepr *repr = NULL; - for (Constr_Vars_Iter cvi(inequality); cvi; cvi++) - if (cvi.curr_var() != v) { - CG_outputRepr *t; - if (cvi.curr_var()->kind() == Wildcard_Var) { - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, cvi.curr_var(), excluded_floor_vars); - if (!result.first) { - delete repr; - throw codegen_error("Can't generate bound expression with wildcard not involved in floor definition"); - } - try { - t = output_inequality_repr(ocg, result.second, cvi.curr_var(), R, assigned_on_the_fly, excluded_floor_vars); - } - catch (const std::exception &e) { - delete repr; - throw e; - } - } - else - t = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly); - - coef_t coef = cvi.curr_coef(); - if (a > 0) { - if (coef > 0) { - if (coef == 1) - repr = ocg->CreateMinus(repr, t); - else - repr = ocg->CreateMinus(repr, ocg->CreateTimes(ocg->CreateInt(coef), t)); - } - else { - if (coef == -1) - repr = ocg->CreatePlus(repr, t); - else - repr = ocg->CreatePlus(repr, ocg->CreateTimes(ocg->CreateInt(-coef), t)); - } - } - else { - if (coef > 0) { - if (coef == 1) - repr = ocg->CreatePlus(repr, t); - else - repr = ocg->CreatePlus(repr, ocg->CreateTimes(ocg->CreateInt(coef), t)); - } - else { - if (coef == -1) - repr = ocg->CreateMinus(repr, t); - else - repr = ocg->CreateMinus(repr, ocg->CreateTimes(ocg->CreateInt(-coef), t)); - } - } - } - coef_t c = inequality.get_const(); - if (c > 0) { - if (a > 0) - repr = ocg->CreateMinus(repr, ocg->CreateInt(c)); - else - repr = ocg->CreatePlus(repr, ocg->CreateInt(c)); - } - else if (c < 0) { - if (a > 0) - repr = ocg->CreatePlus(repr, ocg->CreateInt(-c)); - else - repr = ocg->CreateMinus(repr, ocg->CreateInt(-c)); - } - - if (abs(a) == 1) - return repr; - else if (a > 0) - return ocg->CreateIntegerCeil(repr, ocg->CreateInt(a)); - else // a < 0 - return ocg->CreateIntegerFloor(repr, ocg->CreateInt(-a)); -} - - -// -// nothing special, just an alias -// -CG_outputRepr *output_upper_bound_repr(CG_outputBuilder *ocg, const GEQ_Handle &inequality, Variable_ID v, const Relation &R, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - assert(inequality.get_coef(v) < 0); - CG_outputRepr* zero_; - - zero_ = output_inequality_repr(ocg, inequality, v, R, assigned_on_the_fly); - - if(!zero_) - zero_ = ocg->CreateInt(0); - - return zero_; - -} - - -// -// output lower bound with respect to lattice -// -CG_outputRepr *output_lower_bound_repr(CG_outputBuilder *ocg, const GEQ_Handle &inequality, Variable_ID v, const EQ_Handle &stride_eq, Variable_ID wc, const Relation &R, const Relation &known, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - assert(inequality.get_coef(v) > 0); - CG_outputRepr* zero_; - if (wc == NULL || bound_must_hit_stride(inequality, v, stride_eq, wc, R, known)){ - zero_ = output_inequality_repr(ocg, inequality, v, R, assigned_on_the_fly); - if(!zero_) - zero_ = ocg->CreateInt(0); - - return zero_; - } - CG_outputRepr *strideBoundRepr = NULL; - int sign = (stride_eq.get_coef(v)>0)?1:-1; - for (Constr_Vars_Iter cvi(stride_eq); cvi; cvi++) { - Variable_ID v2 = cvi.curr_var(); - if (v2 == v || v2 == wc) - continue; - - CG_outputRepr *v_repr; - if (v2->kind() == Input_Var || v2->kind() == Global_Var) - v_repr = output_ident(ocg, R, v2, assigned_on_the_fly); - else if (v2->kind() == Wildcard_Var) { - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, v2); - assert(result.first); - v_repr = output_inequality_repr(ocg, result.second, v2, R, assigned_on_the_fly); - } - - coef_t coef = cvi.curr_coef(); - if (sign < 0) { - if (coef > 0) { - if (coef == 1) - strideBoundRepr = ocg->CreatePlus(strideBoundRepr, v_repr); - else - strideBoundRepr = ocg->CreatePlus(strideBoundRepr, ocg->CreateTimes(ocg->CreateInt(coef), v_repr)); - } - else { // coef < 0 - if (coef == -1) - strideBoundRepr = ocg->CreateMinus(strideBoundRepr, v_repr); - else - strideBoundRepr = ocg->CreateMinus(strideBoundRepr, ocg->CreateTimes(ocg->CreateInt(-coef), v_repr)); - } - } - else { - if (coef > 0) { - if (coef == 1) - strideBoundRepr = ocg->CreateMinus(strideBoundRepr, v_repr); - else - strideBoundRepr = ocg->CreateMinus(strideBoundRepr, ocg->CreateTimes(ocg->CreateInt(coef), v_repr)); - } - else { // coef < 0 - if (coef == -1) - strideBoundRepr = ocg->CreatePlus(strideBoundRepr, v_repr); - else - strideBoundRepr = ocg->CreatePlus(strideBoundRepr, ocg->CreateTimes(ocg->CreateInt(-coef), v_repr)); - } - } - } - coef_t c = stride_eq.get_const(); - if (c > 0) { - if (sign < 0) - strideBoundRepr = ocg->CreatePlus(strideBoundRepr, ocg->CreateInt(c)); - else - strideBoundRepr = ocg->CreateMinus(strideBoundRepr, ocg->CreateInt(c)); - } - else if (c < 0) { - if (sign < 0) - strideBoundRepr = ocg->CreateMinus(strideBoundRepr, ocg->CreateInt(-c)); - else - strideBoundRepr = ocg->CreatePlus(strideBoundRepr, ocg->CreateInt(-c)); - } - - CG_outputRepr *repr = output_inequality_repr(ocg, inequality, v, R, assigned_on_the_fly); - CG_outputRepr *repr2 = ocg->CreateCopy(repr); - repr = ocg->CreatePlus(repr2, ocg->CreateIntegerMod(ocg->CreateMinus(strideBoundRepr, repr), ocg->CreateInt(abs(stride_eq.get_coef(wc))))); - - return repr; -} - - -// -// return loop control structure only -// -CG_outputRepr *output_loop(CG_outputBuilder *ocg, const Relation &R, int level, const Relation &known, const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(R, const_cast<Relation &>(R).set_var(level)); - if (result.second != NULL) - assert(abs(result.first.get_coef(const_cast<Relation &>(R).set_var(level))) == 1); - - std::vector<CG_outputRepr *> lbList, ubList; - try { - - coef_t const_lb = negInfinity, const_ub = posInfinity; - - for (GEQ_Iterator e(const_cast<Relation &>(R).single_conjunct()->GEQs()); e; e++) { - coef_t coef = (*e).get_coef(const_cast<Relation &>(R).set_var(level)); - - if (coef > 0) { - CG_outputRepr *repr = output_lower_bound_repr(ocg, *e, const_cast<Relation &>(R).set_var(level), result.first, result.second, R, known, assigned_on_the_fly); - if (repr == NULL) - repr = ocg->CreateInt(0); - lbList.push_back(repr); - - if ((*e).is_const(const_cast<Relation &>(R).set_var(level))){ - if(!result.second) { - - //no variables but v in constr - coef_t L,m; - L = -((*e).get_const()); - - m = (*e).get_coef(const_cast<Relation &>(R).set_var(level)); - coef_t sb = (int) (ceil(((float) L) /m)); - set_max(const_lb, sb); - } - else{ - - coef_t L,m,s,c; - L = -((*e).get_const()); - m = (*e).get_coef(const_cast<Relation &>(R).set_var(level)); - s = abs(result.first.get_coef(result.second)); - c = result.first.get_const(); - coef_t sb = (s * (int) (ceil( (float) (L - (c * m)) /(s*m))))+ c; - set_max(const_lb, sb); - - } - } - - } - else if (coef < 0) { - CG_outputRepr *repr = output_upper_bound_repr(ocg, *e, const_cast<Relation &>(R).set_var(level), R, assigned_on_the_fly); - if (repr == NULL) - repr = ocg->CreateInt(0); - ubList.push_back(repr); - - if ((*e).is_const(const_cast<Relation &>(R).set_var(level))) { - // no variables but v in constraint - set_min(const_ub,-(*e).get_const()/(*e).get_coef(const_cast<Relation &>(R).set_var(level))); - } - - } - } - - if(fillInBounds && lbList.size() == 1 && const_lb != negInfinity) - lowerBoundForLevel = const_lb; - - if(fillInBounds && const_ub != posInfinity) - upperBoundForLevel = const_ub; - if (lbList.size() == 0) - throw codegen_error("missing lower bound at loop level " + to_string(level)); - if (ubList.size() == 0) - throw codegen_error("missing upper bound at loop level " + to_string(level)); - } - catch (const std::exception &e) { - for (int i = 0; i < lbList.size(); i++) - delete lbList[i]; - for (int i = 0; i < ubList.size(); i++) - delete ubList[i]; - throw e; - } - - CG_outputRepr *lbRepr = NULL; - if (lbList.size() > 1) - lbRepr = ocg->CreateInvoke("max", lbList); - else // (lbList.size() == 1) - lbRepr = lbList[0]; - - CG_outputRepr *ubRepr = NULL; - if (ubList.size() > 1) - ubRepr = ocg->CreateInvoke("min", ubList); - else // (ubList.size() == 1) - ubRepr = ubList[0]; - - CG_outputRepr *stRepr; - if (result.second == NULL) - stRepr = ocg->CreateInt(1); - else - stRepr = ocg->CreateInt(abs(result.first.get_coef(result.second))); - CG_outputRepr *indexRepr = output_ident(ocg, R, const_cast<Relation &>(R).set_var(level), assigned_on_the_fly); - return ocg->CreateInductive(indexRepr, lbRepr, ubRepr, stRepr); -} - - -// -// parameter f_root is inside f_exists, not the other way around. -// return replicated variable in new relation, with all cascaded floor definitions -// using wildcards defined in the same way as in the original relation. -// -Variable_ID replicate_floor_definition(const Relation &R, const Variable_ID floor_var, - Relation &r, F_Exists *f_exists, F_And *f_root, - std::map<Variable_ID, Variable_ID> &exists_mapping) { - assert(R.n_out() == 0 && r.n_out() == 0 && R.n_inp() == r.n_inp()); - - std::set<Variable_ID> excluded_floor_vars; - std::stack<Variable_ID> to_fill; - to_fill.push(floor_var); - - while (!to_fill.empty()) { - Variable_ID v = to_fill.top(); - to_fill.pop(); - if (excluded_floor_vars.find(v) != excluded_floor_vars.end()) - continue; - - std::pair<bool, GEQ_Handle> result = find_floor_definition(R, v, excluded_floor_vars); - assert(result.first); - excluded_floor_vars.insert(v); - - GEQ_Handle h1 = f_root->add_GEQ(); - GEQ_Handle h2 = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(result.second); cvi; cvi++) { - Variable_ID v2 = cvi.curr_var(); - switch (v2->kind()) { - case Input_Var: { - int pos = v2->get_position(); - h1.update_coef(r.input_var(pos), cvi.curr_coef()); - h2.update_coef(r.input_var(pos), -cvi.curr_coef()); - break; - } - case Wildcard_Var: { - std::map<Variable_ID, Variable_ID>::iterator p = exists_mapping.find(v2); - Variable_ID v3; - if (p == exists_mapping.end()) { - v3 = f_exists->declare(); - exists_mapping[v2] = v3; - } - else - v3 = p->second; - h1.update_coef(v3, cvi.curr_coef()); - h2.update_coef(v3, -cvi.curr_coef()); - if (v2 != v) - to_fill.push(v2); - break; - } - case Global_Var: { - Global_Var_ID g = v2->get_global_var(); - Variable_ID v3; - if (g->arity() == 0) - v3 = r.get_local(g); - else - v3 = r.get_local(g, v2->function_of()); - h1.update_coef(v3, cvi.curr_coef()); - h2.update_coef(v3, -cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h1.update_const(result.second.get_const()); - h2.update_const(-result.second.get_const()-result.second.get_coef(v)-1); - } - - if (floor_var->kind() == Input_Var) - return r.input_var(floor_var->get_position()); - else if (floor_var->kind() == Wildcard_Var) - return exists_mapping[floor_var]; - else - assert(false); -} - - -// -// pick one guard condition from relation. it can involve multiple -// constraints when involving wildcards, as long as its complement -// is a single conjunct. -// -Relation pick_one_guard(const Relation &R, int level) { - assert(R.n_out()==0); - - Relation r = Relation::True(R.n_set()); - - for (GEQ_Iterator e(const_cast<Relation &>(R).single_conjunct()->GEQs()); e; e++) - if (!(*e).has_wildcards()) { - r.and_with_GEQ(*e); - r.simplify(); - r.copy_names(R); - r.setup_names(); - return r; - } - - for (EQ_Iterator e(const_cast<Relation &>(R).single_conjunct()->EQs()); e; e++) - if (!(*e).has_wildcards()) { - r.and_with_GEQ(*e); - r.simplify(); - r.copy_names(R); - r.setup_names(); - return r; - } - - for (EQ_Iterator e(const_cast<Relation &>(R).single_conjunct()->EQs()); e; e++) - if ((*e).has_wildcards()) { - int num_wildcard = 0; - int max_level = 0; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Wildcard_Var: - num_wildcard++; - break; - case Input_Var: - if (cvi.curr_var()->get_position() > max_level) - max_level = cvi.curr_var()->get_position(); - break; - default: - ; - } - - if (num_wildcard == 1 && max_level != level-1) { - r.and_with_EQ(*e); - r.simplify(); - r.copy_names(R); - r.setup_names(); - return r; - } - } - - for (GEQ_Iterator e(const_cast<Relation &>(R).single_conjunct()->GEQs()); e; e++) - if ((*e).has_wildcards()) { - int num_wildcard = 0; - int max_level = 0; - bool direction; - Variable_ID wc; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Wildcard_Var: - num_wildcard++; - wc = cvi.curr_var(); - direction = cvi.curr_coef()>0?true:false; - break; - case Input_Var: - if (cvi.curr_var()->get_position() > max_level) - max_level = cvi.curr_var()->get_position(); - break; - default: - ; - } - - if (num_wildcard == 1 && max_level != level-1) { - // find the pairing inequality - GEQ_Iterator e2 = e; - e2++; - for ( ; e2; e2++) { - int num_wildcard2 = 0; - int max_level2 = 0; - bool direction2; - Variable_ID wc2; - for (Constr_Vars_Iter cvi(*e2); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Wildcard_Var: - num_wildcard2++; - wc2 = cvi.curr_var(); - direction2 = cvi.curr_coef()>0?true:false; - break; - case Input_Var: - if (cvi.curr_var()->get_position() > max_level2) - max_level2 = cvi.curr_var()->get_position(); - break; - default: - ; - } - - if (num_wildcard2 == 1 && max_level2 != level-1 && wc2 == wc && direction2 == not direction) { - F_Exists *f_exists = r.and_with_and()->add_exists(); - Variable_ID wc3 = f_exists->declare(); - F_And *f_root = f_exists->add_and(); - GEQ_Handle h = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - switch (cvi.curr_var()->kind()) { - case Wildcard_Var: - h.update_coef(wc3, cvi.curr_coef()); - break; - case Input_Var: - h.update_coef(r.input_var(cvi.curr_var()->get_position()), cvi.curr_coef()); - break; - case Global_Var: { - Global_Var_ID g = cvi.curr_var()->get_global_var(); - Variable_ID v; - if (g->arity() == 0) - v = r.get_local(g); - else - v = r.get_local(g, cvi.curr_var()->function_of()); - h.update_coef(v, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h.update_const((*e).get_const()); - - h = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(*e2); cvi; cvi++) { - switch (cvi.curr_var()->kind()) { - case Wildcard_Var: - h.update_coef(wc3, cvi.curr_coef()); - break; - case Input_Var: - h.update_coef(r.input_var(cvi.curr_var()->get_position()), cvi.curr_coef()); - break; - case Global_Var: { - Global_Var_ID g = cvi.curr_var()->get_global_var(); - Variable_ID v; - if (g->arity() == 0) - v = r.get_local(g); - else - v = r.get_local(g, cvi.curr_var()->function_of()); - h.update_coef(v, cvi.curr_coef()); - break; - } - default: - assert(false); - } - } - h.update_const((*e2).get_const()); - - r.simplify(); - r.copy_names(R); - r.setup_names(); - return r; - } - } - } - } -} - - -// -// heavy lifting for code output for one leaf node -// -CG_outputRepr *leaf_print_repr(BoolSet<> active, const std::map<int, Relation> &guards, - CG_outputRepr *guard_repr, const Relation &known, - int indent, CG_outputBuilder *ocg, const std::vector<int> &remap, - const std::vector<Relation> &xforms, const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - if (active.num_elem() == 0) - return NULL; - - CG_outputRepr *stmt_list = NULL; - for (BoolSet<>::iterator i = active.begin(); i != active.end(); i++) { - std::map<int, Relation>::const_iterator j = guards.find(*i); - if (j == guards.end() || Must_Be_Subset(copy(known), copy(j->second))) { - Relation mapping = Inverse(copy((xforms[remap[*i]]))); - mapping.simplify(); - mapping.setup_names(); - std::vector<std::string> loop_vars; - for (int k = 1; k <= mapping.n_out(); k++) { - loop_vars.push_back(mapping.output_var(k)->name()); -// std::cout << "CG_Utils:: " << k << ", " << mapping.output_var(k)->name().c_str() << "\n"; - } - std::vector<CG_outputRepr *> sList = output_substitutions(ocg, mapping, assigned_on_the_fly); - stmt_list = ocg->StmtListAppend(stmt_list, ocg->CreateSubstitutedStmt((guard_repr==NULL)?indent:indent+1, stmts[remap[*i]]->clone(), loop_vars, sList)); - active.unset(*i); - } - } - - if (stmt_list != NULL) { - if (active.num_elem() != 0) - stmt_list = ocg->StmtListAppend(stmt_list, leaf_print_repr(active, guards, NULL, known, (guard_repr==NULL)?indent:indent+1, ocg, remap, xforms, stmts, assigned_on_the_fly)); - if (guard_repr == NULL) - return stmt_list; - else - return ocg->CreateIf(indent, guard_repr, stmt_list, NULL); - } - else { - Relation then_cond = find_best_guard(const_cast<std::map<int, Relation> &>(guards)[*(active.begin())], active, guards); - assert(!then_cond.is_obvious_tautology()); - Relation new_then_known = Intersection(copy(known), copy(then_cond)); - new_then_known.simplify(); - Relation else_cond = Complement(copy(then_cond)); - else_cond.simplify(); - Relation new_else_known = Intersection(copy(known), copy(else_cond)); - new_else_known.simplify(); - - BoolSet<> then_active(active.size()), else_active(active.size()), indep_active(active.size()); - std::map<int, Relation> then_guards, else_guards; - for (BoolSet<>::iterator i = active.begin(); i != active.end(); i++) { - Relation &r = const_cast<std::map<int, Relation> &>(guards)[*i]; - if (Must_Be_Subset(copy(r), copy(then_cond))) { - Relation r2 = Gist(copy(r), copy(then_cond), 1); - if (!r2.is_obvious_tautology()) - then_guards[*i] = r2; - then_active.set(*i); - } - else if (Must_Be_Subset(copy(r), copy(else_cond))) { - Relation r2 = Gist(copy(r), copy(else_cond), 1); - if (!r2.is_obvious_tautology()) - else_guards[*i] = r2; - else_active.set(*i); - } - else - indep_active.set(*i); - } - assert(!then_active.empty()); - - CG_outputRepr *new_guard_repr = output_guard(ocg, then_cond, assigned_on_the_fly); - if (else_active.empty() && indep_active.empty()) { - guard_repr = ocg->CreateAnd(guard_repr, new_guard_repr); - return leaf_print_repr(then_active, then_guards, guard_repr, new_then_known, indent, ocg, remap, xforms, stmts, assigned_on_the_fly); - } - else if (else_active.empty() && !indep_active.empty()) { - int new_indent = (guard_repr==NULL)?indent:indent+1; - stmt_list = leaf_print_repr(then_active, then_guards, new_guard_repr, new_then_known, new_indent, ocg, remap, xforms, stmts, assigned_on_the_fly); - stmt_list = ocg->StmtListAppend(stmt_list, leaf_print_repr(indep_active, guards, NULL, known, new_indent, ocg, remap, xforms, stmts, assigned_on_the_fly)); - if (guard_repr == NULL) - return stmt_list; - else - return ocg->CreateIf(indent, guard_repr, stmt_list, NULL); - } - else { // (!else_active.empty()) - int new_indent = (guard_repr==NULL)?indent:indent+1; - CG_outputRepr *then_stmt_list = leaf_print_repr(then_active, then_guards, NULL, new_then_known, new_indent+1, ocg, remap, xforms, stmts, assigned_on_the_fly); - CG_outputRepr *else_stmt_list = leaf_print_repr(else_active, else_guards, NULL, new_else_known, new_indent+1, ocg, remap, xforms, stmts, assigned_on_the_fly); - stmt_list = ocg->CreateIf(new_indent, new_guard_repr, then_stmt_list, else_stmt_list); - if (!indep_active.empty()) - stmt_list = ocg->StmtListAppend(stmt_list, leaf_print_repr(indep_active, guards, NULL, known, new_indent, ocg, remap, xforms, stmts, assigned_on_the_fly)); - if (guard_repr == NULL) - return stmt_list; - else - return ocg->CreateIf(indent, guard_repr, stmt_list, NULL); - } - } -} - - -// -// heavy lifting for code output for one level of loop nodes -// -CG_outputRepr *loop_print_repr(const std::vector<CG_loop *> &loops, int start, int end, - const Relation &guard, CG_outputRepr *guard_repr, - int indent, CG_outputBuilder *ocg, const std::vector<CG_outputRepr *> &stmts, - const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly) { - if (start >= end) - return NULL; - - Relation R = Gist(copy(loops[start]->guard_), copy(guard), 1); - if (Must_Be_Subset(Intersection(copy(loops[start]->known_), copy(guard)), copy(R))) { - int new_indent = (guard_repr==NULL)?indent:indent+1; - int i = start+1; - for ( ; i < end; i++) - if (!Gist(copy(loops[i]->guard_), copy(guard), 1).is_obvious_tautology()) - break; - CG_outputRepr *stmt_list = NULL; - for (int j = start; j < i; j++) - stmt_list = ocg->StmtListAppend(stmt_list, loops[j]->printRepr(false, new_indent, ocg, stmts, assigned_on_the_fly)); - stmt_list = ocg->StmtListAppend(stmt_list, loop_print_repr(loops, i, end, guard, NULL, new_indent, ocg, stmts, assigned_on_the_fly)); - if (guard_repr == NULL) - return stmt_list; - else - return ocg->CreateIf(indent, guard_repr, stmt_list, NULL); - } - - Relation then_cond = find_best_guard(R, loops, start, end); - assert(!then_cond.is_obvious_tautology()); - Relation else_cond = Complement(copy(then_cond)); - else_cond.simplify(); - - std::vector<CG_loop *> then_loops, else_loops, indep_loops; - int i = start; - for ( ; i < end; i++) - if (!Must_Be_Subset(copy(loops[i]->guard_), copy(then_cond))) - break; - int j = i; - for ( ; j < end; j++) - if (!Must_Be_Subset(copy(loops[j]->guard_), copy(else_cond))) - break; - assert(i>start); - - CG_outputRepr *new_guard_repr = output_guard(ocg, then_cond, assigned_on_the_fly); - if (j == i && end == j) { - guard_repr = ocg->CreateAnd(guard_repr, new_guard_repr); - Relation new_guard = Intersection(copy(guard), copy(then_cond)); - new_guard.simplify(); - return loop_print_repr(loops, start, end, new_guard, guard_repr, indent, ocg, stmts, assigned_on_the_fly); - } - else if (j == i && end > j) { - int new_indent = (guard_repr==NULL)?indent:indent+1; - Relation new_guard = Intersection(copy(guard), copy(then_cond)); - new_guard.simplify(); - CG_outputRepr *stmt_list = loop_print_repr(loops, start, i, new_guard, new_guard_repr, new_indent, ocg, stmts, assigned_on_the_fly); - stmt_list = ocg->StmtListAppend(stmt_list, loop_print_repr(loops, j, end, guard, NULL, new_indent, ocg, stmts, assigned_on_the_fly)); - if (guard_repr == NULL) - return stmt_list; - else - return ocg->CreateIf(indent, guard_repr, stmt_list, NULL); - } - else { // (j > i) - int new_indent = (guard_repr==NULL)?indent:indent+1; - Relation then_new_guard = Intersection(copy(guard), copy(then_cond)); - then_new_guard.simplify(); - CG_outputRepr *then_stmt_list = loop_print_repr(loops, start, i, then_new_guard, NULL, new_indent+1, ocg, stmts, assigned_on_the_fly); - Relation else_new_guard = Intersection(copy(guard), copy(else_cond)); - else_new_guard.simplify(); - CG_outputRepr *else_stmt_list = loop_print_repr(loops, i, j, else_new_guard, NULL, new_indent+1, ocg, stmts, assigned_on_the_fly); - CG_outputRepr *stmt_list = ocg->CreateIf(new_indent, new_guard_repr, then_stmt_list, else_stmt_list); - stmt_list = ocg->StmtListAppend(stmt_list, loop_print_repr(loops, j, end, guard, NULL, new_indent, ocg, stmts, assigned_on_the_fly)); - if (guard_repr == NULL) - return stmt_list; - else - return ocg->CreateIf(indent, guard_repr, stmt_list, NULL); - } -} - -} diff --git a/omegalib/codegen/src/codegen.cc b/omegalib/codegen/src/codegen.cc deleted file mode 100755 index 92ca702..0000000 --- a/omegalib/codegen/src/codegen.cc +++ /dev/null @@ -1,378 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - CodeGen class as entry point for code generation. - - Notes: - Loop variable name prefix should not cause any possible name conflicts - with original loop variables wrapped in statement holder. This guarantees - that variable substitution done correctly in the generated code. - - History: - 04/24/96 MMGenerateCode, added by Fortran D people. Lei Zhou - 09/17/08 loop overhead removal based on actual nesting depth -- by chun - 03/05/11 fold MMGenerateCode into CodeGen class, Chun Chen -*****************************************************************************/ - -#include <typeinfo> -#include <omega.h> -#include <basic/util.h> -#include <math.h> -#include <vector> -#include <algorithm> - -#include <code_gen/CG.h> -#include <code_gen/codegen.h> -#include <code_gen/CG_outputBuilder.h> -#include <code_gen/codegen_error.h> - -namespace omega { - -const std::string CodeGen::loop_var_name_prefix = "t"; -const int CodeGen::var_substitution_threshold = 10; - -//Anand--adding stuff to make Chun's code work with Gabe's -std::vector< std::vector<int> > smtNonSplitLevels; -std::vector< std::vector<std::string> > loopIdxNames;//per stmt -std::vector< std::pair<int, std::string> > syncs; - - - -CodeGen::CodeGen(const std::vector<Relation> &xforms, const std::vector<Relation> &IS, const Relation &known, std::vector< std::vector<int> > smtNonSplitLevels_ , std::vector< std::vector<std::string> > loopIdxNames_, std::vector< std::pair<int, std::string> > syncs_) { - // check for sanity of parameters - int num_stmt = IS.size(); - if (xforms.size() != num_stmt) - throw std::invalid_argument("number of iteration spaces does not match number of transformations"); - known_ = copy(known); - if (known_.n_out() != 0) - throw std::invalid_argument("known condition must be a set relation"); - if (known_.is_null()) - known_ = Relation::True(0); - else - known_.simplify(2, 4); - if (!known_.is_upper_bound_satisfiable()) - return; - if (known_.number_of_conjuncts() > 1) - throw std::invalid_argument("only one conjunct allowed in known condition"); - xforms_ = xforms; - for (int i = 0; i < num_stmt; i++) { - xforms_[i].simplify(); - if (!xforms_[i].has_single_conjunct()) - throw std::invalid_argument("mapping relation must have only one conjunct"); - if (xforms_[i].n_inp() != IS[i].n_inp() || IS[i].n_out() != 0) - throw std::invalid_argument("illegal iteration space or transformation arity"); - } - - - //protonu-- - //easier to handle this as a global - smtNonSplitLevels = smtNonSplitLevels_; - syncs = syncs_; - loopIdxNames = loopIdxNames_; - //end-protonu - - - - // find the maximum iteration space dimension we are going to operate on - int num_level = known_.n_inp(); - for (int i = 0; i < num_stmt; i++) - if (xforms_[i].n_out() > num_level) - num_level = xforms_[i].n_out(); - known_ = Extend_Set(known_, num_level-known_.n_inp()); - for (int i = 1; i <= num_level; i++) - known_.name_set_var(i, loop_var_name_prefix + to_string(i)); - known_.setup_names(); - - // split disjoint conjunctions in original iteration spaces - std::vector<Relation> new_IS; - for (int i = 0; i < num_stmt; i++) { - for (int j = 1; j <= IS[i].n_inp(); j++) - xforms_[i].name_input_var(j, const_cast<std::vector<Relation> &>(IS)[i].input_var(j)->name()); - for (int j = 1; j <= xforms_[i].n_out(); j++) - xforms_[i].name_output_var(j, loop_var_name_prefix + to_string(j)); - xforms_[i].setup_names(); - - Relation R = Range(Restrict_Domain(copy(xforms_[i]), copy(IS[i]))); - R = Intersection(Extend_Set(R, num_level-R.n_inp()), copy(known_)); - R.simplify(2, 4); - if (R.is_inexact()) - throw codegen_error("cannot generate code for inexact iteration spaces"); - - while(R.is_upper_bound_satisfiable()) { - DNF *dnf = R.query_DNF(); - DNF_Iterator c(dnf); - Relation R2 = Relation(R, *c); - R2.simplify(); - new_IS.push_back(copy(R2)); - remap_.push_back(i); - c.next(); - if (!c.live()) - break; - Relation remainder(R, *c); - c.next(); - while (c.live()) { - remainder = Union(remainder, Relation(R, *c)); - c.next(); - } - R = Difference(remainder, R2); - R.simplify(2, 4); - } - } - - // number of new statements after splitting - num_stmt = new_IS.size(); - if(!smtNonSplitLevels.empty()) - smtNonSplitLevels.resize(num_stmt); - // assign a dummy value to loops created for the purpose of expanding to maximum dimension - for (int i = 0; i < num_stmt; i++) { - if (xforms[remap_[i]].n_out() < num_level) { - F_And *f_root = new_IS[i].and_with_and(); - for (int j = xforms[remap_[i]].n_out()+1; j <= num_level; j++) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(new_IS[i].set_var(j), 1); - h.update_const(posInfinity); - } - new_IS[i].simplify(); - } - } - - // calculate projected subspaces for each loop level once and save for CG tree manipulation later - projected_IS_ = std::vector<std::vector<Relation> >(num_level); - for (int i = 0; i < num_level; i++) - projected_IS_[i] = std::vector<Relation>(num_stmt); - for (int i = 0; i < num_stmt; i++) { - if (num_level > 0) - projected_IS_[num_level-1][i] = new_IS[i]; - for (int j = num_level-1; j >= 1; j--) { - projected_IS_[j-1][i] = Project(copy(projected_IS_[j][i]), j+1, Set_Var); - projected_IS_[j-1][i].simplify(2, 4); - } - } -} - - -CG_result *CodeGen::buildAST(int level, const BoolSet<> &active, bool split_on_const, const Relation &restriction) { - if (level > num_level()) - return new CG_leaf(this, active); - - int num_active_stmt = active.num_elem(); - if (num_active_stmt == 0) - return NULL; - else if (num_active_stmt == 1) - return new CG_loop(this, active, level, buildAST(level+1, active, true, restriction)); - - // use estimated constant bounds for fast non-overlap iteration space splitting - if (split_on_const) { - std::vector<std::pair<std::pair<coef_t, coef_t>, int> > bounds; - - for (BoolSet<>::const_iterator i = active.begin(); i != active.end(); i++) { - Relation r = Intersection(copy(projected_IS_[level-1][*i]), copy(restriction)); - r.simplify(2, 4); - if (!r.is_upper_bound_satisfiable()) - continue; - coef_t lb, ub; - r.single_conjunct()->query_variable_bounds(r.set_var(level),lb,ub); - bounds.push_back(std::make_pair(std::make_pair(lb, ub), *i)); - } - sort(bounds.begin(), bounds.end()); - - std::vector<Relation> split_cond; - std::vector<CG_result *> split_child; - - coef_t prev_val = -posInfinity; - coef_t next_val = bounds[0].first.second; - BoolSet<> next_active(active.size()); - int i = 0; - while (i < bounds.size()) { - if (bounds[i].first.first <= next_val) { - next_active.set(bounds[i].second); - next_val = max(next_val, bounds[i].first.second); - i++; - } - else { - Relation r(num_level()); - F_And *f_root = r.add_and(); - if (prev_val != -posInfinity) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(r.set_var(level), 1); - h.update_const(-prev_val-1); - } - if (next_val != posInfinity) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(r.set_var(level), -1); - h.update_const(next_val); - } - r.simplify(); - - Relation new_restriction = Intersection(copy(r), copy(restriction)); - new_restriction.simplify(2, 4); - CG_result *child = buildAST(level, next_active, false, new_restriction); - if (child != NULL) { - split_cond.push_back(copy(r)); - split_child.push_back(child); - } - next_active.unset_all(); - prev_val = next_val; - next_val = bounds[i].first.second; - } - } - if (!next_active.empty()) { - Relation r = Relation::True(num_level()); - if (prev_val != -posInfinity) { - F_And *f_root = r.and_with_and(); - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(r.set_var(level), 1); - h.update_const(-prev_val-1); - r.simplify(); - } - Relation new_restriction = Intersection(copy(r), copy(restriction)); - new_restriction.simplify(2, 4); - CG_result *child = buildAST(level, next_active, false, new_restriction); - if (child != NULL) { - split_cond.push_back(copy(r)); - split_child.push_back(child); - } - } - - if (split_child.size() == 0) - return NULL; - else if (split_child.size() == 1) - return split_child[0]; - else - return new CG_split(this, active, split_cond, split_child); - } - // check bound conditions exhaustively for non-overlap iteration space splitting - else { - std::vector<Relation> Rs(active.size()); - for (BoolSet<>::const_iterator i = active.begin(); i != active.end(); i++) { - Rs[*i] = Intersection(Approximate(copy(projected_IS_[level-1][*i])), copy(restriction)); - Rs[*i].simplify(2, 4); - } - Relation hull = SimpleHull(Rs); - - //protonu-warn Chun about this change - //This does some fancy splitting of statements into loops with the - //fewest dimentions, but that's not necessarily what we want when - //code-gening for CUDA. smtNonSplitLevels keeps track per-statment of - //the levels that should not be split on. - bool checkForSplits = true; - for (BoolSet<>::const_iterator i = active.begin(); i != active.end(); i++) { - if(*i < smtNonSplitLevels.size()) - for(int k = 0; k <smtNonSplitLevels[*i].size(); k++) - if(smtNonSplitLevels[*i][k] == (level-2)){ - checkForSplits = false; - break; - } - } - - - - - for (BoolSet<>::const_iterator i = active.begin(); i != active.end() && checkForSplits; i++) { - Relation r = Gist(copy(Rs[*i]), copy(hull), 1); - if (r.is_obvious_tautology()) - continue; - r = EQs_to_GEQs(r); - - for (GEQ_Iterator e = r.single_conjunct()->GEQs(); e; e++) { - if ((*e).has_wildcards()) - continue; - - Relation cond = Relation::True(num_level()); - BoolSet<> first_chunk(active.size()); - BoolSet<> second_chunk(active.size()); - - if ((*e).get_coef(hull.set_var(level)) > 0) { - cond.and_with_GEQ(*e); - cond = Complement(cond);; - cond.simplify(); - second_chunk.set(*i); - } - else if ((*e).get_coef(hull.set_var(level)) < 0) { - cond.and_with_GEQ(*e); - cond.simplify(); - first_chunk.set(*i); - } - else - continue; - - bool is_proper_split_cond = true; - for (BoolSet<>::const_iterator j = active.begin(); j != active.end(); j++) - if ( *j != *i) { - bool in_first = Intersection(copy(Rs[*j]), copy(cond)).is_upper_bound_satisfiable(); - bool in_second = Difference(copy(Rs[*j]), copy(cond)).is_upper_bound_satisfiable(); - - if (in_first && in_second) { - is_proper_split_cond = false; - break; - } - - if (in_first) - first_chunk.set(*j); - else if (in_second) - second_chunk.set(*j); - } - - if (is_proper_split_cond && first_chunk.num_elem() != 0 && second_chunk.num_elem() != 0) { - CG_result *first_cg = buildAST(level, first_chunk, false, copy(cond)); - CG_result *second_cg = buildAST(level, second_chunk, false, Complement(copy(cond))); - if (first_cg == NULL) - return second_cg; - else if (second_cg == NULL) - return first_cg; - else { - std::vector<Relation> split_cond; - std::vector<CG_result *> split_child; - split_cond.push_back(copy(cond)); - split_child.push_back(first_cg); - split_cond.push_back(Complement(copy(cond))); - split_child.push_back(second_cg); - - return new CG_split(this, active, split_cond, split_child); - } - } - } - } - return new CG_loop(this, active, level, buildAST(level+1, active, true, restriction)); - } -} - - -CG_result *CodeGen::buildAST(int effort) { - if (remap_.size() == 0) - return NULL; - - CG_result *cgr = buildAST(1, ~BoolSet<>(remap_.size()), true, Relation::True(num_level())); - if (cgr == NULL) - return NULL; - - - // break down the complete iteration space condition to levels of bound/guard condtions - cgr = cgr->recompute(cgr->active_, copy(known_), copy(known_)); - - - - if (cgr == NULL) - return NULL; - - // calculate each loop's nesting depth - int depth = cgr->populateDepth(); - - - // redistribute guard condition locations by additional splittings - std::pair<CG_result *, Relation> result = cgr->liftOverhead(min(effort,depth), false); - - // since guard conditions are postponed for non-loop levels, hoist them now. - // this enables proper if-condition simplication when outputting actual code. - result.first->hoistGuard(); - - - - - return result.first; -} - -} diff --git a/omegalib/codegen/src/rose_attributes.cc b/omegalib/codegen/src/rose_attributes.cc deleted file mode 100644 index bb9681c..0000000 --- a/omegalib/codegen/src/rose_attributes.cc +++ /dev/null @@ -1,183 +0,0 @@ -#include <code_gen/rose_attributes.h> - -namespace omega { - -CodeInsertionAttribute* getOrCreateCodeInsertionAttribute(SgNode* node) { - CodeInsertionAttribute* attr; - if(node->attributeExists("code_insertion")) - return static_cast<CodeInsertionAttribute*>(node->getAttribute("code_insertion")); - attr = new CodeInsertionAttribute(); - node->setAttribute("code_insertion", attr); - return attr; -} - -void postProcessRoseCodeInsertion(SgProject* proj) { - //generatePDF(*proj); - CodeInsertionVisitor visitor = CodeInsertionVisitor(); - visitor.initialize(); - visitor.traverseInputFiles(proj); - visitor.insertCode(); -} - -// Swap a code insertion from one node (sn) to another (dn) -// -- note that this function does not currently remove the insertion from the sn node -void moveCodeInsertion(SgNode* sn, CodeInsertion* ci, SgNode* dn) { - CodeInsertionAttribute* new_attr; - // TODO in the near future: replace the above statement with 'new_attr = getOrCreateCodeInsertionAttribute(...)' - CodeInsertionAttribute* old_attr = static_cast<CodeInsertionAttribute*>(sn->getAttribute("code_insertion")); - if(dn->attributeExists("code_insertion")) { - new_attr = static_cast<CodeInsertionAttribute*>(dn->getAttribute("code_insertion")); - } - else { - new_attr = new CodeInsertionAttribute(); - dn->setAttribute("code_insertion", new_attr); - } - new_attr->add(ci); -} - -// A function that copies a specific attribute from one node to another -// this function exists to get around a ROSE limitation that does not -// copy attributes -void copyAttribute(std::string attr_name, SgNode* s, SgNode* d) { - if(s->attributeExists(attr_name)) { - d->setAttribute(attr_name,s->getAttribute(attr_name)); - } -} - -// TODO: find all existng attributes and iterate over them instead of doing them -// individually -void copyAttributes(SgNode* s, SgNode* d) { - copyAttribute("code_insertion", s, d); - //...any other attributes... -} - -void CodeInsertionVisitor::initialize() { - this->loop_level = 0; - this->ci_marks = std::vector<CodeInsertionMark*>(); -} - -void CodeInsertionVisitor::markStmt(SgStatement* stmt, CodeInsertion* ci) { - // this check prevents multiple copies of stmts - // -- may be changed in the future - if(!ci->marked) { - CodeInsertionMark* pos = new CodeInsertionMark(); - pos->stmt = stmt; - pos->ci = ci; - this->ci_marks.push_back(pos); - ci->marked = true; - } -} - -// increase loop_level as the visitor descends -void CodeInsertionVisitor::preOrderVisit(SgNode* n) { - if (isSgForStatement(n)) { - this->loop_level++; - } -} - -void CodeInsertionVisitor::postOrderVisit(SgNode* n) { - if(isSgForStatement(n)) { - this->loop_level--; - } - if(isSgStatement(n)) { - if(n->attributeExists("code_insertion")) { - CodeInsertionAttribute *attr = static_cast<CodeInsertionAttribute*>(n->getAttribute("code_insertion")); - for(CodeInsertionPtrListItr itr = attr->begin(); itr != attr->end(); ++itr) { - CodeInsertion *insertion = *itr; - // check loop level -- if it is equivelent, mark statement for insertion - // -- else, move attribute up to parent - if(insertion->loop_level != this->loop_level) { - moveCodeInsertion(n, insertion, n->get_parent()); - } - else { - this->markStmt(isSgStatement(n), insertion); - } - } - } - } -} - -// final stage of algorithm that inserts marked statements -void CodeInsertionVisitor::insertCode() { - for(std::vector<CodeInsertionMark*>::iterator itr = this->ci_marks.begin(); itr != this->ci_marks.end(); ++itr) { - CodeInsertionMark* mark = *itr; - SgScopeStatement* scope = static_cast<SgScopeStatement*>(mark->stmt->get_parent()); - SageInterface::insertStatementBefore(mark->stmt, mark->ci->getStatement(scope)); - } -} - -SgStatement* PragmaInsertion::getStatement(SgScopeStatement* scopeStmt) { - SgStatement* stmt = SageBuilder::buildPragmaDeclaration(this->name); - return stmt; -} - -//SgStatement* MMPrefetchInsertion::getStatement(SgScopeStatement* scopeStmt) { -// const SgName& name = SgName("_mm_prefetch"); -// SgType* rtype = SageBuilder::buildVoidType(); -// SgExpression* arr_arg = SageBuilder::buildVarRefExp(this->arrName); -// SgExpression* hint_arg = SageBuilder::buildShortVal(this->cacheHint); -// SgExprListExp* args = SageBuilder::buildExprListExp(arr_arg,hint_arg); -// SgStatement* stmt = SageBuilder::buildFunctionCallStmt(name, rtype, args, scopeStmt); -// return stmt; -//} - -SgStatement* MMPrefetchInsertion::getStatement(SgScopeStatement* scopeStmt) { - const SgName fname = SgName("_mm_prefetch"); - SgType* rtype = SageBuilder::buildVoidType(); - SgExpression* arr_arg = this->buildArrArg(scopeStmt); - SgExpression* hint_arg = SageBuilder::buildShortVal(this->cacheHint); - SgExprListExp* args = SageBuilder::buildExprListExp(arr_arg, hint_arg); - return SageBuilder::buildFunctionCallStmt(fname, rtype, args, scopeStmt); -} - -SgExpression* MMPrefetchInsertion::buildArrArg(SgScopeStatement* scopeStmt) { - // if there are no index arguments given, just return a variable reference - if(this->indexCount == 0) { - const SgName aname = SgName(this->arrName); - return SageBuilder::buildVarRefExp(aname, scopeStmt); - } - std::vector<SgExpression*> argList = std::vector<SgExpression*>(); - // foreach dimension - for(int i = 0; i < this->indexCount; i++) { - argList.push_back(this->makeIndexExp(i, scopeStmt)); - } - return SageBuilder::buildExprListExp(argList); -} - -SgExpression* MMPrefetchInsertion::makeIndexExp(int dim, SgScopeStatement* scopeStmt) { - //(i + offset) or (offset) or (i) - std::string* indexer = this->indecies.at(dim); - int offset = this->offsets.at(dim); - if(indexer == NULL) { - return SageBuilder::buildIntVal(offset); - } - else { - const SgName name = SgName(*indexer); - SgVarRefExp* iref = SageBuilder::buildVarRefExp(name, scopeStmt); - if(offset == 0) { - return iref; - } - else { - return SageBuilder::buildAddOp(iref, SageBuilder::buildIntVal(offset)); - } - } -} - -void MMPrefetchInsertion::initialize(const std::string& arrName, int hint) { - this->arrName = std::string(arrName); - this->cacheHint = hint; - this->indecies = std::vector<std::string*>(); - this->offsets = std::vector<int>(); - this->indexCount = 0; -} -void MMPrefetchInsertion::addDim(int offset) { - this->offsets.push_back(offset); - this->indecies.push_back(NULL); - this->indexCount++; -} -void MMPrefetchInsertion::addDim(int offset, const std::string& indexer) { - this->offsets.push_back(offset); - this->indecies.push_back(new std::string(indexer)); - this->indexCount++; -} -} diff --git a/omegalib/doc/calculator.pdf b/omegalib/doc/calculator.pdf Binary files differdeleted file mode 100755 index 5c307ab..0000000 --- a/omegalib/doc/calculator.pdf +++ /dev/null diff --git a/omegalib/doc/interface.pdf b/omegalib/doc/interface.pdf Binary files differdeleted file mode 100755 index 7f918ae..0000000 --- a/omegalib/doc/interface.pdf +++ /dev/null diff --git a/omegalib/omega/CMakeLists.txt b/omegalib/omega/CMakeLists.txt deleted file mode 100644 index 5bc7e0b..0000000 --- a/omegalib/omega/CMakeLists.txt +++ /dev/null @@ -1,69 +0,0 @@ -set(BASIC_SRC - src/basic/ConstString.cc - src/basic/Link.cc - ) - -set(OC_SRC - src/omega_core/oc.cc - src/omega_core/oc_eq.cc - src/omega_core/oc_exp_kill.cc - src/omega_core/oc_global.cc - src/omega_core/oc_print.cc - src/omega_core/oc_problems.cc - src/omega_core/oc_simple.cc - src/omega_core/oc_solve.cc - src/omega_core/oc_query.cc - src/omega_core/oc_quick_kill.cc - src/omega_core/oc_util.cc - ) - -set(PRES_SRC - src/pres_beaut.cc - src/pres_cnstr.cc - src/pres_col.cc - src/pres_conj.cc - src/pres_decl.cc - src/pres_dnf.cc - src/pres_form.cc - src/pres_gen.cc - src/pres_logic.cc - src/pres_print.cc - src/pres_rear.cc - src/pres_quant.cc - src/pres_subs.cc - src/pres_var.cc - ) - -set(REL_SRC - src/evac.cc - src/farkas.cc - src/hull_legacy.cc - src/hull_simple.cc - src/Relation.cc - src/Relations.cc - src/RelBody.cc - src/RelVar.cc - ) - -set(FANCY_SRC - src/closure.cc - src/reach.cc - ) - -include_directories( - include - ) - -add_library(omega - ${BASIC_SRC} - ${OC_SRC} - ${PRES_SRC} - ${REL_SRC} - ${FANCY_SRC} - ) - -install(TARGETS omega - ARCHIVE DESTINATION lib) - -install(DIRECTORY include - DESTINATION .) diff --git a/omegalib/omega/doc/interface.pdf b/omegalib/omega/doc/interface.pdf Binary files differdeleted file mode 100644 index 7f918ae..0000000 --- a/omegalib/omega/doc/interface.pdf +++ /dev/null diff --git a/omegalib/omega/include/basic/Bag.h b/omegalib/omega/include/basic/Bag.h deleted file mode 100644 index a3d07a0..0000000 --- a/omegalib/omega/include/basic/Bag.h +++ /dev/null @@ -1,405 +0,0 @@ -#if ! defined _Bag_h -#define _Bag_h 1 - -#include <stdio.h> -#include <basic/Iterator.h> -#include <basic/Collection.h> -#include <basic/Link.h> -#include <assert.h> - -namespace omega { - -template<class T> class Bag : public Collection<T> { -public: -virtual ~Bag(); - Bag(); - Bag(const Bag<T>&); - Bag & operator=(const Bag<T>&); - //! add elements in b - virtual void operator |= (const Bag<T> & b); - Iterator<T> *new_iterator(); - bool empty() const; - void remove(T); - virtual void insert(T); - void clear(); - virtual bool contains(T) const; - int size() const; - T extract(); -// protected: breaks g++ 261 - List_Element<T>* contents; -}; - - -template<class T> class Ordered_Bag : public Bag<T> { -public: - Ordered_Bag(); - Ordered_Bag(const Ordered_Bag<T>& B) : Bag<T>(B) {} - void insert(T); - //! add elements in b - virtual void operator |= (const Ordered_Bag<T> & b); - //! add elements in b - void operator |= (const Bag<T> & b); - bool contains(T) const; - bool operator == (const Ordered_Bag<T>&) const; - bool operator != (const Ordered_Bag<T>&) const; - bool operator < (const Ordered_Bag<T>&) const; -}; - -template <class T> class Set : public Ordered_Bag <T> { -public: - Set(); - Set(T); - Set(const Set<T>& S) : Ordered_Bag<T>(S) {} - - bool contains (const Set<T>& b) const; - bool contains (T t) const { return Ordered_Bag<T>::contains(t); } - // the above makes "standard" C++ happy - - //! add elements in b - virtual void operator |= (const Set<T> & b); - //! add elements in b - void operator |= (const Ordered_Bag<T> & b); - //! add elements in b - void operator |= (const Bag<T> & b); - - //! delete items also in b - void operator -= (const Set<T> & b); - //! delete items not in b - void operator &= (const Set<T> & b); - //! check for elements in common - bool operator & (const Set<T> &) const; -}; - -} // namespace - -#define instantiate_Bag(T) template class Bag<T>; \ - instantiate_List_Element(T); -#define instantiate_Ordered_Bag(T) template class Ordered_Bag<T>; \ - instantiate_Bag(T) -#define instantiate_Set(T) template class Set<T>; \ - instantiate_Ordered_Bag(T) - - -namespace omega { - -template<class T> Bag<T>::Bag() { - contents = new List_Element <T>; - contents->tail = 0; - } -template<class T> Bag<T>::~Bag() { - delete contents; - } - -template<class T> Ordered_Bag<T>::Ordered_Bag() {} - -template<class T> Set<T>::Set() {} - -template<class T> Bag<T>::Bag(const Bag<T> &L) { - contents = new List_Element<T>(*L.contents); - } - -template<class T> Bag<T> & Bag<T>::operator=(const Bag<T> &L) { - if (this != &L) { - delete contents; - contents = new List_Element<T>(*L.contents); - } - return *this; - } - - - -template<class T> Set<T>::Set(T e) { - assert(this->contents); - this->contents->tail = new List_Element<T>(e, 0); - } - - -/**************************************************************** - * * - * Misc. simple Collection operations * - * * - ****************************************************************/ - -template<class T> bool Bag<T>::empty() const { - return contents->tail == 0; - } - -template<class T> Iterator<T> *Bag<T>::new_iterator() - { - return new List_Element_Iterator<T>(contents->tail); - } - - -template<class T> void Bag<T>::clear() { - if (contents->tail) delete contents->tail; - contents->tail = 0; - } - -template<class T> int Bag<T>::size() const { - int i = 0; - List_Element<T> * p = contents->tail; - while (p) { - p = p->tail; - i++; - }; - return i; - } - - -/**************************************************************** - * * - * Collection/Element operations (e.g. insert, contains) * - * * - ****************************************************************/ - -template<class T> void Bag<T>::remove(T e) { - List_Element<T> * p = contents; - while (p->tail && p->tail->head != e) p = p->tail; - if (p->tail && p->tail->head == e) { - List_Element<T> * q = p->tail; - p->tail = q->tail; - q->tail = 0; - delete q; - } - } - -template<class T> T Bag<T>::extract() { - List_Element<T> * p = contents->tail; - T e = p->head; - contents->tail = p->tail; - p->tail = 0; - delete p; - return e; - } - - -template<class T> void Bag<T>::insert(T e) { - List_Element<T> * q = new List_Element<T>(e,contents->tail); - contents->tail = q; - } - -template<class T> void Ordered_Bag<T>::insert(T e) { - List_Element<T> * p = this->contents; - while (p->tail && p->tail->head < e) p = p->tail; - if (!p->tail || p->tail->head != e) { - List_Element<T> * q = new List_Element<T>(e,p->tail); - p->tail = q; - } - } - - -template<class T> bool Bag<T>::contains(T e) const { - List_Element<T> * p = contents; - while (p->tail && p->tail->head != e) p = p->tail; - return (p->tail && p->tail->head == e); - } - -template<class T> bool Ordered_Bag<T>::contains(T e) const { - List_Element<T> * p = this->contents; - while (p->tail && p->tail->head < e) p = p->tail; - return (p->tail && p->tail->head == e); - } - - -template<class T> bool Set<T>::contains (const Set<T>& b) const { - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents; - do { - /* consume matched elements in p and q */ - p = p->tail; - q = q->tail; - if (!q) return 1; /* no more elements to match */ - if (!p) return 0; /* nothing left in p to match with */ - if (q->head < p->head) { - /* nothing smaller than - p->head left in p, so q->head - can't be matched */ - return 0; - }; - while (p && p->head < q->head) { - /* toss away some elements from p */ - p = p->tail; - } - if (!p || q->head < p->head) return 0; - } while (q); - - return 1; - } - - - -/**************************************************************** - * * - * Collection/Collection operations (e.g. |=) * - * * - ****************************************************************/ - -template<class T> void Bag<T>::operator |= (const Bag<T> & b) { - assert(this != &b); - List_Element<T> * q = b.contents->tail; - - while (q) { - List_Element<T> * r = new List_Element<T>(q->head,contents->tail); - contents->tail = r; - q = q->tail; - } - } - -template<class T> void Ordered_Bag<T>::operator |= (const Ordered_Bag<T> & b) { - if (this == &b) return; - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents->tail; - - while (q) { - while (p->tail && p->tail->head < q->head) p = p->tail; - List_Element<T> * r = new List_Element<T>(q->head,p->tail); - p->tail = r; - q = q->tail; - } - } - -template<class T> void Ordered_Bag<T>::operator |= (const Bag<T> & b) { - Ordered_Bag<T> tmp; - for (List_Element<T> *p = b.contents; p; p=p->tail) { - tmp.insert(p->head); - } - *this |= tmp; -} - -template<class T> void Set<T>::operator |= (const Set<T> & b) { - if (this == &b) return; - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents->tail; - - while (q) { - while (p->tail && p->tail->head < q->head) p = p->tail; - if (!p->tail || p->tail->head != q->head) { - List_Element<T> * r = new List_Element<T>(q->head,p->tail); - p->tail = r; - } - q = q->tail; - } - } - -template<class T> void Set<T>::operator |= (const Ordered_Bag<T> & b) { - Set<T> tmp; - for (List_Element<T> *p = b.contents; p; p=p->tail) { - tmp.insert(p->head); - } - *this |= tmp; -} - -template<class T> void Set<T>::operator |= (const Bag<T> & b) { - Set<T> tmp; - for (List_Element<T> *p = b.contents; p; p=p->tail) { - tmp.insert(p->head); - } - *this |= tmp; -} - - - -// delete items also in b -template<class T> void Set<T>::operator -= (const Set<T> & b) { - if (this == &b) { - this->clear(); - return; - } - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents->tail; - - while (q) { - while (p->tail && p->tail->head < q->head) p = p->tail; - if (p->tail && p->tail->head == q->head) { - List_Element<T> * r = p->tail; - p->tail = r->tail; - r->tail = 0; - delete r; - } - q = q->tail; - } - } - - -// delete items not in b -template<class T> void Set<T>::operator &= (const Set<T> & b) - { - if (this == &b) return; - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents->tail; - - while (q) { - while (p->tail && p->tail->head < q->head) { - List_Element<T> * r = p->tail; - p->tail = r->tail; - r->tail = 0; - delete r; - }; - if (p->tail && p->tail->head == q->head) { - /* allow p->tail->head into the result */ - p = p->tail; - } - /* q->head has matched anything it is going to match */ - q = q->tail; - } - if (p->tail) { - delete p->tail; - p->tail = 0; - }; - - } - - -template<class T> bool Set<T>::operator & (const Set<T>& b) const { - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents; - do { - p = p->tail; - q = q->tail; - while (p && q && p->head != q->head) { - while (p && p->head < q->head) p = p->tail; - while (p && q && q->head < p->head) q = q->tail; - }; - if (p && q && p->head == q->head) return 1; - } while (p && q); - - return 0; - } - - -template<class T> bool Ordered_Bag<T>::operator == (const Ordered_Bag<T>& b) const { - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents; - while (1) { - p = p->tail; - q = q->tail; - if (!p && !q) return 1; - if (!p || !q) return 0; - if (p->head != q->head) return 0; - }; - - } - -template<class T> bool Ordered_Bag<T>::operator != (const Ordered_Bag<T>& b) const { - return !(*this == b); - } - -template<class T> bool Ordered_Bag<T>::operator < (const Ordered_Bag<T>& b) const { - List_Element<T> * p = this->contents; - List_Element<T> * q = b.contents; - while (1) { - p = p->tail; - q = q->tail; - if (!p && !q) return 0; - if (!p) return 1; - if (!q) return 0; - if (p->head < q->head) return 1; - if (q->head < p->head) return 0; - }; - - return 1; - } - -} // namespace - -#endif diff --git a/omegalib/omega/include/basic/BoolSet.h b/omegalib/omega/include/basic/BoolSet.h deleted file mode 100755 index a78af2e..0000000 --- a/omegalib/omega/include/basic/BoolSet.h +++ /dev/null @@ -1,641 +0,0 @@ -/***************************************************************************** - Copyright (C) 2009-2011 Chun Chen - All Rights Reserved. - - Purpose: - BoolSet class, used as a set of integers from 0..n-1 where n is a very - small integer. - - Notes: - Set operands of binary operations can be of different sizes, missing - elements are treated as false. - - History: - 03/30/09 Created by Chun Chen. - 03/26/11 iterator added, -chun -*****************************************************************************/ - -#ifndef _BOOLSET_H -#define _BOOLSET_H - -#include <vector> -#include <iostream> -#include <assert.h> -#include <stdexcept> -#include <iterator> - -namespace omega { - - //! BoolSet class, used as a set of integers from 0 to n-1 where n is a very small integer. -template<typename T = unsigned int> -class BoolSet { -protected: - unsigned int size_; - std::vector<T> set_; - -public: - BoolSet(unsigned int size = 0); - ~BoolSet() {} - - void set(unsigned int); - void unset(unsigned int); - void set_all(); - void unset_all(); - bool get(unsigned int) const; - unsigned int size() const {return size_;} - unsigned int num_elem() const; - bool imply(const BoolSet<T> &) const; - bool empty() const; - void dump() const; - - BoolSet<T> &operator|=(const BoolSet<T> &); - BoolSet<T> &operator&=(const BoolSet<T> &); - BoolSet<T> &operator-=(const BoolSet<T> &); - - //! union - template<typename TT> friend BoolSet<TT> operator|(const BoolSet<TT> &, const BoolSet<TT> &); - //! intersection - template<typename TT> friend BoolSet<TT> operator&(const BoolSet<TT> &, const BoolSet<TT> &); - //! difference - template<typename TT> friend BoolSet<TT> operator-(const BoolSet<TT> &, const BoolSet<TT> &); - //! complement - template<typename TT> friend BoolSet<TT> operator~(const BoolSet<TT> &); - template<typename TT> friend bool operator==(const BoolSet<TT> &, const BoolSet<TT> &); - template<typename TT> friend bool operator!=(const BoolSet<TT> &, const BoolSet<TT> &); - template<typename TT> friend std::ostream& operator<<(std::ostream &, const BoolSet<TT> &); - template<typename TT> friend bool operator<(const BoolSet<TT> &, const BoolSet<TT> &); - -public: - class iterator; - class const_iterator; - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; -}; - - -template<typename T> -BoolSet<T>::BoolSet(unsigned int size) { - assert(size >= 0); - size_ = size; - unsigned int n = size / (sizeof(T)*8); - unsigned int r = size % (sizeof(T)*8); - if (r != 0) - n++; - set_ = std::vector<T>(n, static_cast<T>(0)); -} - - -template<typename T> -void BoolSet<T>::set(unsigned int i) { - assert(i < size_ && i >= 0); - unsigned int n = i / (sizeof(T)*8); - unsigned int r = i % (sizeof(T)*8); - - T t = static_cast<T>(1) << r; - set_[n] |= t; -} - - -template<typename T> -void BoolSet<T>::unset(unsigned int i) { - assert(i < size_ && i >= 0); - unsigned int n = i / (sizeof(T)*8); - unsigned int r = i % (sizeof(T)*8); - - T t = static_cast<T>(1) << r; - t = ~t; - set_[n] &= t; -} - - -template<typename T> -void BoolSet<T>::set_all() { - unsigned int r = size_ % (sizeof(T)*8); - if (r == 0) { - for (unsigned int i = 0; i < set_.size(); i++) - set_[i] = ~static_cast<T>(0); - } - else { - for (unsigned int i = 0; i < set_.size()-1; i++) - set_[i] = ~static_cast<T>(0); - set_[set_.size()-1] = static_cast<T>(0); - T t = static_cast<T>(1); - for (unsigned int i = 0; i < r; i++) { - set_[set_.size()-1] |= t; - t = t<<1; - } - } -} - - -template<typename T> -void BoolSet<T>::unset_all() { - for (unsigned int i = 0; i < set_.size(); i++) - set_[i] = static_cast<T>(0); -} - - -template<typename T> -bool BoolSet<T>::get(unsigned int i) const { - assert(i < size_ && i >= 0); - unsigned int n = i / (sizeof(T)*8); - unsigned int r = i % (sizeof(T)*8); - - T t = static_cast<T>(1) << r; - t = set_[n] & t; - if (t) - return true; - else - return false; -} - - -template<typename T> -unsigned int BoolSet<T>::num_elem() const { - unsigned int n = size_; - unsigned int c = 0; - unsigned int p = 0; - while (n != 0) { - unsigned int m; - if (n >= sizeof(T)*8) { - m = sizeof(T)*8; - n -= sizeof(T)*8; - } - else { - m = n; - n = 0; - } - - T v = set_[p++]; - if (v != static_cast<T>(0)) { - for (unsigned int i = 0; i < m; i++) { - if (v & static_cast<T>(1)) - c++; - v >>= 1; - } - } - } - - return c; -} - - -template<typename T> -bool BoolSet<T>::imply(const BoolSet<T> &b) const { - if (size_ >= b.size_) { - for (unsigned int i = 0; i < b.set_.size(); i++) - if ((set_[i] & b.set_[i]) != b.set_[i]) - return false; - } - else { - for (unsigned int i = 0; i < set_.size(); i++) - if ((set_[i] & b.set_[i]) != b.set_[i]) - return false; - for (unsigned int i = set_.size(); i < b.set_.size(); i++) - if (b.set_[i] != static_cast<T>(0)) - return false; - } - - return true; -} - - -template<typename T> -bool BoolSet<T>::empty() const { - for (int i = 0; i < set_.size(); i++) - if (set_[i] != static_cast<T>(0)) - return false; - - return true; -} - - -template<typename T> -void BoolSet<T>::dump() const { - int j = 1; - for (unsigned int i = 0; i < size(); i++) { - if (get(i)) - std::cout << '1'; - else - std::cout << '0'; - if (j%10 == 0 && i != size() - 1) { - std::cout << ' '; - j = 1; - } - else - j++; - } - std::cout << std::endl; - std::cout.flush(); -} - - -template<typename T> -BoolSet<T> operator|(const BoolSet<T> &a, const BoolSet<T> &b) { - if (a.size_ >= b.size_) { - BoolSet<T> c = a; - for (unsigned int i = 0; i < b.set_.size(); i++) - c.set_[i] |= b.set_[i]; - return c; - } - else { - BoolSet<T> c = b; - for (unsigned int i = 0; i < a.set_.size(); i++) - c.set_[i] |= a.set_[i]; - return c; - } -} - - -template<typename T> -BoolSet<T> operator&(const BoolSet<T> &a, const BoolSet<T> &b) { - if (a.size_ >= b.size_) { - BoolSet<T> c = a; - for (unsigned int i = 0; i < b.set_.size(); i++) - c.set_[i] &= b.set_[i]; - for (unsigned int i = b.set_.size(); i < a.set_.size(); i++) - c.set_[i] = static_cast<T>(0); - return c; - } - else { - BoolSet<T> c = b; - for (unsigned int i = 0; i < a.set_.size(); i++) - c.set_[i] &= a.set_[i]; - for (unsigned int i = a.set_.size(); i < b.set_.size(); i++) - c.set_[i] = static_cast<T>(0); - return c; - } -} - - -template<typename T> -BoolSet<T> operator-(const BoolSet<T> &a, const BoolSet<T> &b) { - BoolSet<T> c(a.size_); - - int sz = a.set_.size(); - if (sz > b.set_.size()) - sz = b.set_.size(); - for (int i = 0; i < sz; i++) - c.set_[i] = a.set_[i] ^ (a.set_[i] & b.set_[i]); - for (int i = sz; i < a.set_.size(); i++) - c.set_[i] = a.set_[i]; - - return c; -} - - -template<typename T> -BoolSet<T> operator~(const BoolSet<T> &b) { - unsigned int r = b.size_ % (sizeof(T)*8); - BoolSet<T> a(b.size_); - for (unsigned int i = 0; i < b.set_.size(); i++) - a.set_[i] = ~b.set_[i]; - - if (r != 0) { - T t = static_cast<T>(1); - for (unsigned int i = 1; i < r; i++) - t = (t << 1) | static_cast<T>(1); - a.set_[a.set_.size()-1] &= t; - } - return a; -} - - -template<typename T> -bool operator==(const BoolSet<T> &a, const BoolSet<T> &b) { - return (a.size_ == b.size_) && (a.set_ == b.set_); -} - - -template<typename T> -bool operator!=(const BoolSet<T> &a, const BoolSet<T> &b) { - return !(a == b); -} - - - -template<typename T> -BoolSet<T> & BoolSet<T>::operator|=(const BoolSet<T> &b) { - *this = *this | b; - return *this; -} - - -template<typename T> -BoolSet<T> & BoolSet<T>::operator&=(const BoolSet<T> &b) { - *this = *this & b; - return *this; -} - - -template<typename T> -BoolSet<T> & BoolSet<T>::operator-=(const BoolSet<T> &b) { - *this = *this - b; - return *this; -} - - -template<typename T> -std::ostream& operator<<(std::ostream &os, const BoolSet<T> &b) { - os << '{'; - for (typename BoolSet<T>::const_iterator i = b.begin(); i != b.end(); i++) { - os << *i; - if (i+1 != b.end()) - os << ','; - } - os << '}'; - - return os; -} - - -template<typename T> -bool operator<(const BoolSet<T> &a, const BoolSet<T> &b) { - unsigned int t1, t2; - t1 = a.num_elem(); - t2 = b.num_elem(); - if (t1 < t2) - return true; - else if (t1 > t2) - return false; - else { - t1 = a.size(); - t2 = b.size(); - if (t1 < t2) - return true; - else if (t1 > t2) - return false; - else - for (unsigned int i = 0; i < a.set_.size(); i++) - if (a.set_[i] < b.set_[i]) - return true; - } - return false; -} - - -// -// iterator for BoolSet -// - -template<typename T> -typename BoolSet<T>::iterator BoolSet<T>::begin() { - typename BoolSet<T>::iterator it(this, 0); - if (size_ == 0) - return it; - else if (set_[0] & static_cast<T>(1)) - return it; - else - return ++it; -} - - -template<typename T> -typename BoolSet<T>::iterator BoolSet<T>::end() { - return typename BoolSet<T>::iterator(this, size_); -} - - -template<typename T> -typename BoolSet<T>::const_iterator BoolSet<T>::begin() const { - typename BoolSet<T>::const_iterator it(this, 0); - if (size_ == 0) - return it; - else if (set_[0] & static_cast<T>(1)) - return it; - else - return ++it; -} - - -template<typename T> -typename BoolSet<T>::const_iterator BoolSet<T>::end() const { - return typename BoolSet<T>::const_iterator(this, size_); -} - - -template<typename T> -class BoolSet<T>::iterator: public std::iterator<std::forward_iterator_tag, T> { -protected: - BoolSet<T> *s_; - unsigned int pos_; - -protected: - iterator(BoolSet<T> *s, unsigned int pos) { s_ = s; pos_ = pos; } - -public: - ~iterator() {} - - typename BoolSet<T>::iterator &operator++(); - typename BoolSet<T>::iterator operator++(int); - typename BoolSet<T>::iterator operator+(int) const; - unsigned int operator*() const; - bool operator==(const BoolSet<T>::iterator &) const; - bool operator!=(const BoolSet<T>::iterator &) const; - operator typename BoolSet<T>::const_iterator(); - - friend class BoolSet<T>; -}; - - -template<typename T> -typename BoolSet<T>::iterator &BoolSet<T>::iterator::operator++() { - assert(pos_ < s_->size_); - - pos_++; - unsigned int n = pos_ / (sizeof(T)*8); - unsigned int r = pos_ % (sizeof(T)*8); - while (pos_ < s_->size_) { - if (s_->set_[n] == static_cast<T>(0)) { - pos_ += sizeof(T)*8-r; - n++; - r = 0; - if (pos_ >= s_->size_) - break; - } - - if (r == 0) { - while (pos_ < s_->size_) { - if (s_->set_[n] == static_cast<T>(0)) { - pos_ += sizeof(T)*8; - n++; - } - else - break; - } - if (pos_ >= s_->size_) - break; - } - - for (unsigned int i = r; i < sizeof(T)*8; i++) - if (s_->set_[n] & static_cast<T>(1) << i) { - pos_ = pos_+i-r; - return *this; - } - - pos_ += sizeof(T)*8-r; - n++; - r = 0; - } - - pos_ = s_->size_; - return *this; -} - - -template<typename T> -typename BoolSet<T>::iterator BoolSet<T>::iterator::operator++(int) { - typename BoolSet<T>::iterator it(*this); - ++(*this); - return it; -} - - -template<typename T> -typename BoolSet<T>::iterator BoolSet<T>::iterator::operator+(int n) const { - assert(n >= 0); - typename BoolSet<T>::iterator it(*this); - while (n > 0) { - ++it; - --n; - } - return it; -} - - -template<typename T> -unsigned int BoolSet<T>::iterator::operator*() const { - assert(pos_ < s_->size_); - return pos_; -} - - -template<typename T> -bool BoolSet<T>::iterator::operator==(const BoolSet<T>::iterator &other) const { - return s_ == other.s_ && pos_ == other.pos_; -} - - -template<typename T> -bool BoolSet<T>::iterator::operator!=(const BoolSet<T>::iterator &other) const { - return !((*this) == other); -} - - -template<typename T> -BoolSet<T>::iterator::operator typename BoolSet<T>::const_iterator() { - return BoolSet<T>::const_iterator(s_, pos_); -} - - -template<typename T> -class BoolSet<T>::const_iterator: public std::iterator<std::forward_iterator_tag, T> { -protected: - const BoolSet<T> *s_; - unsigned int pos_; - -protected: - const_iterator(const BoolSet<T> *s, unsigned int pos) { s_ = s; pos_ = pos; } - -public: - ~const_iterator() {} - - typename BoolSet<T>::const_iterator &operator++(); - typename BoolSet<T>::const_iterator operator++(int); - typename BoolSet<T>::const_iterator operator+(int) const; - unsigned int operator*() const; - bool operator==(const BoolSet<T>::const_iterator &) const; - bool operator!=(const BoolSet<T>::const_iterator &) const; - - friend class BoolSet<T>; -}; - - -template<typename T> -typename BoolSet<T>::const_iterator &BoolSet<T>::const_iterator::operator++() { - assert(pos_ < s_->size_); - - pos_++; - unsigned int n = pos_ / (sizeof(T)*8); - unsigned int r = pos_ % (sizeof(T)*8); - while (pos_ < s_->size_) { - if (s_->set_[n] == static_cast<T>(0)) { - pos_ += sizeof(T)*8-r; - n++; - r = 0; - if (pos_ >= s_->size_) - break; - } - - if (r == 0) { - while (pos_ < s_->size_) { - if (s_->set_[n] == static_cast<T>(0)) { - pos_ += sizeof(T)*8; - n++; - } - else - break; - } - if (pos_ >= s_->size_) - break; - } - - for (unsigned int i = r; i < sizeof(T)*8; i++) - if (s_->set_[n] & static_cast<T>(1) << i) { - pos_ = pos_+i-r; - return *this; - } - - pos_ += sizeof(T)*8-r; - n++; - r = 0; - } - - pos_ = s_->size_; - return *this; -} - - -template<typename T> -typename BoolSet<T>::const_iterator BoolSet<T>::const_iterator::operator++(int) { - typename BoolSet<T>::const_iterator it(*this); - ++(*this); - return it; -} - - -template<typename T> -typename BoolSet<T>::const_iterator BoolSet<T>::const_iterator::operator+(int n) const { - assert(n >= 0); - typename BoolSet<T>::const_iterator it(*this); - while (n > 0) { - ++it; - --n; - } - return it; -} - - -template<typename T> -unsigned int BoolSet<T>::const_iterator::operator*() const { - assert(pos_ < s_->size_); - return pos_; -} - - -template<typename T> -bool BoolSet<T>::const_iterator::operator==(const BoolSet<T>::const_iterator &other) const { - return s_ == other.s_ && pos_ == other.pos_; -} - - -template<typename T> -bool BoolSet<T>::const_iterator::operator!=(const BoolSet<T>::const_iterator &other) const { - return !((*this) == other); -} - -} - -#endif diff --git a/omegalib/omega/include/basic/Collection.h b/omegalib/omega/include/basic/Collection.h deleted file mode 100644 index 80ddf48..0000000 --- a/omegalib/omega/include/basic/Collection.h +++ /dev/null @@ -1,43 +0,0 @@ -#if !defined Already_Included_Collection -#define Already_Included_Collection - -namespace omega { - -template<class T> class Iterator; -template<class T> class Any_Iterator; - - -//! protocol for any kind of collection -template<class T> class Collection { -public: - virtual Iterator<T> *new_iterator() = 0; - virtual Any_Iterator<T> any_iterator() { return Any_Iterator<T>(new_iterator()); } - - virtual int size() const = 0; -}; - - -/*! - * protocol for collections whose elements are ordered - * by the way they are entered into the collection, and - * whose elements can be accessed by "index" - * - * note that the implementation need not be a linked list - */ -template<class T> class Sequence : public Collection<T> { -public: - virtual const T &operator[](int) const = 0; - virtual T &operator[](int) = 0; - - /*! Y in X --> X[X.index(Y)] == Y */ - virtual int index(const T &) const = 0; }; - -} // namespace - -#define instantiate_Collection(T) template class Collection<T>; \ - instantiate_Any_Iterator(T) -#define instantiate_Sequence(T) template class Sequence<T>; \ - instantiate_Collection(T) - -#endif - diff --git a/omegalib/omega/include/basic/Collections.h b/omegalib/omega/include/basic/Collections.h deleted file mode 100644 index 1e68031..0000000 --- a/omegalib/omega/include/basic/Collections.h +++ /dev/null @@ -1,12 +0,0 @@ -#if !defined Already_Included_Collections -#define Already_Included_Collections - -#include <stdio.h> -#include <basic/Collection.h> -#include <basic/Iterator.h> -#include <basic/List.h> -#include <basic/Bag.h> -#include <basic/Map.h> - -#endif - diff --git a/omegalib/omega/include/basic/ConstString.h b/omegalib/omega/include/basic/ConstString.h deleted file mode 100644 index f149c9d..0000000 --- a/omegalib/omega/include/basic/ConstString.h +++ /dev/null @@ -1,57 +0,0 @@ -#if ! defined _Const_String_h -#define _Const_String_h 1 - -#include <string> - -namespace omega { - -// should be inside Const_String, but I can't get it to -// compile the hashTable when it is: hashTable can't be -// global, but if it and its size are static to Const_String, -// the compiler still doesn't seem to like the definition, -// or the declaration either for that matter. -class ConstStringRep { -public: - const char *name; - int count; - ConstStringRep *nextInBucket; - ConstStringRep(const char *t); -}; - -class Const_String { -private: - ConstStringRep *rep; - void buildRep(const char *t); - -public: - Const_String(); - Const_String(const char* t); - Const_String(const std::string &s); - Const_String(const Const_String & t) {rep = t.rep;} - - operator int() const; - int null() const; - - operator const char*() const; - operator std::string() const; - int operator++(int); - int operator++(); - int operator--(int); - int operator--(); - friend int operator==(const Const_String &x, const Const_String &y); - friend int operator!=(const Const_String &x, const Const_String &y); - friend int operator<(const Const_String &x, const Const_String &y); - friend int operator >(const Const_String &x, const Const_String &y); - -}; - -#if defined SCREWED_UP_CASTING_RULES -static int operator==(const Const_String &x, const char *y) -{ return x == (Const_String) y; } -static int operator!=(const Const_String &x, const char *y) -{ return x != (Const_String) y; } -#endif - -} // namespace - -#endif diff --git a/omegalib/omega/include/basic/DynamicArray.h b/omegalib/omega/include/basic/DynamicArray.h deleted file mode 100644 index 08f8b91..0000000 --- a/omegalib/omega/include/basic/DynamicArray.h +++ /dev/null @@ -1,318 +0,0 @@ -#ifndef Already_Included_DynamicArray -#define Already_Included_DynamicArray - -#include <assert.h> - -namespace omega { - -template <class T> class DynamicArray2; -template <class T> class DynamicArray3; -template <class T> class DynamicArray4; - -template <class T, int d> class DynamicArray - { - public: - DynamicArray(DynamicArray<T,d> &D); - ~DynamicArray(); - - protected: - DynamicArray(); - bool partial; - int *bounds; - T *elements; - - void do_constr(); - void do_destruct(); - }; - - -template <class T> class DynamicArray1 : public DynamicArray<T,1> - { - public: - DynamicArray1(const char *s0 = 0); - DynamicArray1(int d0); - void resize(int d0); - T& operator[](int d); - - friend class DynamicArray2<T>; - - private: - void do_construct(int d0); - }; - - -template <class T> class DynamicArray2 : public DynamicArray<T,2> - { - public: - DynamicArray2(const char *s0 = 0, const char *s1 = 0); - DynamicArray2(int d0, int d1); - void resize(int d0, int d1); - DynamicArray1<T> operator[](int d); - - friend class DynamicArray3<T>; - - private: - void do_construct(int d0, int d1); - }; - - -template <class T> class DynamicArray3 : public DynamicArray<T,3> - { - public: - DynamicArray3(const char *s0 = 0, const char *s1 = 0, const char *s2 = 0); - DynamicArray3(int d0, int d1, int d2); - void resize(int d0, int d1, int d2); - DynamicArray2<T> operator[](int d); - - friend class DynamicArray4<T>; - - private: - void do_construct(int d0, int d1, int d2); - }; - -template <class T> class DynamicArray4 : public DynamicArray<T,4> - { - public: - DynamicArray4(const char *s0 = 0, const char *s1 = 0, const char *s2 = 0, const char *s3 = 0); - DynamicArray4(int d0, int d1, int d2, int d3); - void resize(int d0, int d1, int d2, int d3); - DynamicArray3<T> operator[](int d); - - private: - void do_construct(int d0, int d1, int d2, int d3); - }; - -} // namespace - -#define instantiate_DynamicArray1(T) template class DynamicArray1<T>; \ - template class DynamicArray<T,1>; - -#define instantiate_DynamicArray2(T) template class DynamicArray2<T>; \ - template class DynamicArray<T,2>; \ - instantiate_DynamicArray1(T); - -#define instantiate_DynamicArray3(T) template class DynamicArray3<T>; \ - template class DynamicArray<T,3>; \ - instantiate_DynamicArray2(T); - -#define instantiate_DynamicArray4(T) template class DynamicArray4<T>; \ - template class DynamicArray<T,4>; \ - instantiate_DynamicArray3(T); - -namespace omega { - -template<class T, int d> void DynamicArray<T,d>::do_constr() - { -// #if ! defined SHUT_UP_ABOUT_STATEMENT_WITH_NO_EFFECT_IN_DYNAMIC_ARRAY_CREATION -// assert(d > 0); -// #endif - bounds = 0; - elements = 0; - partial = false; - } - - -template<class T> void DynamicArray1<T>::do_construct(int d0) - { - this->bounds = new int[1]; - this->bounds[0] = d0; - this->elements = new T [d0]; - this->partial = false; - } - -template<class T> void DynamicArray2<T>::do_construct(int d0, int d1) - { - this->bounds = new int[2]; - this->bounds[0] = d0; - this->bounds[1] = d1; - this->elements = new T [d0 * d1]; - this->partial = false; - } - -template<class T> void DynamicArray3<T>::do_construct(int d0,int d1,int d2) - { - this->bounds = new int[3]; - this->bounds[0] = d0; - this->bounds[1] = d1; - this->bounds[2] = d2; - this->elements = new T [d0 * d1 * d2]; - this->partial = false; - } - -template<class T> void DynamicArray4<T>::do_construct(int d0,int d1,int d2,int d3) - { - this->bounds = new int[4]; - this->bounds[0] = d0; - this->bounds[1] = d1; - this->bounds[2] = d2; - this->bounds[3] = d3; - this->elements = new T [d0 * d1 * d2 * d3]; - this->partial = false; - } - -template<class T, int d> DynamicArray<T,d>::DynamicArray() - { - do_constr(); - } - -template<class T> DynamicArray1<T>::DynamicArray1(const char *) - { - this->do_constr(); - } - -template<class T> DynamicArray2<T>::DynamicArray2(const char *,const char *) - { - this->do_constr(); - } - -template<class T> DynamicArray3<T>::DynamicArray3(const char *,const char *,const char *) - { - this->do_constr(); - } - -template<class T> DynamicArray4<T>::DynamicArray4(const char *,const char *,const char *,const char *) - { - this->do_constr(); - } - -template<class T> DynamicArray1<T>::DynamicArray1(int d0) - { - do_construct(d0); - } - -template<class T> DynamicArray2<T>::DynamicArray2(int d0, int d1) - { - do_construct(d0, d1); - } - -template<class T> DynamicArray3<T>::DynamicArray3(int d0,int d1,int d2) - { - do_construct(d0, d1, d2); - } - -template<class T> DynamicArray4<T>::DynamicArray4(int d0,int d1,int d2,int d3) - { - do_construct(d0, d1, d2, d3); - } - - -template<class T, int d> void DynamicArray<T,d>::do_destruct() - { - if (! partial) - { - delete [] bounds; - delete [] elements; - } - } - - -template<class T, int d> DynamicArray<T,d>::~DynamicArray() - { - do_destruct(); - } - - -template<class T> void DynamicArray1<T>::resize(int d0) - { - assert(!this->partial); - this->do_destruct(); - if (d0 == 0) - this->do_constr(); - else - do_construct(d0); - } - -template<class T> void DynamicArray2<T>::resize(int d0, int d1) - { - assert(!this->partial); - this->do_destruct(); - if (d0 == 0 && d1 == 0) - this->do_constr(); - else - do_construct(d0, d1); - } - -template<class T> void DynamicArray3<T>::resize(int d0, int d1, int d2) - { - assert(!this->partial); - this->do_destruct(); - if (d0 == 0 && d1 == 0 && d2 == 0) - this->do_constr(); - else - do_construct(d0, d1, d2); - } - -template<class T> void DynamicArray4<T>::resize(int d0, int d1, int d2, int d3) - { - assert(!this->partial); - this->do_destruct(); - if (d0 == 0 && d1 == 0 && d2 == 0 && d3 == 0) - this->do_constr(); - else - do_construct(d0, d1, d2, d3); - } - - -template<class T> T& DynamicArray1<T>::operator[](int d0) - { -#if !defined (NDEBUG) - assert(this->elements != 0 && "Trying to dereference undefined array"); - assert(0 <= d0 && d0 < this->bounds[0] && "Array subscript out of bounds"); -#endif - - return this->elements[d0]; - } - -template<class T> DynamicArray1<T> DynamicArray2<T>::operator[](int d0) - { -#if !defined (NDEBUG) - assert(this->elements != 0 && "Trying to dereference undefined array"); - assert(0 <= d0 && d0 < this->bounds[0] && "Array subscript out of bounds"); -#endif - - DynamicArray1<T> result; - result.bounds = this->bounds+1; - result.elements = this->elements + this->bounds[1] * d0; - result.partial = true; - return result; - } - -template<class T> DynamicArray2<T> DynamicArray3<T>::operator[](int d0) - { -#if !defined (NDEBUG) - assert(this->elements != 0 && "Trying to dereference undefined array"); - assert(0 <= d0 && d0 < this->bounds[0] && "Array subscript out of bounds"); -#endif - DynamicArray2<T> result; - result.bounds = this->bounds+1; - result.elements = this->elements + this->bounds[1] * this->bounds[2] * d0; - result.partial = true; - return result; - } - -template<class T> DynamicArray3<T> DynamicArray4<T>::operator[](int d0) - { -#if !defined (NDEBUG) - assert(this->elements != 0 && "Trying to dereference undefined array"); - assert(0 <= d0 && d0 < this->bounds[0] && "Array subscript out of bounds"); -#endif - - DynamicArray3<T> result; - result.bounds = this->bounds+1; - result.elements = this->elements + this->bounds[1] * this->bounds[2] * this->bounds[3] * d0; - result.partial = true; - return result; - } - - -template<class T, int d> - DynamicArray<T,d>::DynamicArray(DynamicArray<T,d> &D) - { - assert(D.elements != 0 && "Trying to copy an undefined array"); - partial = true; - bounds = D.bounds; - elements = D.elements; - } - -} // namespace -#endif diff --git a/omegalib/omega/include/basic/Iterator.h b/omegalib/omega/include/basic/Iterator.h deleted file mode 100644 index f62874c..0000000 --- a/omegalib/omega/include/basic/Iterator.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Base classes for iterators, generators - * - * These don't really work yet for constant collections. - * I'm not sure how to make that happen. - */ - -#if ! defined _Iterator_h -#define _Iterator_h 1 - -#include <basic/Collection.h> - -namespace omega { - -#define foreach(x,T,S,A) do {for (omega::Any_Iterator<T> __P_##x = (S).any_iterator();__P_##x;__P_##x++) {T & x = *__P_##x; A;}} while (0) - -#define foreachSeparated(x,T,S,A,B) do {for (omega::Any_Iterator<T> __P_##x = (S).any_iterator();__P_##x;) {T & x = *__P_##x; A; __P_##x++; if (__P_##x) B;}} while (0) - -/*! - * \brief Abstract base class Iterator<type> - * - * Supports two styles of iteration: - * ~~~ - * for ( ... initialize i (typically i = collection) ... ; i ; i++ ) - * operate_on(*i) - * ~~~ - * or - * ~~~ - * for ( ... initialize i ... ; i.live() ; i.next() ) - * operate_on(i.curr()) - * ~~~ - * **IF THE COLLECTION IS CHANGED, THE ITERATOR IS NO LONGER VALID** - * - * For collections that are not "Sequence"s, the order in - * which the elements are returned may not be consistent. - */ -template<class T> class Iterator { -public: - virtual const T & operator*() const = 0; - virtual T & operator*() = 0; - - virtual void operator++(int) = 0; - virtual void operator++() = 0; - - virtual bool live() const = 0; - operator bool() const { return live(); } - - const T & curr() const { return *(*this); } - T & curr() { return *(*this); } - void next() { (*this)++; } - - virtual Iterator<T> *new_copy() const = 0; - virtual ~Iterator() {} -}; - - -//! A generator is like an iterator but it gives out values -/*! Values may or may not exist in some writable collection */ -template<class T> class Generator { -public: - virtual T operator*() const = 0; - - virtual void operator++(int) = 0; - virtual void operator++() = 0; - - virtual int live() const = 0; - operator int() const { return live(); } - - const T curr() const { return *(*this); } - T curr() { return *(*this); } - void next() { (*this)++; } -}; - - - -//! Delegate to any kind of iterator (on the heap) -/*! - * * If created via a reference, become a copy of the iterator - * * If created via a pointer, manipulate that pointer and free *p when this dies - * - * Mostly useful for Collection::iterator `Iterator::Iterator(Collection)` - */ -template<class T> class Any_Iterator : public Iterator<T> { -public: - Any_Iterator(Collection<T> &c); - Any_Iterator(const Iterator<T> &i); // copy of i - - virtual ~Any_Iterator() { delete me; } - - Any_Iterator<T> &operator=(const Any_Iterator<T> &rhs) - { delete me; me = rhs.me->new_copy(); return *this; } - - const T & operator*() const { return *(*me); } - T & operator*() { return *(*me); } - void operator++(int) { (*me)++; } - void operator++() { ++(*me); } - bool live() const { return (*me).live(); } - - Iterator<T> *new_copy() const { return new Any_Iterator<T>((*me).new_copy()); } - -private: - //! take over *p, *p MUST BE ON THE HEAP - Any_Iterator(Iterator<T> *p) { me = p; } - friend class Collection<T>; -/* - * // Couldn't make this work with g++258 - * friend Any_Iterator<T> Collection<T>::any_iterator(); - */ - Iterator<T> *me; -}; - -template <class T> inline Any_Iterator<T>::Any_Iterator(Collection<T> &c) - { - me = c.new_iterator(); - } - -template <class T> inline Any_Iterator<T>::Any_Iterator(const Iterator<T> &i) - { - me = i.new_copy(); - } - -} // namespace - -#define instantiate_Iterator(T) template class Iterator<T>; -#define instantiate_Generator(T) template class Generator<T>; -#define instantiate_Any_Iterator(T) template class Any_Iterator<T>; \ - instantiate_Iterator(T) - -#endif diff --git a/omegalib/omega/include/basic/Link.h b/omegalib/omega/include/basic/Link.h deleted file mode 100644 index bdf169c..0000000 --- a/omegalib/omega/include/basic/Link.h +++ /dev/null @@ -1,97 +0,0 @@ -#if ! defined _Link_h -#define _Link_h 1 - -#include <basic/Iterator.h> -#include <stddef.h> - -namespace omega { - -// By default, if ndebug is not set, do not do free list - -#if ! defined ListElementFreeList -#if ! defined NDEBUG || defined ASSERTIONS_ANYWAY -#define ListElementFreeList 0 -#else -#define ListElementFreeList 1 -#endif -#endif - -#if ListElementFreeList - // g++ 2.5.8 does not allow static data in template classes, so... - extern void *kludgy_List_Element_new(size_t size); - extern void kludgy_List_Element_delete(void *ptr, size_t size); -#endif -/*! - * \brief List_Element: one item in a list and the pointer to the next. - * - * Each such object should be pointed to by either exactly one - * other List_Element or by some other pointer(s), exactly one - * of which will delete the List_Element. - * ListElements should ONLY be allocated on the heap. - */ -template <class T> class List_Element { -public: -#if ListElementFreeList - void *operator new(size_t size) - { - return kludgy_List_Element_new(size); - } - void operator delete(void *ptr, size_t size) - { - kludgy_List_Element_delete(ptr, size); - } -#endif - - T head; - List_Element<T> *tail; - - List_Element() { - tail = 0; - } - List_Element(T h, List_Element<T> * t) { - head = h; - tail = t; - } - List_Element(const List_Element<T> & L) { - head = L.head; - if (L.tail) tail = new List_Element<T>(*L.tail); - else tail = 0; - } - List_Element & operator=(const List_Element<T> &L) { - if (this != &L) { - head = L.head; - if (tail) delete tail; - if (L.tail) tail = new List_Element<T>(*L.tail); - else tail = 0; - } - return *this; - } - virtual ~List_Element() { // virtual ensures 2nd arg of delete is right - delete tail; - } -}; - - - -template<class T> class List_Element_Iterator : public Iterator<T> { -public: - List_Element_Iterator(List_Element<T>* j) { i = j; } - virtual const T & operator*() const { return i->head; } - virtual T & operator*() { return i->head; } - virtual void operator++(int) { i = i->tail; } - virtual void operator++() { i = i->tail; } - virtual bool live() const { return i != 0; } - Iterator<T> * new_copy() const { return new List_Element_Iterator<T>(i);} - -protected: - List_Element<T> *i; -}; - -} // namespace - -#define instantiate_Only_List_Element(T) template class List_Element<T>; \ - template class List_Element_Iterator<T>; -#define instantiate_List_Element(T) instantiate_Only_List_Element(T)\ - instantiate_Collection(T) - -#endif diff --git a/omegalib/omega/include/basic/List.h b/omegalib/omega/include/basic/List.h deleted file mode 100644 index 28ab1d5..0000000 --- a/omegalib/omega/include/basic/List.h +++ /dev/null @@ -1,233 +0,0 @@ -#if ! defined _List_h -#define _List_h 1 - -/* - * Linked lists with an interface like a bit of libg++'s SLList class - */ -#include <stdio.h> // for NULL -#include <basic/Iterator.h> -#include <basic/Collection.h> -#include <basic/Link.h> -#include <assert.h> - -namespace omega { - -template<class T> class List_Iterator; - -// -// indexing of Lists starts at 1, index == 0 means not there -// - -template<class T> class List : public Sequence<T> { -public: - List(const List<T> &l) - { contents = l.contents ? new List_Element<T>(*l.contents) : 0; } - List() { contents = 0; } - virtual ~List() { delete contents; } - - Iterator<T> *new_iterator(); - const T &operator[](int) const; - T &operator[](int); - - int index(const T &) const; - - int size() const; - int length() const { return size(); } - bool empty() const { return size() == 0; } - - T &front() const; - -// insertion/deletion on a list invalidates any iterators -// that are on/after the element added/removed - - T remove_front(); - - void prepend(const T &item); - void append(const T &item); - void ins_after(List_Iterator<T> i, const T &item); - - void del_front(); - void del_after(List_Iterator<T> i); - void clear(); - - void join(List<T> &consumed); - -private: - friend class List_Iterator<T>; - List_Element<T> **end() - { - List_Element<T> **e = &contents; - while (*e) - e = &((*e)->tail); - return e; - } - - List_Element<T> *contents; -}; - - -template<class T> class List_Iterator : public List_Element_Iterator<T> { -public: - List_Iterator(List<T> &l); - List_Iterator(const List<T> &l); - List_Iterator(); -private: - List_Element<T> &element() { return *List_Element_Iterator<T>::i; } ; - friend class List<T>; -}; - -} // namespace - -#define instantiate_List(T) template class List<T>; \ - template class List_Iterator<T>; \ - instantiate_Only_List_Element(T) \ - instantiate_Sequence(T) - -namespace omega { - -template<class T> List_Iterator<T>::List_Iterator(List<T> &l) -: List_Element_Iterator<T>(l.contents) {} - -template<class T> List_Iterator<T>::List_Iterator(const List<T> &l) -: List_Element_Iterator<T>(l.contents) {} - -template<class T> List_Iterator<T>::List_Iterator() -: List_Element_Iterator<T>(0) {} - -template<class T> Iterator<T> *List<T>::new_iterator() -{ - return new List_Iterator<T>(*this); -} - -template<class T> const T &List<T>::operator[](int i) const -{ - assert(i > 0 && "Subscript out of bounds"); - List_Iterator<T> p(*this); - - while(--i > 0 && p) - p++; - - if (p) - return *p; - else - return *((T *)0); -} - -template<class T> T &List<T>::operator[](int i) -{ - assert(i > 0 && "Subscript out of bounds"); - List_Iterator<T> p(*this); - - while(--i > 0 && p) - p++; - - if (p) - return *p; - else - return *((T *)0); -} - -template<class T> int List<T>::index(const T &item) const -{ - List_Iterator<T> p(*this); - int i = 1; - - while(p && *p != item) - { - p++; - i++; - } - - if (p) - return i; - else - return 0; -} - -template<class T> int List<T>::size() const - { - int i = 0; - List_Element<T> * p = contents; - while (p) - { - p = p->tail; - i++; - } - return i; - } - -template<class T> T &List<T>::front() const - { - return contents->head; - } - -template<class T> T List<T>::remove_front() - { - List_Element<T> *frunt = contents; - contents = contents->tail; - T fruntT = frunt->head; - frunt->tail = 0; - delete frunt; - return fruntT; - } - -template<class T> void List<T>::prepend(const T &item) - { - contents = new List_Element<T>(item, contents); - } - - -template<class T> void List<T>::append(const T &item) - { - *(end()) = new List_Element<T>(item, 0); - } - -template<class T> void List<T>::ins_after(List_Iterator<T> i, - const T &item) - { -#if ! defined NDEBUG - for (List_Element<T> *e = contents; e != &(i.element()); e=e->tail) - { - assert(e); - } -#endif - i.element().tail = new List_Element<T>(item, i.element().tail); - } - -template<class T> void List<T>::del_front() - { - List_Element<T> *e = contents; - contents = contents->tail; - e->tail = 0; - delete e; - } - -template<class T> void List<T>::del_after(List_Iterator<T> i) - { -#if ! defined NDEBUG - for (List_Element<T> *e0 = contents; e0 != &(i.element()); e0=e0->tail) - { - assert(e0); - } -#endif - List_Element<T> *e = i.element().tail; - i.element().tail = e->tail; - e->tail = 0; - delete e; - } - -template<class T> void List<T>::clear() - { - delete contents; - contents = 0; - } - -template<class T> void List<T>::join(List<T> &consumed) - { - List_Element<T> *e = consumed.contents; - consumed.contents = 0; - *(end()) = e; - } - -} // namespace -#endif diff --git a/omegalib/omega/include/basic/Map.h b/omegalib/omega/include/basic/Map.h deleted file mode 100644 index 25a116d..0000000 --- a/omegalib/omega/include/basic/Map.h +++ /dev/null @@ -1,127 +0,0 @@ -#if ! defined _Map_h -#define _Map_h 1 - -#include <basic/Link.h> -#include <stdio.h> // for NULL - -namespace omega { - -#define foreach_map(k,K,v,V,M,A) {for (omega::MapElementIterator<K,V> __M_##k = (M).iterator();__M_##k;__M_##k++) {K & k = *__M_##k; V & v = __M_##k.value(); A;}} - -template <class K, class V> class MapElement { -public: - K k; - V v; - MapElement<K,V> *tail; - MapElement(const MapElement<K,V>&); - MapElement() {} - MapElement & operator=(const MapElement<K,V>&); - ~MapElement() { delete tail; } -}; - -template<class K, class V> class MapElementIterator { -public: - MapElementIterator(MapElement<K,V>* j) { i = j;} - virtual const K & operator*() const { return i->k; } - virtual K & operator*() { return i->k;} - virtual const V & value() const { return i->v; } - virtual V & value() { return i->v; } - virtual void operator++(int) { i = i->tail; } - virtual void operator++() { i = i->tail; } - virtual bool live() const { return i != NULL; } - operator bool() const { return live(); } -protected: -MapElement<K,V> *i; -}; - -template <class K, class V> class Map { -public: -#if ! defined linux - Map(const V &default_value); -#else - // work around for '386 g++ on Linux - Map(V default_value); -#endif - ~Map(); - MapElementIterator<K,V> iterator() - {return MapElementIterator<K,V>(contents);} - int empty() const {return contents == NULL;} - V operator()(K) const; - V& operator[](K); -private: - MapElement<K,V> * contents; - V _default_value; -}; - -} // namespace - -#define instantiate_Map(T1,T2) template class Map<T1,T2>; \ - template class MapElement<T1,T2>; \ - template class MapElementIterator<T1,T2>; -#define instantiate_MapElement(T1,T2) instantiate_Map(T1,T2) -#define instantiate_MapElementIterator(T1,T2) instantiate_Map(T1,T2) - -namespace omega { - -template<class K, class V> MapElement<K,V>:: MapElement(const MapElement<K,V>& M) { - if (M.tail) tail = new MapElement<K,V>(*M.tail); - else tail = 0; - k = M.k; - v = M.v; - } - -template<class K, class V> MapElement<K,V> & - MapElement<K,V>:: operator=(const MapElement<K,V>& M) { - if (this != &M) { - if (tail) delete tail; - if (M.tail) tail = new MapElement<K,V>(*M.tail); - else tail = 0; - k = M.k; - v = M.v; - } - return *this; - } - - - - -#if ! defined linux -template <class K, class V> Map <K,V>::Map(const V &default_value) -#else -template <class K, class V> Map <K,V>::Map(V default_value) -#endif - : _default_value(default_value) - { - contents = 0; - } - -template <class K, class V> Map <K,V>::~Map() - { - delete contents; - } - -template <class K, class V> V Map<K,V>::operator()(K k) const { - MapElement <K,V> * P = contents; - while (P) { - if (P->k == k) return P->v; - P = P->tail; - }; - return _default_value; - } - -template <class K, class V> V & Map<K,V>::operator[](K k) { - MapElement <K,V> * P = contents; - while (P) { - if (P->k == k) return P->v; - P = P->tail; - }; - P = new MapElement <K,V>; - P->k = k; - P->v = _default_value; - P->tail = contents; - contents = P; - return P->v; - } - -} // namespace -#endif diff --git a/omegalib/omega/include/basic/Section.h b/omegalib/omega/include/basic/Section.h deleted file mode 100644 index 7a4d241..0000000 --- a/omegalib/omega/include/basic/Section.h +++ /dev/null @@ -1,138 +0,0 @@ -#if ! defined _Section_h -#define _Section_h 1 -/* - Section of an existing collection viewed as a collection - */ - -#include <basic/Collection.h> -#include <assert.h> - -namespace omega { - -template<class T> class Section_Iterator; - -template <class T> class Section : public Sequence<T> { -public: - Section(Sequence<T> *, int start, int length); - - Iterator<T> *new_iterator(); - - const T &operator[](int) const; - T &operator[](int); - - int index(const T &) const; - int size() const; - - friend class Section_Iterator<T>; - -private: - Sequence<T> *it; - int _start, _length; -}; - -template <class T> class Section_Iterator : public Iterator<T> { -public: - Section_Iterator(Section<T> &sec); - virtual ~Section_Iterator() { delete it; } - - const T & operator*() const { return *(*it); } - T & operator*() { return *(*it); } - - void operator++(int); - void operator++(); - - bool live() const; - Iterator<T> *new_copy() const; - -private: - Section_Iterator(const Section_Iterator<T> &si); - Iterator<T> *it; - int remaining; -}; - -} // namespace - -#define instantiate_Section(T) template class Section<T>; \ - template class Section_Iterator<T>; \ - instantiate_Sequence(T) -#define instantiate_Section_Iterator(T) instantiate_Section(T) - - -namespace omega { - -template <class T> Section<T>::Section(Sequence<T> *s, int start, int length) - { - assert(s->size() >= start-1 + length); - it = s; - _start = start; - _length = length; - } - -template <class T> Iterator<T> *Section<T>::new_iterator() - { - return new Section_Iterator<T>(*this); - } - -template <class T> const T &Section<T>::operator[](int i) const - { - assert(1 <= i && i <= size()); - return (*it)[i+(_start-1)]; - } - -template <class T> T &Section<T>::operator[](int i) - { - assert(1 <= i && i <= size()); - return (*it)[i+(_start-1)]; - } - -template <class T> int Section<T>::index(const T &var) const - { - int i; - for (i=1; i<=size(); i++) - if ((*this)[i] == var) - return i; - return 0; - } - -template <class T> int Section<T>::size() const - { - return _length; - } - - -template <class T> Section_Iterator<T>::Section_Iterator(Section<T> &sec) - { - it = sec.it->new_iterator(); - for (int i = 1; i < sec._start; i++) - (*it)++; - remaining = sec.size(); - } - - -template <class T> Section_Iterator<T>::Section_Iterator(const Section_Iterator<T> &si) : it(si.it), remaining(si.remaining) {} - - -template <class T> void Section_Iterator<T>::operator++() - { this->operator++(0); } - -template <class T> void Section_Iterator<T>::operator++(int) - { - if (remaining > 0) - { - (*it)++; - remaining--; - } - } - -template <class T> bool Section_Iterator<T>::live() const - { - return (remaining > 0); - } - -template <class T> Iterator<T> *Section_Iterator<T>::new_copy() const - { - return new Section_Iterator<T>(*this); - } - -} // namespace -#endif diff --git a/omegalib/omega/include/basic/SimpleList.h b/omegalib/omega/include/basic/SimpleList.h deleted file mode 100644 index 104390d..0000000 --- a/omegalib/omega/include/basic/SimpleList.h +++ /dev/null @@ -1,194 +0,0 @@ -#if ! defined _Simple_List_h -#define _Simple_List_h 1 - -/* - * Linked lists with an interface like a bit of libg++'s SLSimple_List class - */ - -#include <assert.h> -#include <basic/Iterator.h> -#include <basic/Collection.h> -#include <basic/Link.h> - -namespace omega { - -#define Simple_List Omega_Simple_List -#define Simple_List_Iterator Omega_Simple_List_Iterator - -template<class T> class Simple_List_Iterator; - -// A TEMPORARY HACK - ERROR IF YOU TRY TO USE "INDEX" - FERD - -template<class T> class Simple_List : public Sequence<T> { -public: - Simple_List(const Simple_List<T> &l) - { contents = l.contents ? new List_Element<T>(*l.contents) : 0; } - Simple_List() { contents = 0; } - virtual ~Simple_List() { delete contents; } - - Iterator<T> *new_iterator(); - const T &operator[](int) const; - T &operator[](int); - - - int size() const; - int length() const { return size(); } - int empty() const { return size() == 0; } - - T &front() const; - -// insertion/deletion on a list invalidates any iterators -// that are on/after the element added/removed - - T remove_front(); - - void prepend(const T &item); - void append(const T &item); - - void del_front(); - void clear(); - - void join(Simple_List<T> &consumed); - - int index(const T &) const { - assert(0&&"ILLEGAL SimpleList operation\n"); - return -1; - } - -private: - friend class Simple_List_Iterator<T>; - List_Element<T> **end() - { - List_Element<T> **e = &contents; - while (*e) - e = &((*e)->tail); - return e; - } - - List_Element<T> *contents; -}; - - -template<class T> class Simple_List_Iterator : public List_Element_Iterator<T> { -public: - Simple_List_Iterator(Simple_List<T> &l); - Simple_List_Iterator(const Simple_List<T> &l); - Simple_List_Iterator(); -private: - List_Element<T> &element() { return *this->i; } ; - friend class Simple_List<T>; -}; - -} // namespace - -#define instantiate_Simple_List(T) template class Simple_List<T>; \ - template class Simple_List_Iterator<T>; \ - instantiate_Only_List_Element(T) \ - instantiate_Sequence(T) - -namespace omega { - -template<class T> Simple_List_Iterator<T>::Simple_List_Iterator(Simple_List<T> &l) -: List_Element_Iterator<T>(l.contents) {} - -template<class T> Simple_List_Iterator<T>::Simple_List_Iterator(const Simple_List<T> &l) -: List_Element_Iterator<T>(l.contents) {} - -template<class T> Simple_List_Iterator<T>::Simple_List_Iterator() -: List_Element_Iterator<T>(0) {} - -template<class T> Iterator<T> *Simple_List<T>::new_iterator() -{ - return new Simple_List_Iterator<T>(*this); -} - -template<class T> const T &Simple_List<T>::operator[](int i) const -{ - Simple_List_Iterator<T> p(*this); - - while(--i > 0 && p) - p++; - - if (p) - return *p; - else - return *((T *)0); -} - -template<class T> T &Simple_List<T>::operator[](int i) -{ - Simple_List_Iterator<T> p(*this); - - while(--i > 0 && p) - p++; - - if (p) - return *p; - else - return *((T *)0); -} - - -template<class T> int Simple_List<T>::size() const - { - int i = 0; - List_Element<T> * p = contents; - while (p) - { - p = p->tail; - i++; - } - return i; - } - -template<class T> T &Simple_List<T>::front() const - { - return contents->head; - } - -template<class T> T Simple_List<T>::remove_front() - { - List_Element<T> *frunt = contents; - contents = contents->tail; - T fruntT = frunt->head; - frunt->tail = 0; - delete frunt; - return fruntT; - } - -template<class T> void Simple_List<T>::prepend(const T &item) - { - contents = new List_Element<T>(item, contents); - } - - -template<class T> void Simple_List<T>::append(const T &item) - { - *(end()) = new List_Element<T>(item, 0); - } - - -template<class T> void Simple_List<T>::del_front() - { - List_Element<T> *e = contents; - contents = contents->tail; - e->tail = 0; - delete e; - } - - -template<class T> void Simple_List<T>::clear() - { - delete contents; - contents = 0; - } - -template<class T> void Simple_List<T>::join(Simple_List<T> &consumed) - { - List_Element<T> *e = consumed.contents; - consumed.contents = 0; - *(end()) = e; - } - -} // namespace -#endif diff --git a/omegalib/omega/include/basic/Tuple.h b/omegalib/omega/include/basic/Tuple.h deleted file mode 100644 index e9aae84..0000000 --- a/omegalib/omega/include/basic/Tuple.h +++ /dev/null @@ -1,336 +0,0 @@ -#if !defined _Already_defined_tuple -#define _Already_defined_tuple - -#include <stdio.h> - -#include <basic/Collection.h> -#include <basic/Iterator.h> -#include <basic/util.h> - -namespace omega { - -template<class T> class Tuple_Iterator; - -// TUPLES ARE INDEXED STARTING AT 1 -// index\(i\) == 0 MEANS i IS NOT IN THE TUPLE - -template <class T> class Tuple : public Sequence<T> { -public: - Tuple(); - Tuple(int size); - Tuple (const Tuple<T>& tpl); - virtual ~Tuple(); - Tuple<T>& operator=(const Tuple<T>& tpl); - int size() const { return sz; } - int length() const { return sz; } - bool operator==(const Tuple<T> &b) const; - void reallocate(const int); - void delete_last(); - void append(const Tuple<T> &v); - void append(const T &v); - void join(Tuple<T> &v); - void clear(); - int empty() const; - - Iterator<T> *new_iterator(); - - virtual T &operator[](int index); - virtual const T &operator[](int index) const; - - int index(const T &) const; - - friend class Tuple_Iterator<T>; - -private: - int prealloc_size(const int req_size) - { return max(req_size+prealloc_pad,prealloc_min); } - int realloc_size(const int oldsize) { return 2*oldsize; } - - - int sz, alloc_sz; // Number of elements, size of allocated array - int prealloc_min,prealloc_pad; // These should be static, but that - // causes portability prob. for initialization - -protected: - T * data; -}; - -template <class T> class Tuple_Iterator : public Iterator <T> { -public: - Tuple_Iterator(const Tuple<T> &tpl); - const T & operator*() const; - T & operator*(); - void set_position(const int req_pos); - void operator++(int); - void operator++(); - void operator--(int); - void operator--(); - void set_to_last(); - void set_to_first(); -// void set_position(const int req_pos); Don't do this, compiler bug - bool live() const; - Iterator<T> *new_copy() const; - -private: - Tuple_Iterator(T * cr, T * frst, T *lst, int insz); - T * current, * lastptr, *firstptr; - int sz; -}; - -} // namespace - -#define instantiate_Tuple(T) template class Tuple<T>; \ - template class Tuple_Iterator<T>; \ - instantiate_Sequence(T) - -namespace omega { - -template<class T> T &Tuple<T>::operator[](int index) - { - assert(1 <= index && index <= sz); return data[index-1]; - } - -template<class T> const T &Tuple<T>::operator[](int index) const - { - assert(1 <= index && index <= sz); return data[index-1]; - } - - -template<class T> Tuple<T>::~Tuple() - { - if (data) - delete [] data; - } - -template<class T> Tuple<T>::Tuple() : sz(0), alloc_sz(0), - prealloc_min(20),prealloc_pad(5), data(0) -{ - // nothing needs be done - } - -template<class T> Tuple<T>::Tuple(int size) : sz(size), - prealloc_min(20),prealloc_pad(5) -{ - if (sz > 0) - { - alloc_sz = prealloc_size(sz); - data = new T[alloc_sz]; - assert(alloc_sz >= sz); - //Need some handling for out of memory. - assert (data!=0); - } - else { - alloc_sz = 0; - data = 0; - } -} - - -template<class T> Tuple<T>::Tuple(const Tuple<T>& t) - : sz(t.sz), alloc_sz(t.alloc_sz), prealloc_min(20),prealloc_pad(5) -{ - if (sz > 0) { - data = new T[alloc_sz]; - assert (data!=0); - assert (alloc_sz >= sz); - for (int i=0; i<sz; i++) - data[i] = t.data[i]; - } else { - data = 0; - alloc_sz = 0; // THis might not be 0 if it was a "clear"ed Tuple -// assert(alloc_sz == 0); - } -} - - -template<class T> Tuple<T>& Tuple<T>::operator=(const Tuple<T>& t) -{ - if (this != &t) { // Delete this - if (data) - delete [] data; - sz = t.sz; - alloc_sz = t.alloc_sz; - assert(alloc_sz >= sz); - if (sz > 0) { // Copy old - data = new T[alloc_sz]; - assert (data!=0); - for (int i=0; i<sz; i++) - data[i] = t.data[i]; - } else { - data=0; - alloc_sz = 0; // THis might not be 0 if it was a "clear"ed Tuple -// assert(alloc_sz == 0); - } - } - return *this; -} - - -template<class T> void Tuple<T>::reallocate(const int req_size) -{ - if (alloc_sz >= req_size) { // if (sz >= req_size), does this. - sz = req_size; - return; - } - alloc_sz = prealloc_size(req_size); - T* tmp_data = new T[alloc_sz]; - for(int i=0;i<sz;i++) - tmp_data[i] = data[i]; - delete [] data; - data = tmp_data; - sz = req_size; - assert(alloc_sz >= req_size); -} - -template<class T> void Tuple<T>::delete_last() -{ -assert(sz > 0); -sz --; -} - -template<class T> void Tuple<T>::append(const T &v) -{ - // Check if reallocation is necessary. - if (sz == 0) { // Empty Tuple - assert(alloc_sz >= 0); // May be nonzero for cleared tuple - - if(alloc_sz == 0) { // If it's > 1 no allocation is necessary - alloc_sz = prealloc_size(1); - data = new T[alloc_sz]; - } - assert (alloc_sz > 0 && data != 0); - } else { - if(sz == alloc_sz) { // Requires new allocation - alloc_sz = realloc_size(alloc_sz); - T * data_tmp = new T[alloc_sz]; - assert (data_tmp!=0); - assert (alloc_sz > sz); - for (int i=0; i<sz; i++) - data_tmp[i] = data[i]; - delete [] data; - data=data_tmp; - } // Otherwise big enough, no reallocation necessary - } - // Make assignment - assert(alloc_sz >= sz); - data[sz++] = v; -} - -template<class T> void Tuple<T>::append(const Tuple<T>& t) { - int old_sz = sz; - reallocate(t.size()+size()); - assert(alloc_sz >= sz); - for(int i=0; i<t.sz; i++) - data[i+old_sz] = t.data[i]; -} - -template<class T> void Tuple<T>::join(Tuple<T>& t) { - int old_sz = sz; - reallocate(t.size()+size()); - assert(alloc_sz >= sz); - for(int i=0; i<t.sz; i++) - data[i+old_sz] = t.data[i]; - t.clear(); -} - -template<class T> void Tuple<T>::clear() { if (sz) delete [] data; data = 0; alloc_sz = 0; sz = 0; } - -template<class T> int Tuple<T>::empty() const { return (sz == 0); } - -template<class T> Iterator<T> *Tuple<T>::new_iterator() -{ - return new Tuple_Iterator<T>(*this); -} - -template<class T> int Tuple<T>::index(const T & var) const -/* returns index or 0 if var isn't in the tuple */ -{ - int i; - for (i=0; i<sz; i++) - if (data[i]== var) - return i+1; - return 0; -} - -template<class T> bool Tuple<T>::operator == (const Tuple<T>& b) const -{ - int i; - if (sz != b.size()) return false; - for (i=0; i<sz; i++) - if (!(data[i] == b[i+1])) return false; - return true; -} - -/* class Tuple_Iterator */ - -template<class T> Tuple_Iterator<T>::Tuple_Iterator(const Tuple<T> &tpl) : -current(tpl.data), lastptr(tpl.data+tpl.sz-1), firstptr(tpl.data), sz(tpl.sz) -{ -} - -template<class T> Tuple_Iterator<T>::Tuple_Iterator(T * cr, T *frst, T * lst, - int insz) - : current(cr), lastptr(lst), firstptr(frst), sz(insz) -{ -} - -template<class T> const T & Tuple_Iterator<T>::operator*() const -{ - assert (current<=lastptr && current>=firstptr); - return *current; -} - -template<class T> T & Tuple_Iterator<T>::operator*() -{ - assert (current<=lastptr && current >=firstptr); - return *current; -} - -template<class T> void Tuple_Iterator<T>::operator++(int) -{ - current++; -} - -template<class T> void Tuple_Iterator<T>::operator++() -{ - current++; -} - -template<class T> void Tuple_Iterator<T>::operator--(int) -{ - current--; -} - -template<class T> void Tuple_Iterator<T>::operator--() -{ - current--; -} - -template<class T> void Tuple_Iterator<T>::set_to_last() -{ - current = lastptr; -} - -template<class T> void Tuple_Iterator<T>::set_to_first() -{ - current = firstptr; -} - -template<class T> void Tuple_Iterator<T>::set_position(const int req_pos) -{ - assert(req_pos <= sz && 1 <= req_pos); - current = firstptr + (req_pos - 1); -} - - -template<class T> bool Tuple_Iterator<T>::live() const -{ - return (current !=0 && current<=lastptr && current >= firstptr); -} - -template<class T> Iterator<T> *Tuple_Iterator<T>::new_copy() const { - return new Tuple_Iterator<T>(current, firstptr, lastptr, sz); -} - -} // namespace -#endif diff --git a/omegalib/omega/include/basic/omega_error.h b/omegalib/omega/include/basic/omega_error.h deleted file mode 100644 index e342efb..0000000 --- a/omegalib/omega/include/basic/omega_error.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef OMEGA_ERROR_H -#define OMEGA_ERROR_H - -namespace omega { - -struct presburger_error: public std::runtime_error { - presburger_error(const std::string &msg): std::runtime_error("presburger error: " + msg) {} -}; - - - -} -#endif - diff --git a/omegalib/omega/include/basic/util.h b/omegalib/omega/include/basic/util.h deleted file mode 100644 index 4e807cd..0000000 --- a/omegalib/omega/include/basic/util.h +++ /dev/null @@ -1,263 +0,0 @@ -#if ! defined Already_Included_Util -#define Already_Included_Util - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <string> -#include <sstream> -#include <stdexcept> - -namespace omega { - -#define LONG_LONG_COEF 1 - -#if LONG_LONG_COEF -#if defined BOGUS_LONG_DOUBLE_COEF -typedef long double coef_t; // type of coefficients -#define coef_fmt "%llf" -#define posInfinity (1e+24) -#define negInfinity (-1e+24) -#else -#ifdef WIN32 -typedef _int64 coef_t; // type of coefficients -#else -typedef long long coef_t; -#endif -#define coef_fmt "%lld" -#define posInfinity (0x7ffffffffffffffLL) -#define negInfinity (-0x7ffffffffffffffLL) -#endif -#else -typedef int coef_t; // type of coefficients -#define coef_fmt "%d" -#define posInfinity (0x7ffffff) -#define negInfinity (-0x7ffffff) -#endif - - -template<typename T> inline const T& max(const T &x, const T &y) { - if (x >= y) return x; else return y; -} - - -template<typename T> inline const T& max(const T &x, const T &y, const T &z) { - return max(x, max(y, z)); -} - -template<typename T> inline const T& min(const T &x, const T &y) { - if (x <= y) return x; else return y; -} - -template<typename T> inline const T& min(const T &x, const T &y, const T &z) { - return min(x, min(y, z)); -} - -template<class T> inline void set_max(T &m, const T &x) { - if (m < x) m = x; -} - -template<class T> inline void set_min(T &m, const T &x) { - if (m > x) m = x; -} - -/* template<class T> inline void swap(T &i, T &j) { */ -/* T tmp; */ -/* tmp = i; */ -/* i = j; */ -/* j = tmp; */ -/* } */ - -/* template<class T> inline T copy(const T &t) { return t; } */ - - -/* inline coef_t check_pos_mul(coef_t x, coef_t y) { */ -/* if (y >= 48051280 && y < posInfinity) */ -/* fprintf(stderr, "%d %d\n", x, y); */ -/* /\* #if !defined NDEBUG *\/ */ -/* /\* if (x != 0) *\/ */ -/* /\* assert(((MAXINT)/4) / x > y); *\/ */ -/* /\* #elif defined STILL_CHECK_MULT *\/ */ -/* /\* if (x != 0 && !(((MAXINT)/4) / x > y)) { *\/ */ -/* /\* assert(0&&"Integer overflow during multiplication (util.h)"); *\/ */ -/* /\* } *\/ */ -/* /\* #endif *\/ */ -/* #if !defined NDEBUG */ -/* if (x != 0 && y != 0) */ -/* assert(x*y > 0); */ -/* #elif defined STILL_CHECK_MULT */ -/* if (x != 0 && y != 0 && x*y < 0) */ -/* assert(0&&"Integer overflow during multiplication (util.h)"); */ -/* #endif */ -/* return x * y; */ -/* } */ - - -/* inline int */ -/* check_pos_mul(int x, int y) { */ -/* #if !defined NDEBUG */ -/* if (x != 0) */ -/* assert(((posInfinity)/4) / x > y); */ -/* #elif defined STILL_CHECK_MULT */ -/* if (x != 0 && !(((posInfinity)/4) / x > y)) { */ -/* assert(0&&"Integer overflow during multiplication (util.h)"); */ -/* } */ -/* #endif */ -/* return x * y; */ -/* } */ - -/* inline LONGLONG */ -/* check_pos_mul(LONGLONG x, LONGLONG y) { */ -/* #if !defined NDEBUG */ -/* if (x != 0) */ -/* assert(((posInfinity)/4) / x > y); */ -/* #elif defined STILL_CHECK_MULT */ -/* if (x != 0 && !(((posInfinity)/4) / x > y)) { */ -/* assert(0&&"Integer overflow during multiplication (util.h)"); */ -/* } */ -/* #endif */ -/* return x * y; */ -/* } */ - -/* inline LONGLONG abs(LONGLONG c) { return (c>=0?c:(-c)); } */ - -template<typename T> inline T check_mul(const T &x, const T &y) { -#if defined NDEBUG && ! defined STILL_CHECK_MULT - return x*y; -#else - if (x == 0 || y == 0) - return 0; - - T z = x*y; - int sign_x = (x>0)?1:-1; - int sign_y = (y>0)?1:-1; - int sign_z = (z>0)?1:-1; - - if (sign_x * sign_y != sign_z) - throw std::overflow_error("coefficient multiply overflow"); - - return z; - - /* if (x > 0) { */ - /* if (y > 0) { */ - /* assert(x*y > 0); */ - /* } */ - /* else */ - /* assert(x*y < 0); */ - /* } */ - /* else { */ - /* if (y > 0) */ - /* assert(x*y < 0); */ - /* else */ - /* assert(x*y > 0); */ - /* } */ - /* return x*y; */ -#endif -} - -template<typename T> inline T abs(const T &v) { - return (v >= static_cast<T>(0))?v:-v; -} - -template<class T> inline T int_div(const T &a, const T &b) { - T result; - assert(b > 0); - if (a>0) result = a/b; - else result = -((-a+b-1)/b); - return result; -} - -template<class T> inline T int_mod(const T &a, const T &b) { - return a-b*int_div(a,b); -} - -template<class T> inline T int_mod_hat(const T &a, const T &b) { - T r; - assert(b > 0); - r = a-b*int_div(a,b); - if (r > -(r-b)) r -= b; - return r; -} - -template<typename T> inline T gcd(T b, T a) {/* First argument is non-negative */ - assert(a >= 0); - assert(b >= 0); - if (b == 1) - return (1); - while (b != 0) { - T t = b; - b = a % b; - a = t; - } - return (a); -} - -template<typename T> inline T lcm(T b, T a) { /* First argument is non-negative */ - assert(a >= 0); - assert(b >= 0); - return check_mul(a/gcd(a,b), b); -} - -template<typename T> T square_root(const T &n, T precision = 1) { - T guess = 1; - - while (true) { - T next_guess = 0.5*(guess+n/guess); - if (abs(next_guess-guess) <= precision) - return next_guess; - else - guess = next_guess; - } -} - -template<typename T> T factor(const T &n) { - assert(n >= 0); - if (n == 1) return 1; - - static int prime[30] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113}; - - if (n <= 113*113) { - for (int i = 0; i < 30; i++) - if (n % static_cast<T>(prime[i]) == 0) - return static_cast<T>(prime[i]); - - return n; - } - - T i = 1; - T k = 2; - T x = static_cast<T>(rand())%n; - T y = x; - while(i < square_root<float>(n, 1)) { - i++; - x = (x*x-1) % n; - T d = gcd(abs(y-x), n); - if(d != 1 && d != n) - return factor(d); - if(i == k) { - y = x; - k *= 2; - } - } - return n; -} - -/* #define implies(A,B) (A==(A&B)) */ - -template<typename T> std::string to_string(const T &t) { - std::ostringstream ss; - ss << t; - return ss.str(); -} - -template<typename T> T from_string(const std::string &s) { - std::istringstream ss(s); - ss.exceptions(std::ios::failbit); - T t; - ss >> t; - return t; -} - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega.h b/omegalib/omega/include/omega.h deleted file mode 100644 index 8aa2c08..0000000 --- a/omegalib/omega/include/omega.h +++ /dev/null @@ -1,71 +0,0 @@ -/********************************************************************* - Old license information from the Omega Project, updated one can be - found in LICENSE file. - - Copyright (C) 1994-1996 by the Omega Project - All rights reserved. - - NOTICE: This software is provided ``as is'', without any - warranty, including any implied warranty for merchantability or - fitness for a particular purpose. Under no circumstances shall - the Omega Project or its agents be liable for any use of, misuse - of, or inability to use this software, including incidental and - consequential damages. - - License is hereby given to use, modify, and redistribute this - software, in whole or in part, for any purpose, commercial or - non-commercial, provided that the user agrees to the terms of this - copyright notice, including disclaimer of warranty, and provided - that this copyright notice, including disclaimer of warranty, is - preserved in the source code and documentation of anything derived - from this software. Any redistributor of this software or - anything derived from this software assumes responsibility for - ensuring that any parties to whom such a redistribution is made - are fully aware of the terms of this license and disclaimer. - - The Omega project can be contacted at omega@cs.umd.edu - or http://www.cs.umd.edu/projects/omega -*********************************************************************/ - -#ifndef Already_Included_Omega -#define Already_Included_Omega - -/* - * The presburger interface is divided into the following parts. - * These parts are all included together, but are in separate - * files to keep things organized a bit. - * - * In many files, you can include just some of the following, - * specifically: if you are building a presburger tree, just - * include "pres_tree.h"; if you are querying it, include - * "pres_dnf.d" and "pres_conj.h"; if you are doing relational - * operations, include "Relation.h" - * - * Most of the function definitions are in the .c files with - * the same name as the .h that declares them, except: - * the remap and push_exists functions are in pres_var.c - * the DNFize functions are in pres_dnf.c - * the functions involving printing are in pres_print.c - * the beautify functions are in pres_beaut.c - * the rearrange functions are in pres_rear.c - * the compression functions are in pres_cmpr.c - */ - -#include <omega/omega_core/debugging.h> -#include <omega/pres_var.h> -#include <omega/pres_cnstr.h> -#include <omega/pres_subs.h> -#include <omega/pres_form.h> -#include <omega/pres_logic.h> -#include <omega/pres_decl.h> -#include <omega/pres_quant.h> -#include <omega/pres_conj.h> -#include <omega/pres_cmpr.h> -#include <omega/Relation.h> - -#include <omega/Rel_map.h> -#include <omega/farkas.h> -#include <omega/hull.h> -#include <omega/closure.h> - -#endif diff --git a/omegalib/omega/include/omega/RelBody.h b/omegalib/omega/include/omega/RelBody.h deleted file mode 100644 index 3c11702..0000000 --- a/omegalib/omega/include/omega/RelBody.h +++ /dev/null @@ -1,165 +0,0 @@ -#if ! defined _RelBody_h -#define _RelBody_h 1 - -#include <omega/pres_form.h> -#include <omega/pres_dnf.h> - -namespace omega { - -typedef enum {under_construction, compressed, uncompressed} Rel_Body_Status; -typedef unsigned char Rel_Unknown_Uses; -const Rel_Unknown_Uses no_u = 1; -const Rel_Unknown_Uses and_u = 2; -const Rel_Unknown_Uses or_u = 4; - -// -// Relation body. -// Body and representative are separated to do reference counting. -// - -class Rel_Body : public Formula { -public: - bool is_null() const; - - inline Node_Type node_type() { return Op_Relation; } - - inline bool is_set() const { return number_output == 0; } - int n_inp() const; - int n_out() const; - int n_set() const; - - inline Variable_ID_Tuple *global_decls() { return &Symbolic; } - int max_ufs_arity(); - int max_shared_ufs_arity(); - int max_ufs_arity_of_set(); - int max_ufs_arity_of_in(); - int max_ufs_arity_of_out(); - - Variable_ID input_var(int nth); - Variable_ID output_var(int nth); - Variable_ID set_var(int nth); - Variable_ID get_local(const Variable_ID v); - Variable_ID get_local(const Global_Var_ID G); - Variable_ID get_local(const Global_Var_ID G, Argument_Tuple of); - bool has_local(const Global_Var_ID G); - bool has_local(const Global_Var_ID G, Argument_Tuple of); - void name_input_var(int, Const_String); - void name_output_var(int, Const_String); - void name_set_var(int, Const_String); - - F_And *and_with_and(); - EQ_Handle and_with_EQ(); - EQ_Handle and_with_EQ(const Constraint_Handle &c); - GEQ_Handle and_with_GEQ(); - GEQ_Handle and_with_GEQ(const Constraint_Handle &c); - - void print(); - void print(FILE *output_file) { print(output_file, true); } - void print(FILE *output_file, bool printSym); - std::string print_variables_to_string(bool printSym); - void print_with_subs(FILE *output_file, bool printSym, bool newline); - void print_with_subs(); - std::string print_with_subs_to_string(bool printSym, bool newline); - std::string print_outputs_with_subs_to_string(); - std::string print_outputs_with_subs_to_string(int i); - std::string print_formula_to_string(); - void prefix_print(); - void prefix_print(FILE *output_file, int debug = 1); - - bool is_satisfiable(); - bool is_lower_bound_satisfiable(); - bool is_upper_bound_satisfiable(); - bool is_obvious_tautology(); - bool is_definite_tautology(); - bool is_unknown(); - DNF* query_DNF(); - DNF* query_DNF(int rdt_conjs, int rdt_constrs); - void simplify(int rdt_conjs = 0, int rdt_constrs = 0); - void finalize(); - inline bool is_finalized() { return finalized; } - inline bool is_shared() { return ref_count > 1; } - - void query_difference(Variable_ID v1, Variable_ID v2, - coef_t &lowerBound, coef_t &upperBound, - bool &quaranteed); - void query_variable_bounds(Variable_ID, coef_t &lowerBound, coef_t &upperBound); - coef_t query_variable_mod(Variable_ID v, coef_t factor); - - Relation extract_dnf_by_carried_level(int level, int direction); - void make_level_carried_to(int level); - - // these are only public to allow the creation of "null_rel" - Rel_Body(); - ~Rel_Body(); - void setup_names(); - -private: - - // These are manipulated primarily as parts of Relations - friend class Relation; - friend_rel_ops; - - friend void remap_DNF_vars(Rel_Body *new_rel, Rel_Body *old_rel); - - Rel_Unknown_Uses unknown_uses(); - - inline bool is_simplified() const { return (simplified_DNF!=NULL && get_children().empty()); } - bool is_compressed(); - Conjunct *rm_first_conjunct(); - Conjunct *single_conjunct(); - bool has_single_conjunct(); - - void beautify(); - void rearrange(); - - friend class EQ_Handle; // these set up names for printing - friend class GEQ_Handle; // and check if simplified - friend class Constraint_Handle; // and update coefficients - - void compress(); - void uncompress(); - - void interpret_unknown_as_true(); - void interpret_unknown_as_false(); - - Rel_Body(int n_input, int n_output); - /* Rel_Body(Rel_Body *r); */ - Rel_Body(Rel_Body *r, Conjunct *c); - Rel_Body &operator=(Rel_Body &r); - Rel_Body *clone(); - - inline Formula *formula() { return children().front(); } - inline Formula *rm_formula() { return children().remove_front(); } - bool can_add_child(); - - void reverse_leading_dir_info(); - void invalidate_leading_info(int changed = -1) { Formula::invalidate_leading_info(changed); } - void enforce_leading_info(int guaranteed, int possible, int dir) { Formula::enforce_leading_info(guaranteed, possible, dir); } - // re-declare this so that Relation (a friend) can call it - - DNF* DNFize(); - void DNF_to_formula(); - - Conjunct *find_available_conjunct(); - F_And *find_available_And(); - - -/* === data === */ -private: - - int ref_count; - Rel_Body_Status status; - - int number_input, number_output; - Tuple<Const_String> In_Names, Out_Names; - Variable_ID_Tuple Symbolic; - - DNF* simplified_DNF; - short r_conjs; // are redundant conjuncts eliminated? - bool finalized; - bool _is_set; -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/Rel_map.h b/omegalib/omega/include/omega/Rel_map.h deleted file mode 100644 index 5641cb3..0000000 --- a/omegalib/omega/include/omega/Rel_map.h +++ /dev/null @@ -1,161 +0,0 @@ -#if ! defined _Rel_map_h -#define _Rel_map_h 1 - -#include <omega/pres_gen.h> -#include <omega/pres_var.h> - -namespace omega { - -// -// Mapping for relations -// When a relation operation needs to re-arrange the variables, -// it describes the re-arragement with a mapping, and then calls -// align to re-arrange them. -// -// In a mapping, map_in (map_out/map_set) gives the new type and -// position of each of the old input (output/set) variables. -// For variables being mapped to Input, Output, or Set variables, -// the position is the new position in the tuple. -// For variables being mapped to Exists_Var, Forall_Var, or -// Wildcard_Var, the positions can be used to map multiple -// variables to the same quantified variable, by providing -// the same position. Each variable with a negative position -// is given a unique quantified variable that is NOT listed -// in the seen_exists_ids list. -// I'm not sure what the positions mean for Global_Vars - perhaps -// they are ignored? -// -// Currently, align seems to support only mapping to Set, Input, -// Output, and Exists vars. -// - -class Mapping { -public: - inline Mapping(int no_in, int no_out): n_input(no_in), n_output(no_out) {} - inline Mapping(int no_set): n_input(no_set), n_output(0){} - inline Mapping(const Mapping &m): n_input(m.n_input), n_output(m.n_output) { - int i; - for(i=1; i<=n_input; i++) map_in_kind[i] = m.map_in_kind[i]; - for(i=1; i<=n_input; i++) map_in_pos[i] = m.map_in_pos[i]; - for(i=1; i<=n_output;i++) map_out_kind[i] = m.map_out_kind[i]; - for(i=1; i<=n_output;i++) map_out_pos[i] = m.map_out_pos[i]; - } - - inline void set_map (Var_Kind in_kind, int pos, Var_Kind type, int map) { - if(in_kind==Input_Var) - set_map_in(pos,type,map); - else if(in_kind==Set_Var) - set_map_in(pos,type,map); - else if(in_kind==Output_Var) - set_map_out(pos,type,map); - else - assert(0); - } - - inline void set_map_in (int pos, Var_Kind type, int map) { - assert(pos>=1 && pos<=n_input); - map_in_kind[pos] = type; - map_in_pos[pos] = map; - } - inline void set_map_set (int pos, Var_Kind type, int map) { - assert(pos>=1 && pos<=n_input); - map_in_kind[pos] = type; - map_in_pos[pos] = map; - } - - inline void set_map_out(int pos, Var_Kind type, int map) { - assert(pos>=1 && pos<=n_output); - map_out_kind[pos] = type; - map_out_pos[pos] = map; - } - - inline Var_Kind get_map_in_kind(int pos) const { - assert(pos>=1 && pos<=n_input); - return map_in_kind[pos]; - } - - inline int get_map_in_pos(int pos) const { - assert(pos>=1 && pos<=n_input); - return map_in_pos[pos]; - } - - inline Var_Kind get_map_out_kind(int pos) const { - assert(pos>=1 && pos<=n_output); - return map_out_kind[pos]; - } - - inline int get_map_out_pos(int pos) const { - assert(pos>=1 && pos<=n_output); - return map_out_pos[pos]; - } - - inline int n_in() const { return n_input; } - inline int n_out() const { return n_output; } - - // If a tuple as a whole becomes the new Input or Output tuple, - // return the Tuple of they will become (Input, Output) - // Return Unknown_Tuple otherwise - - inline Argument_Tuple get_tuple_fate(Argument_Tuple t, int prefix = -1) const { - return t== Input_Tuple ? get_input_fate(prefix) : - (t==Output_Tuple ? get_output_fate(prefix) : Unknown_Tuple); } - - inline Argument_Tuple get_set_fate(int prefix = -1) const { - return get_input_fate(prefix); } - - inline Argument_Tuple get_input_fate(int prefix = -1) const { - if (prefix < 0) prefix = n_input; - assert(n_input >= prefix); - if (n_input < prefix) - return Unknown_Tuple; - Var_Kind vf = map_in_kind[1]; - for (int i = 1; i<=prefix; i++) - if (map_in_pos[i]!=i || map_in_kind[i]!=vf) - return Unknown_Tuple; - - return vf == Input_Var ? Input_Tuple - : vf == Set_Var ? Set_Tuple - : vf == Output_Var ? Output_Tuple - : Unknown_Tuple; - } - - inline Argument_Tuple get_output_fate(int prefix = -1) const { - if (prefix < 0) prefix = n_output; - assert(n_output >= prefix); - if (n_output < 1) - return Unknown_Tuple; - Var_Kind vf = map_out_kind[1]; - for (int i = 1; i<=prefix; i++) - if (map_out_pos[i]!=i || map_out_kind[i]!=vf) - return Unknown_Tuple; - return vf == Input_Var ? Input_Tuple - : vf == Set_Var ? Set_Tuple - : vf == Output_Var ? Output_Tuple - : Unknown_Tuple; - } - - inline static Mapping Identity(int inp, int outp) { - Mapping m(inp, outp); int i; - for(i=1; i<=m.n_input; i++) m.set_map(Input_Var, i, Input_Var, i); - for(i=1; i<=m.n_output;i++) m.set_map(Output_Var, i, Output_Var, i); - return m; - } - - inline static Mapping Identity(int setvars) { - Mapping m(setvars); int i; - for(i=1; i<=setvars; i++) m.set_map(Set_Var, i, Set_Var, i); - return m; - } - -private: - int n_input; - int n_output; - Var_Kind map_in_kind[maxVars]; - int map_in_pos[maxVars]; - Var_Kind map_out_kind[maxVars]; - int map_out_pos[maxVars]; -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/Relation.h b/omegalib/omega/include/omega/Relation.h deleted file mode 100644 index b41bef5..0000000 --- a/omegalib/omega/include/omega/Relation.h +++ /dev/null @@ -1,299 +0,0 @@ -#if ! defined _Relation_h -#define _Relation_h 1 - -#include <omega/RelBody.h> -#include <omega/pres_cnstr.h> -#include <iostream> -#include <limits.h> - -namespace omega { - -// -// Relation representative. -// Body and representative are separated to do reference counting. -// -class Relation { -public: - Relation(); - - Relation(int n_input, int n_output = 0); - Relation(const Relation &r); - Relation(const Relation &r, Conjunct *c); - Relation &operator=(const Relation &r); - Relation(Rel_Body &r, int foo); - - static Relation Null(); - static Relation Empty(const Relation &R); - static Relation True(const Relation &R); - static Relation True(int setvars); - static Relation True(int in, int out); - static Relation False(const Relation &R); - static Relation False(int setvars); - static Relation False(int in, int out); - static Relation Unknown(const Relation &R); - static Relation Unknown(int setvars); - static Relation Unknown(int in, int out); - - - bool is_null() const; - - ~Relation(); - - inline F_Forall *add_forall() - { return rel_body->add_forall(); } - inline F_Exists *add_exists() - { return rel_body->add_exists(); } - inline F_And *add_and() - { return rel_body->add_and(); } - inline F_And *and_with() - { return rel_body->and_with(); } - inline F_Or *add_or() - { return rel_body->add_or(); } - inline F_Not *add_not() - { return rel_body->add_not(); } - inline void finalize() - { rel_body->finalize(); } - inline bool is_finalized() const - { return rel_body->finalized; } - inline bool is_set() const - { return rel_body->is_set(); } - inline int n_inp() const - { return rel_body->n_inp(); } - inline int n_out() const - { return rel_body->n_out(); } - inline int n_set() const - { return rel_body->n_set(); } - - inline const Variable_ID_Tuple *global_decls() const - { return rel_body->global_decls(); } - inline int max_ufs_arity() const - { return rel_body->max_ufs_arity(); } - inline int max_ufs_arity_of_in() const - { return rel_body->max_ufs_arity_of_in(); } - inline int max_ufs_arity_of_set() const - { return rel_body->max_ufs_arity_of_set(); } - inline int max_ufs_arity_of_out() const - { return rel_body->max_ufs_arity_of_out(); } - inline int max_shared_ufs_arity() const - { return rel_body->max_shared_ufs_arity(); } - - inline Variable_ID input_var(int nth) - { return rel_body->input_var(nth); } - inline Variable_ID output_var(int nth) - { return rel_body->output_var(nth); } - inline Variable_ID set_var(int nth) - { return rel_body->set_var(nth); } - inline bool has_local(const Global_Var_ID G) - { return rel_body->has_local(G); } - inline bool has_local(const Global_Var_ID G, Argument_Tuple of) - { return rel_body->has_local(G, of); } - inline Variable_ID get_local(const Variable_ID v) - { return split()->get_local(v); } - inline Variable_ID get_local(const Global_Var_ID G) - { return split()->get_local(G); } - inline Variable_ID get_local(const Global_Var_ID G, Argument_Tuple of) - { return split()->get_local(G, of); } - - inline void name_input_var(int nth, Const_String S) - { split()->name_input_var(nth, S); } - inline void name_output_var(int nth, Const_String S) - { split()->name_output_var(nth, S); } - inline void name_set_var(int nth, Const_String S) - { split()->name_set_var(nth, S); } - - - inline F_And *and_with_and() - { return split()->and_with_and(); } - inline EQ_Handle and_with_EQ() - { return split()->and_with_EQ(); } - inline EQ_Handle and_with_EQ(const Constraint_Handle &c) - { return split()->and_with_EQ(c); } - inline GEQ_Handle and_with_GEQ() - { return split()->and_with_GEQ(); } - inline GEQ_Handle and_with_GEQ(const Constraint_Handle &c) - { return split()->and_with_GEQ(c); } - - inline void print() - { rel_body->print(); } - inline void print(FILE *output_file) - { rel_body->print(output_file); } - inline void print_with_subs() - { rel_body->print_with_subs(); } - inline void print_with_subs(FILE *output_file, bool printSym=false, - bool newline=true) - { rel_body->print_with_subs(output_file, printSym, newline); } - inline std::string print_with_subs_to_string(bool printSym=false, - bool newline=true) - { return rel_body->print_with_subs_to_string(printSym, newline); } - inline std::string print_outputs_with_subs_to_string() - { return rel_body->print_outputs_with_subs_to_string(); } - inline std::string print_outputs_with_subs_to_string(int i) - { return rel_body->print_outputs_with_subs_to_string(i); } - inline void prefix_print() - { rel_body->prefix_print(); } - inline void prefix_print(FILE *output_file, int debug = 1) - { rel_body->prefix_print(output_file, debug); } - inline std::string print_formula_to_string() { - return rel_body->print_formula_to_string(); - } - void dimensions(int & ndim_all, int &ndim_domain); - - inline bool is_lower_bound_satisfiable() - { return rel_body->is_lower_bound_satisfiable(); } - inline bool is_upper_bound_satisfiable() - { return rel_body->is_upper_bound_satisfiable(); } - inline bool is_satisfiable() - { return rel_body->is_satisfiable(); } - - inline bool is_tautology() - { return rel_body->is_obvious_tautology(); } // for compatibility - inline bool is_obvious_tautology() - { return rel_body->is_obvious_tautology(); } - inline bool is_definite_tautology() - { return rel_body->is_definite_tautology(); } - - // return x s.t. forall conjuncts c, c has >= x leading 0s - // for set, return -1 (pass this in, in case there are no conjuncts - inline int number_of_conjuncts() - { return rel_body->query_DNF()->length(); } - - // return x s.t. forall conjuncts c, c has >= x leading 0s - // for set, return -1 (pass this in, in case there are no conjuncts - inline int query_guaranteed_leading_0s() - { return rel_body->query_DNF()->query_guaranteed_leading_0s(this->is_set() ? -1 : 0); } - - // return x s.t. forall conjuncts c, c has <= x leading 0s - // if no conjuncts return min of input and output tuple sizes, or -1 if relation is a set - inline int query_possible_leading_0s() - { return rel_body->query_DNF()->query_possible_leading_0s( - this->is_set()? -1 : min(n_inp(),n_out())); } - - // return +-1 according to sign of leading dir, or 0 if we don't know - inline int query_leading_dir() - { return rel_body->query_DNF()->query_leading_dir(); } - - inline DNF* query_DNF() - { return rel_body->query_DNF(); } - inline DNF* query_DNF(int rdt_conjs, int rdt_constrs) - { return rel_body->query_DNF(rdt_conjs, rdt_constrs); } - inline void simplify(int rdt_conjs = 0, int rdt_constrs = 0) - { rel_body->simplify(rdt_conjs, rdt_constrs); } - inline bool is_simplified() - { return rel_body->is_simplified(); } - inline bool is_compressed() const - { return rel_body->is_compressed(); } - inline Conjunct *rm_first_conjunct() - { return rel_body->rm_first_conjunct(); } - inline Conjunct *single_conjunct() - { return rel_body->single_conjunct(); } - inline bool has_single_conjunct() - { return rel_body->has_single_conjunct(); } - - - void query_difference(Variable_ID v1, Variable_ID v2, coef_t &lowerBound, coef_t &upperBound, bool &guaranteed) { - rel_body->query_difference(v1, v2, lowerBound, upperBound, guaranteed); - } - void query_variable_bounds(Variable_ID v, coef_t &lowerBound, coef_t &upperBound) { - rel_body->query_variable_bounds(v,lowerBound,upperBound); - } - coef_t query_variable_mod(Variable_ID v, coef_t factor) { - assert(factor > 0); - return rel_body->query_variable_mod(v, factor); - } - int query_variable_mod(Variable_ID v, int factor) { - assert(sizeof(int) <= sizeof(coef_t)); - coef_t result = rel_body->query_variable_mod(v, static_cast<coef_t>(factor)); - if (result == posInfinity) - return INT_MAX; - else - return static_cast<int>(result); - } - - - inline void make_level_carried_to(int level) - { - split()->make_level_carried_to(level); - } - - inline Relation extract_dnf_by_carried_level(int level, int direction) - { - return split()->extract_dnf_by_carried_level(level, direction); - } - - inline void compress() - { -#if defined(INCLUDE_COMPRESSION) - split()->compress(); -#endif - } - void uncompress() - { rel_body->uncompress(); } - - inline bool is_exact() const - { return !(rel_body->unknown_uses() & (and_u | or_u)) ; } - inline bool is_inexact() const - { return !is_exact(); } - inline bool is_unknown() const - { return rel_body->is_unknown(); } - inline Rel_Unknown_Uses unknown_uses() const - { return rel_body->unknown_uses(); } - - void setup_names() {rel_body->setup_names();} - void copy_names(const Relation &r) { - copy_names(*r.rel_body); - }; - void copy_names(Rel_Body &r); - -private: - // Functions that have to create sets from relations: - friend class Rel_Body; - friend_rel_ops; - - - Rel_Body *split(); - - DNF* simplified_DNF() { - simplify(); - return rel_body->simplified_DNF; - }; - - inline void invalidate_leading_info(int changed = -1) - { split()->invalidate_leading_info(changed); } - inline void enforce_leading_info(int guaranteed, int possible, int dir) - { - split()->enforce_leading_info(guaranteed, possible, dir); - } - - - void makeSet(); - void markAsSet(); - void markAsRelation(); - - friend bool operator==(const Relation &, const Relation &); - - void reverse_leading_dir_info() - { split()->reverse_leading_dir_info(); } - void interpret_unknown_as_true() - { split()->interpret_unknown_as_true(); } - void interpret_unknown_as_false() - { split()->interpret_unknown_as_false(); } - - - Rel_Body *rel_body; - - - friend Relation merge_rels(Tuple<Relation> &R, const Tuple<std::map<Variable_ID, std::pair<Var_Kind, int> > > &mapping, const Tuple<bool> &inverse, Combine_Type ctype, int number_input, int number_output); -}; - -inline std::ostream & operator<<(std::ostream &o, Relation &R) -{ - return o << R.print_with_subs_to_string(); -} - -Relation copy(const Relation &r); - -} // namespace - -#include <omega/Relations.h> - -#endif diff --git a/omegalib/omega/include/omega/Relations.h b/omegalib/omega/include/omega/Relations.h deleted file mode 100644 index 4fd81e6..0000000 --- a/omegalib/omega/include/omega/Relations.h +++ /dev/null @@ -1,88 +0,0 @@ -#if ! defined _Relations_h -#define _Relations_h 1 - -#include <map> -#include <omega/Relation.h> - -namespace omega { - -// UPDATE friend_rel_ops IN pres_gen.h WHEN ADDING TO THIS LIST -// REMEMBER TO TAKE OUT DEFAULT ARGUMENTS IN THAT FILE - -/* The following allows us to avoid warnings about passing - temporaries as non-const references. This is useful but - has suddenly become illegal. */ -Relation consume_and_regurgitate(NOT_CONST Relation &R); - -// -// Operations over relations -// -Relation Union(NOT_CONST Relation &r1, NOT_CONST Relation &r2); -Relation Intersection(NOT_CONST Relation &r1, NOT_CONST Relation &r2); -Relation Extend_Domain(NOT_CONST Relation &R); -Relation Extend_Domain(NOT_CONST Relation &R, int more); -Relation Extend_Range(NOT_CONST Relation &R); -Relation Extend_Range(NOT_CONST Relation &R, int more); -Relation Extend_Set(NOT_CONST Relation &R); -Relation Extend_Set(NOT_CONST Relation &R, int more); -Relation Restrict_Domain(NOT_CONST Relation &r1, NOT_CONST Relation &r2); // Takes set as 2nd -Relation Restrict_Range(NOT_CONST Relation &r1, NOT_CONST Relation &r2); // Takes set as 2nd -Relation Domain(NOT_CONST Relation &r); // Returns set -Relation Range(NOT_CONST Relation &r); // Returns set -Relation Cross_Product(NOT_CONST Relation &A, NOT_CONST Relation &B); // Takes two sets -Relation Inverse(NOT_CONST Relation &r); -Relation After(NOT_CONST Relation &r, int carried_by, int new_output,int dir=1); -Relation Deltas(NOT_CONST Relation &R); // Returns set -Relation Deltas(NOT_CONST Relation &R, int eq_no); // Returns set -Relation DeltasToRelation(NOT_CONST Relation &R, int n_input, int n_output); -Relation Complement(NOT_CONST Relation &r); -Relation Project(NOT_CONST Relation &R, Global_Var_ID v); -Relation Project(NOT_CONST Relation &r, int pos, Var_Kind vkind); -Relation Project(NOT_CONST Relation &S, Variable_ID v); -Relation Project(NOT_CONST Relation &S, Sequence<Variable_ID> &s); -Relation Project_Sym(NOT_CONST Relation &R); -Relation Project_On_Sym(NOT_CONST Relation &R, - NOT_CONST Relation &context = Relation::Null()); -Relation GistSingleConjunct(NOT_CONST Relation &R, NOT_CONST Relation &R2, int effort=0); -Relation Gist(NOT_CONST Relation &R1, NOT_CONST Relation &R2, int effort=0); -Relation Difference(NOT_CONST Relation &r1, NOT_CONST Relation &r2); -Relation Approximate(NOT_CONST Relation &R, bool strides_allowed = false); -Relation Identity(int n_inp); -Relation Identity(NOT_CONST Relation &r); -bool Must_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); -bool Might_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); -// May is the same as might, just another name -bool May_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); -bool Is_Obvious_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); -Relation Composition(NOT_CONST Relation &F, NOT_CONST Relation &G); -bool prepare_relations_for_composition(Relation &F, Relation &G); -Relation Join(NOT_CONST Relation &G, NOT_CONST Relation &F); -Relation EQs_to_GEQs(NOT_CONST Relation &, bool excludeStrides=false); -Relation Symbolic_Solution(NOT_CONST Relation &S); -Relation Symbolic_Solution(NOT_CONST Relation &S, Sequence<Variable_ID> &T); -Relation Sample_Solution(NOT_CONST Relation &S); -Relation Solution(NOT_CONST Relation &S, Sequence<Variable_ID> &T); -Relation Upper_Bound(NOT_CONST Relation &r); -Relation Lower_Bound(NOT_CONST Relation &r); - -Relation merge_rels(Tuple<Relation> &R, const Tuple<std::map<Variable_ID, std::pair<Var_Kind, int> > > &mapping, const Tuple<bool> &inverse, Combine_Type ctype, int number_input = -1, int number_output = -1); - -// The followings might retire in the futrue!!! -void MapRel1(Relation &inputRel, - const Mapping &map, - Combine_Type ctype, - int number_input=-1, int number_output=-1, - bool invalidate_resulting_leading_info = true, - bool finalize = true); -Relation MapAndCombineRel2(Relation &R1, Relation &R2, - const Mapping &mapping1, const Mapping &mapping2, - Combine_Type ctype, - int number_input=-1, int number_output=-1); -void align(Rel_Body *originalr, Rel_Body *newr, F_Exists *fe, - Formula *f, const Mapping &mapping, bool &newrIsSet, - List<int> &seen_exists, - Variable_ID_Tuple &seen_exists_ids); - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/closure.h b/omegalib/omega/include/omega/closure.h deleted file mode 100644 index 67088dd..0000000 --- a/omegalib/omega/include/omega/closure.h +++ /dev/null @@ -1,31 +0,0 @@ -#if ! defined _closure_h -#define _closure_h - -#include <omega/Relation.h> - -namespace omega { - -Relation VennDiagramForm( - Tuple<Relation> &Rs, - NOT_CONST Relation &Context_In); -Relation VennDiagramForm( - NOT_CONST Relation &R_In, - NOT_CONST Relation &Context_In = Relation::Null()); - -// Given a Relation R, returns a relation deltas -// that correspond to the ConicHull of the detlas of R -Relation ConicClosure (NOT_CONST Relation &R); - -Relation TransitiveClosure (NOT_CONST Relation &r, - int maxExpansion = 1, - NOT_CONST Relation &IterationSpace=Relation::Null()); - -/* Tomasz Klimek */ -Relation calculateTransitiveClosure(NOT_CONST Relation &r); - -/* Tomasz Klimek */ -Relation ApproxClosure(NOT_CONST Relation &r); - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/evac.h b/omegalib/omega/include/omega/evac.h deleted file mode 100644 index a561f8c..0000000 --- a/omegalib/omega/include/omega/evac.h +++ /dev/null @@ -1,15 +0,0 @@ -#if defined STUDY_EVACUATIONS - -namespace omega { - -// study the evacuation from one side of C to the other for UFS's of -// arity up to max_arity -extern void study_evacuation(Conjunct *C, which_way dir, int max_arity); - -// study the evacuation from the joined C2's output and C1's input to -// either of the other possible tuples -extern void study_evacuation(Conjunct *C1, Conjunct *C2, int max_arity); - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/farkas.h b/omegalib/omega/include/omega/farkas.h deleted file mode 100644 index e77ed66..0000000 --- a/omegalib/omega/include/omega/farkas.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef Already_Included_Affine_Closure -#define Already_Included_Affine_Closure - -#include <omega/Relation.h> - -namespace omega { - -enum Farkas_Type {Basic_Farkas, Decoupled_Farkas, - Linear_Combination_Farkas, Positive_Combination_Farkas, - Affine_Combination_Farkas, Convex_Combination_Farkas }; - -Relation Farkas(NOT_CONST Relation &R, Farkas_Type op, bool early_bailout = false); - -extern coef_t farkasDifficulty; -extern Global_Var_ID coefficient_of_constant_term; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/hull.h b/omegalib/omega/include/omega/hull.h deleted file mode 100644 index 928d0c6..0000000 --- a/omegalib/omega/include/omega/hull.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef Already_Included_Hull -#define Already_Included_Hull - -#include <omega/farkas.h> - -namespace omega { - -Relation SimpleHull(const Relation &R, bool allow_stride_constraint = false, bool allow_irregular_constraint = false); -Relation SimpleHull(const std::vector<Relation> &Rs, bool allow_stride_constraint = false, bool allow_irregular_constraint = false); - - -// All of the following first call approximate on R to -// eliminate any wildcards and strides. - -// x in Convex Hull of R -// iff -// exist a_i, y_i s.t. -// x = Sum_i a_i y_i s.t. -// forall i, y_i in R -// forall i, a_i >=0 -// sum_i a_i = 1 -Relation ConvexHull(NOT_CONST Relation &R); - -// DecoupledConvexHull is the same as ConvexHull, -// except that it only finds constraints that involve -// both variables x&y if there is a constraint -// that involves both x&y in one of the conjuncts -// of R. -Relation DecoupledConvexHull(NOT_CONST Relation &R); - -// The affine hull just consists of equality constraints -// but is otherwise the tightest hull on R. -// x in Affine Hull of R -// iff -// exist a_i, y_i s.t. -// x = Sum_i a_i y_i s.t. -// forall i, y_i in R -// sum_i a_i = 1 -Relation AffineHull(NOT_CONST Relation &R); - -// x in Linear Hull of R -// iff -// exist a_i, y_i s.t. -// x = Sum_i a_i y_i s.t. -// forall i, y_i in R -Relation LinearHull(NOT_CONST Relation &R); - -// The conic hull is the tighest cone that contains R -// x in Conic Hull of R. -// iff -// exist a_i, y_i s.t. -// x = Sum_i a_i y_i s.t. -// forall i, y_i in R -// forall i, a_i >=0 -Relation ConicHull(NOT_CONST Relation &R); - -// RectHull includes readily-available constraints from relation -// that can be part of hull, plus rectangular bounds calculated -// from input/output/set variables' range. -Relation RectHull(NOT_CONST Relation &Rel); - -// A constraint is in the result of QuickHull only if it appears in one of -// the relations and is directly implied by a single constraint in each of -// the other relations. -Relation QuickHull(Relation &R); // deprecated -Relation QuickHull(Tuple<Relation> &Rs); // deprecated - -Relation FastTightHull(NOT_CONST Relation &input_R, - NOT_CONST Relation &input_H); -Relation Hull(NOT_CONST Relation &R, - bool stridesAllowed = false, - int effort=1, - NOT_CONST Relation &knownHull = Relation::Null() - ); -Relation Hull(Tuple<Relation> &Rs, - const std::vector<bool> &validMask, - int effort = 1, - bool stridesAllowed = false, - NOT_CONST Relation &knownHull = Relation::Null()); - -// If a union of several conjuncts is a convex, their union -// representaition can be simplified by their convex hull. -Relation ConvexRepresentation(NOT_CONST Relation &R); -Relation CheckForConvexPairs(NOT_CONST Relation &S); // deprecated -Relation CheckForConvexRepresentation(NOT_CONST Relation &R_In); // deprecated - -} - -#endif diff --git a/omegalib/omega/include/omega/omega_core/debugging.h b/omegalib/omega/include/omega/omega_core/debugging.h deleted file mode 100644 index e217ae9..0000000 --- a/omegalib/omega/include/omega/omega_core/debugging.h +++ /dev/null @@ -1,30 +0,0 @@ -#if !defined(Already_included_debugging) -#define Already_included_debugging - -// Debugging flags. Can set any of these. - -#include <stdio.h> -#include <ctype.h> - -namespace omega { - - - -extern int omega_core_debug; -extern int pres_debug; -extern int relation_debug; -extern int closure_presburger_debug; -extern int hull_debug; -extern int farkas_debug; -extern int code_gen_debug; - -enum negation_control { any_negation, one_geq_or_eq, one_geq_or_stride }; -extern negation_control pres_legal_negations; - -#if defined STUDY_EVACUATIONS -extern int evac_debug; -#endif - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/omega_core/oc.h b/omegalib/omega/include/omega/omega_core/oc.h deleted file mode 100644 index e4f5444..0000000 --- a/omegalib/omega/include/omega/omega_core/oc.h +++ /dev/null @@ -1,350 +0,0 @@ -#ifndef Already_Included_OC -#define Already_Included_OC 1 - -#include <stdio.h> -#include <string> -#include <basic/util.h> -#include <omega/omega_core/debugging.h> -#include <basic/Tuple.h> - -namespace omega { - -// Manu:: commented the line below -- fortran bug workaround -//#define maxVars 256 /* original 56, increased by chun */ -#define maxVars 100 - -extern int maxGEQs; -extern int maxEQs; - -// Manu:: commented the lines below -- fortran bug workaround -//const int maxmaxGEQs = 2048; // original 512, increaded by chun -//const int maxmaxEQs = 512; // original 256, increased by chun -const int maxmaxGEQs = 512; -const int maxmaxEQs = 256; - -/* #if ! defined maxmaxGEQs */ -/* #define maxmaxGEQs 2048 /\* original 512, increaded by chun *\/ */ -/* #endif */ -/* #if ! defined maxmaxEQs */ -/* #define maxmaxEQs 512 /\* original 256, increased by chun *\/ */ -/* #endif */ - - -#if 0 -#if ! defined Already_Included_Portable -typedef unsigned char bool; /* what a gross thing to do */ -#endif -#endif - -typedef int EqnKey; - -enum {EQ_BLACK = 0, EQ_RED = 1}; -enum {OC_SOLVE_UNKNOWN = 2, OC_SOLVE_SIMPLIFY = 3}; - -struct eqn { - EqnKey key; - coef_t touched; // see oc_simple.c - int color; - int essential; - int varCount; - coef_t coef[maxVars + 1]; -}; - -// typedef eqn * Eqn; -enum redType {notRed=0, redEQ, redGEQ, redLEQ, redStride}; -enum redCheck {noRed=0, redFalse, redConstraints}; -enum normalizeReturnType {normalize_false, normalize_uncoupled, - normalize_coupled}; - -extern char wildName[200][20]; - -extern FILE *outputFile; /* printProblem writes its output to this file */ -#define doTrace (trace && TRACE) -#define isRed(e) (desiredResult == OC_SOLVE_SIMPLIFY && (e)->color) -// #define eqnncpy(e1,e2,s) {int *p00,*q00,*r00; p00 = (int *)(e1); q00 = (int *)(e2); r00 = &p00[headerWords+1+s]; while(p00 < r00) *p00++ = *q00++; } -// #define eqncpy(e1,e2) eqnncpy(e1,e2,nVars) -// #define eqnnzero(e,s) {int *p00,*r00; p00 = (int *)(e); r00 = &p00[headerWords+1+(s)]; while(p00 < r00) *p00++ = 0;} -// #define eqnzero(e) eqnnzero(e,nVars) - -//void eqnncpy(eqn *dest, eqn *src, int); -//void eqnnzero(eqn *e, int); - -inline void eqnncpy(eqn *dest, eqn *src, int nVars) { - dest->key = src->key; - dest->touched = src->touched; - dest->color = src->color; - dest->essential = src->essential; - dest->varCount = src->varCount; - for (int i = 0; i <= nVars; i++) - dest->coef[i] = src->coef[i]; -} - - -inline void eqnnzero(eqn *e, int nVars) { - e->key = 0; - e->touched = 0; - e->color = EQ_BLACK; - e->essential = 0; - e->varCount = 0; - for (int i = 0; i <= nVars; i++) - e->coef[i] = 0; -} - -extern int mayBeRed; - -#ifdef SPEED -#define TRACE 0 -#define DBUG 0 -#define DEBUG 0 -#else -#define TRACE (omega_core_debug) -#define DBUG (omega_core_debug > 1) -#define DEBUG (omega_core_debug > 2) -#endif - - -class Memory { -public: - int length; - coef_t stride; - redType kind; - coef_t constantTerm; - coef_t coef[maxVars + 1]; - int var[maxVars + 1]; -}; - -/* #define headerWords ((4*sizeof(int) + sizeof(coef_t))/sizeof(int)) */ - -void check_number_EQs(int); -void check_number_GEQs(int); -extern eqn SUBs[]; -extern Memory redMemory[]; - -class Problem { -public: - short nVars, safeVars; - short nEQs, nGEQs,nSUBs,nMemories,allocEQs,allocGEQs; - short varsOfInterest; - bool variablesInitialized; - bool variablesFreed; - short var[maxVars+2]; - short forwardingAddress[maxVars+2]; - // int variableColor[maxVars+2]; - int hashVersion; - const char *(*get_var_name)(unsigned int var, void *args); - void *getVarNameArgs; - eqn *GEQs; - eqn *EQs; - bool isTemporary; - - Problem(int in_eqs=0, int in_geqs=0); - Problem(const Problem &); - ~Problem(); - Problem & operator=(const Problem &); - -/* Allocation parameters and functions */ - - static const int min_alloc,first_alloc_pad; - int padEQs(int oldalloc, int newreq) { - check_number_EQs(newreq); - return min((newreq < 2*oldalloc ? 2*oldalloc : 2*newreq),maxmaxEQs); - } - int padGEQs(int oldalloc, int newreq) { - check_number_GEQs(newreq); - return min((newreq < 2*oldalloc ? 2*oldalloc : 2*newreq),maxmaxGEQs); - } - int padEQs(int newreq) { - check_number_EQs(newreq); - return min(max(newreq+first_alloc_pad,min_alloc), maxmaxEQs); - } - int padGEQs(int newreq) { - check_number_GEQs(newreq); - return min(max(newreq+first_alloc_pad,min_alloc), maxmaxGEQs); - } - - - void zeroVariable(int i); - - void putVariablesInStandardOrder(); - void noteEssential(int onlyWildcards); - int findDifference(int e, int &v1, int &v2); - int chainKill(int color,int onlyWildcards); - - int newGEQ(); - int newEQ(); - int newSUB(){ - return nSUBs++; - } - - - void initializeProblem(); - void initializeVariables() const; - void printProblem(int debug = 1) const; - void printSub(int v) const; - std::string print_sub_to_string(int v) const; - void clearSubs(); - void printRedEquations() const; - int countRedEquations() const; - int countRedGEQs() const; - int countRedEQs() const; - int countRedSUBs() const; - void difficulty(int &numberNZs, coef_t &maxMinAbsCoef, coef_t &sumMinAbsCoef) const; - int prettyPrintProblem() const; - std::string prettyPrintProblemToString() const; - int prettyPrintRedEquations() const; - int simplifyProblem(int verify, int subs, int redundantElimination); - int simplifyProblem(); - int simplifyAndVerifyProblem(); - int simplifyApproximate(bool strides_allowed); - void coalesce(); - void partialElimination(); - void unprotectVariable(int var); - void negateGEQ(int); - void convertEQstoGEQs(bool excludeStrides); - void convertEQtoGEQs(int eq); - void nameWildcard(int i); - void useWildNames(); - void ordered_elimination(int symbolic); - int eliminateRedundant (bool expensive); - void eliminateRed(bool expensive); - void constrainVariableSign(int color, int var, int sign); - void constrainVariableValue(int color, int var, int value); - void query_difference(int v1, int v2, coef_t &lowerBound, coef_t &upperBound, bool &guaranteed); - int solve(int desiredResult); - std::string print_term_to_string(const eqn *e, int c) const; - void printTerm(const eqn * e, int c) const; - std::string printEqnToString(const eqn * e, int test, int extra) const; - void sprintEqn(char *str, const eqn * e, int is_geq,int extra) const; - void printEqn(const eqn * e, int is_geq, int extra) const; - void printEQ(const eqn *e) const {printEqn(e,0,0); } - std::string print_EQ_to_string(const eqn *e) const {return printEqnToString(e,0,0);} - std::string print_GEQ_to_string(const eqn *e) const {return printEqnToString(e,1,0);} - void printGEQ(const eqn *e) const {printEqn(e,1,0); } - void printGEQextra(const eqn *e) const {printEqn(e,1,1); } - void printSubstitution(int s) const; - void printVars(int debug = 1) const; - void swapVars(int i, int j); - void reverseProtectedVariables(); - redCheck redSimplifyProblem(int effort, int computeGist); - - // calculate value of variable mod integer from set of equations -- by chun 12/14/2006 - coef_t query_variable_mod(int v, coef_t factor, int color=EQ_BLACK, int nModularEQs=0, int nModularVars=0) const; - coef_t query_variable_mod(int v, coef_t factor, int color, int nModularEQs, int nModularVars, Tuple<bool> &working_on) const; // helper function - - int queryVariable(int i, coef_t *lowerBound, coef_t *upperBound); - int query_variable_bounds(int i, coef_t *l, coef_t *u); - void queryCoupledVariable(int i, coef_t *l, coef_t *u, int *couldBeZero, coef_t lowerBound, coef_t upperBound); - int queryVariableSigns(int i, int dd_lt, int dd_eq, int dd_gt, coef_t lowerBound, coef_t upperBound, bool *distKnown, coef_t *dist); - void addingEqualityConstraint(int e); - normalizeReturnType normalize(); - void normalize_ext(); - void cleanoutWildcards(); - void substitute(eqn *sub, int i, coef_t c); - void deleteVariable( int i); - void deleteBlack(); - int addNewProtectedWildcard(); - int addNewUnprotectedWildcard(); - int protectWildcard( int i); - void doMod( coef_t factor, int e, int j); - void freeEliminations( int fv); - int verifyProblem(); - void resurrectSubs(); - int solveEQ(); - int combineToTighten() ; - int quickKill(int onlyWildcards, bool desperate = false); - int expensiveEqualityCheck(); - int expensiveRedKill(); - int expensiveKill(); - int smoothWeirdEquations(); - void quickRedKill(int computeGist); - void chainUnprotect(); - void freeRedEliminations(); - void doElimination( int e, int i); - void analyzeElimination( - int &v, - int &darkConstraints, - int &darkShadowFeasible, - int &unit, - coef_t ¶llelSplinters, - coef_t &disjointSplinters, - coef_t &lbSplinters, - coef_t &ubSplinters, - int ¶llelLB); - int parallelSplinter(int e, int diff, int desiredResult); - int solveGEQ( int desiredResult); - void setInternals(); - void setExternals(); - int reduceProblem(); - void problem_merge(Problem &); - void deleteRed(); - void turnRedBlack(); - void checkGistInvariant() const; - void check() const; - coef_t checkSum() const; - void rememberRedConstraint(eqn *e, redType type, coef_t stride); - void recallRedMemories(); - void simplifyStrideConstraints(); - const char * orgVariable(int i) const { - return ((i == 0) ? // cfront likes this form better - "1" : - ((i < 0) ? - wildName[-i] : - (*get_var_name)(i,getVarNameArgs))); - }; - const char * variable(int i) const { - return orgVariable(var[i]) ; - }; - - void deleteGEQ(int e) { - if (DEBUG) { - fprintf(outputFile,"Deleting %d (last:%d): ",e,nGEQs-1); - printGEQ(&GEQs[e]); - fprintf(outputFile,"\n"); - }; - if (e < nGEQs-1) - eqnncpy (&GEQs[e], &GEQs[nGEQs - 1],(nVars)); - nGEQs--; - }; - void deleteEQ(int e) { - if (DEBUG) { - fprintf(outputFile,"Deleting %d (last:%d): ",e,nEQs-1); - printGEQ(&EQs[e]); - fprintf(outputFile,"\n"); - }; - if (e < nEQs-1) - eqnncpy (&EQs[e], &EQs[nEQs - 1],(nVars)); - nEQs--; - }; - -}; - - - -/* #define UNKNOWN 2 */ -/* #define SIMPLIFY 3 */ -/* #define _red 1 */ -/* #define black 0 */ - - -extern int print_in_code_gen_style; - - -void initializeOmega(void); - - -/* set extra to 0 for normal use */ -int singleVarGEQ(eqn *e); - -void setPrintLevel(int level); - -void printHeader(); - -void setOutputFile(FILE *file); - -extern void check_number_EQs(int nEQs); -extern void check_number_GEQs(int nGEQs); -extern void checkVars(int nVars); - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/omega_core/oc_i.h b/omegalib/omega/include/omega/omega_core/oc_i.h deleted file mode 100644 index 9533a40..0000000 --- a/omegalib/omega/include/omega/omega_core/oc_i.h +++ /dev/null @@ -1,79 +0,0 @@ -#if !defined(Already_included_oc_i) -#define Already_included_oc_i - -#include <basic/util.h> -#include <omega/omega_core/oc.h> -#include <stdlib.h> -#include <assert.h> -#include <string> -#include <vector> - -namespace omega { - -#define maxWildcards 18 - -extern int findingImplicitEqualities; -extern int firstCheckForRedundantEquations; -extern int use_ugly_names; -extern int doItAgain; -extern int newVar; -extern int conservative; -extern FILE *outputFile; /* printProblem writes its output to this file */ -extern int nextWildcard; -extern int trace; -extern int depth; -extern int packing[maxVars]; -extern int headerLevel; -extern int inApproximateMode; -extern int inStridesAllowedMode; -extern int addingOuterEqualities; -extern int outerColor; - -const int keyMult = 31; -const int hashTableSize =5*maxmaxGEQs; -const int maxKeys = 8*maxmaxGEQs; -extern int hashVersion; -extern eqn hashMaster[hashTableSize]; -extern int fastLookup[maxKeys*2]; -extern int nextKey; - -extern int reduceWithSubs; -extern int pleaseNoEqualitiesInSimplifiedProblems; - -#define noProblem ((Problem *) 0) - -extern Problem *originalProblem; -int checkIfSingleVar(eqn *e, int i); -/* Solve e = factor alpha for x_j and substitute */ - -void negateCoefficients(eqn * eqn, int nV); - -extern int omegaInitialized; -extern Problem full_answer, context,redProblem; - -#if defined BRAIN_DAMAGED_FREE -static inline void free(const Problem *p) -{ - free((char *)p); -} -#endif - -#if defined NDEBUG -#define CHECK_FOR_DUPLICATE_VARIABLE_NAMES -#else -#define CHECK_FOR_DUPLICATE_VARIABLE_NAMES \ - { \ - std::vector<std::string> name(nVars); \ - for(int i=1; i<=nVars; i++) { \ - name[i-1] = variable(i); \ - assert(!name[i-1].empty()); \ - for(int j=1; j<i; j++) \ - assert(!(name[i-1] == name[j-1])); \ - } \ - } -#endif - - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/omega_i.h b/omegalib/omega/include/omega/omega_i.h deleted file mode 100644 index e5d9230..0000000 --- a/omegalib/omega/include/omega/omega_i.h +++ /dev/null @@ -1,30 +0,0 @@ -#if ! defined _omega_i_h -#define _omega_i_h 1 - -#include <omega/pres_var.h> - -namespace omega { - -/* #define Assert(c,t) if(!(c)) PresErrAssert(t) */ -/* void PresErrAssert(const char *t); */ - -extern Rel_Body null_rel; - -extern int skip_finalization_check; -// extern int skip_set_checks; - -// Global input and output variable tuples. - -extern Global_Input_Output_Tuple input_vars; -extern Global_Input_Output_Tuple output_vars; -extern Global_Input_Output_Tuple &set_vars; - -} // namespace - -#if ! defined DONT_INCLUDE_TEMPLATE_CODE -// with g++258, everything will need to make Tuple<Relation>, as a -// function taking it as an argument is a friend of lots of classes -#include <omega/Relation.h> -#endif - -#endif diff --git a/omegalib/omega/include/omega/pres_cmpr.h b/omegalib/omega/include/omega/pres_cmpr.h deleted file mode 100644 index fb3e6f0..0000000 --- a/omegalib/omega/include/omega/pres_cmpr.h +++ /dev/null @@ -1,49 +0,0 @@ -#if ! defined _pres_cmpr_h -#define _pres_cmpr_h 1 - -#include <omega/omega_core/oc.h> - -namespace omega { - -// -// Compressed problem: rectangular non-0 cut from the big problem. -// -class Comp_Constraints { -public: - Comp_Constraints(eqn *constrs, int no_constrs, int no_vars); - void UncompressConstr(eqn *constrs, short &pn_constrs); - ~Comp_Constraints(); - bool no_constraints() const - { return n_constrs == 0; } - int n_constraints() const - { return n_constrs; } - -protected: - inline int coef_index(int e, int v) - {return e*(n_vars+1) + v;} - -private: - int n_constrs; - int n_vars; - coef_t *coefs; -}; - -class Comp_Problem { -public: - Comp_Problem(Problem *problem); - Problem *UncompressProblem(); - bool no_constraints() const - { return eqs.no_constraints() && geqs.no_constraints(); } - -private: -/* === data === */ - int _nVars, _safeVars; - const char *(*_get_var_name)(unsigned int var, void *args); - void *_getVarNameArgs; - Comp_Constraints eqs; - Comp_Constraints geqs; -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_cnstr.h b/omegalib/omega/include/omega/pres_cnstr.h deleted file mode 100644 index 7b2d98d..0000000 --- a/omegalib/omega/include/omega/pres_cnstr.h +++ /dev/null @@ -1,192 +0,0 @@ -#if ! defined _pres_cnstr_h -#define _pres_cnstr_h 1 - -#include <omega/pres_var.h> -#include <vector> - -namespace omega { - -// -// Constraint handles -// - - - -void copy_constraint(Constraint_Handle H, const Constraint_Handle initial); - -class Constraint_Handle { -public: - Constraint_Handle() {} - virtual ~Constraint_Handle() {} - - void update_coef(Variable_ID, coef_t delta); - void update_const(coef_t delta); - coef_t get_coef(Variable_ID v) const; - coef_t get_const() const; - bool has_wildcards() const; - int max_tuple_pos() const; - int min_tuple_pos() const; - bool is_const(Variable_ID v); - bool is_const_except_for_global(Variable_ID v); - - virtual std::string print_to_string() const; - virtual std::string print_term_to_string() const; - - Variable_ID get_local(const Global_Var_ID G); - Variable_ID get_local(const Global_Var_ID G, Argument_Tuple of); - // not sure that the second one can be used in a meaningful - // way if the conjunct is in multiple relations - - void finalize(); - void multiply(int multiplier); - Rel_Body *relation() const; - - -protected: - Conjunct *c; - eqn **eqns; - int e; - - friend class Constr_Vars_Iter; - friend class Constraint_Iterator; - - Constraint_Handle(Conjunct *, eqn **, int); - -#if defined PROTECTED_DOESNT_WORK - friend class EQ_Handle; - friend class GEQ_Handle; -#endif - - void update_coef_during_simplify(Variable_ID, coef_t delta); - void update_const_during_simplify(coef_t delta); - coef_t get_const_during_simplify() const; - coef_t get_coef_during_simplify(Variable_ID v) const; - - -public: - friend class Conjunct; // assert_leading_info updates coef's - // as does move_UFS_to_input - friend class DNF; // and DNF::make_level_carried_to - - friend void copy_constraint(Constraint_Handle H, - const Constraint_Handle initial); - // copy_constraint does updates and gets at c and e - -}; - -class GEQ_Handle : public Constraint_Handle { -public: - inline GEQ_Handle() {} - - virtual std::string print_to_string() const; - virtual std::string print_term_to_string() const; - bool operator==(const Constraint_Handle &that); - - void negate(); - -private: - friend class Conjunct; - friend class GEQ_Iterator; - - GEQ_Handle(Conjunct *, int); -}; - - -class EQ_Handle : public Constraint_Handle { -public: - inline EQ_Handle() {} - - virtual std::string print_to_string() const; - virtual std::string print_term_to_string() const; - bool operator==(const Constraint_Handle &that); - -private: - friend class Conjunct; - friend class EQ_Iterator; - - EQ_Handle(Conjunct *, int); -}; - - -// -// Conjuct iterators -- for querying resulting DNF. -// -class Constraint_Iterator : public Generator<Constraint_Handle> { -public: - Constraint_Iterator(Conjunct *); - int live() const; - void operator++(int); - void operator++(); - Constraint_Handle operator* (); - Constraint_Handle operator* () const; - -private: - Conjunct *c; - int current,last; - eqn **eqns; -}; - - -class EQ_Iterator : public Generator<EQ_Handle> { -public: - EQ_Iterator(Conjunct *); - int live() const; - void operator++(int); - void operator++(); - EQ_Handle operator* (); - EQ_Handle operator* () const; - -private: - Conjunct *c; - int current, last; -}; - - -class GEQ_Iterator : public Generator<GEQ_Handle> { -public: - GEQ_Iterator(Conjunct *); - int live() const; - void operator++(int); - void operator++(); - GEQ_Handle operator* (); - GEQ_Handle operator* () const; - -private: - Conjunct *c; - int current, last; -}; - - -// -// Variables of constraint iterator. -// -struct Variable_Info { - Variable_ID var; - coef_t coef; - Variable_Info(Variable_ID _var, coef_t _coef) - { var = _var; coef = _coef; } -}; - -class Constr_Vars_Iter : public Generator<Variable_Info> { -public: - Constr_Vars_Iter(const Constraint_Handle &ch, bool _wild_only = false); - int live() const; - void operator++(int); - void operator++(); - Variable_Info operator*() const; - - Variable_ID curr_var() const; - coef_t curr_coef() const; - -private: - eqn **eqns; - int e; - Problem *prob; - Variable_ID_Tuple &vars; - bool wild_only; - int current; -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_conj.h b/omegalib/omega/include/omega/pres_conj.h deleted file mode 100644 index ea10a2c..0000000 --- a/omegalib/omega/include/omega/pres_conj.h +++ /dev/null @@ -1,299 +0,0 @@ -#if ! defined _pres_conj_h -#define _pres_conj_h 1 - -#include <limits.h> -#include <omega/pres_decl.h> -#include <omega/pres_logic.h> -#include <omega/pres_cnstr.h> - -namespace omega { - -// -// Conjunct -// -// About variables in Conjunct: -// All varaibles appear in exactly one declaration. -// All variables used in Conjunct are referenced in mappedVars. -// Wildcard variables are referenced both in mappedVars and in myLocals, -// since they are declared in the conjunct. -// All other variables are declared at the levels above. -// Column number is: -// in forwardingAddress in Problem if variablesInitialized is set, -// equal to position of Variable_ID in mappedVars list otherwise. -// - -class Conjunct : public F_Declaration { -public: - Constraint_Iterator constraints(); - Variable_ID_Tuple *variables(); - EQ_Iterator EQs(); - GEQ_Iterator GEQs(); - inline int n_EQs() { return problem->nEQs; } - inline int n_GEQs() { return problem->nGEQs; } - - void promise_that_ub_solutions_exist(Relation &R); - - inline Node_Type node_type() {return Op_Conjunct;} - - inline int is_true() {return problem->nEQs==0 && problem->nGEQs==0 - && exact;} - - void query_difference(Variable_ID v1, Variable_ID v2, - coef_t &lowerBound, coef_t &upperBound, bool &guaranteed); - void query_variable_bounds(Variable_ID v, coef_t &lowerBound, coef_t &upperBound); - coef_t query_variable_mod(Variable_ID v, coef_t factor); - bool query_variable_used(Variable_ID v); - - int countNonzeros() const { - int numberNZs; - coef_t maxCoef, SumAbsCoef; - problem->difficulty(numberNZs,maxCoef,SumAbsCoef); - return numberNZs; - } - - void difficulty(int &numberNZs, coef_t &maxCoef, coef_t &SumAbsCoef) const { - problem->difficulty(numberNZs,maxCoef,SumAbsCoef); - } - - int query_guaranteed_leading_0s() { - count_leading_0s(); - return guaranteed_leading_0s; - } - - int query_possible_leading_0s() { - count_leading_0s(); - return possible_leading_0s; - } - - int query_leading_dir() { - count_leading_0s(); - return leading_dir; - } - - void calculate_dimensions(Relation &R, int &ndim_all, int &ndim_domain); - int max_ufs_arity_of_set(); - int max_ufs_arity_of_in(); - int max_ufs_arity_of_out(); - - int rank(); - - ~Conjunct(); - - bool is_unknown() const; - inline bool is_exact() const { return exact;} - inline bool is_inexact() const { return !exact;} - inline void make_inexact() { exact=false;} - - -#if ! defined NDEBUG - void assert_leading_info(); -#else - void assert_leading_info() {} -#endif - - - // PRINTING FUNCTIONS - void print(FILE *output_file); - void prefix_print(FILE *output_file, int debug = 1); - std::string print_to_string(int true_printed); - std::string print_EQ_to_string(eqn *e) { return problem->print_EQ_to_string(e); } - std::string print_GEQ_to_string(eqn *e) { return problem->print_GEQ_to_string(e); } - std::string print_EQ_to_string(int e) - { return problem->print_EQ_to_string(&(problem->EQs[e])); } - std::string print_GEQ_to_string(int e) - { return problem->print_GEQ_to_string(&(problem->GEQs[e])); } - std::string print_term_to_string(eqn *e) { return problem->print_term_to_string(e,1); } - std::string print_EQ_term_to_string(int e) - { return problem->print_term_to_string(&(problem->EQs[e]),1); } - std::string print_GEQ_term_to_string(int e) - { return problem->print_term_to_string(&(problem->GEQs[e]),1); } - std::string print_sub_to_string(int col) { return problem->print_sub_to_string(col); } - -private: - - inline void interpret_unknown_as_true() { exact=true;} - - friend Relation approx_closure(NOT_CONST Relation &r, int n); - - virtual Conjunct *really_conjunct(); - - - // create new constraints with all co-efficients 0 - // These are public in F_And, use them from there. - EQ_Handle add_stride(int step, int preserves_level = 0); - EQ_Handle add_EQ(int preserves_level = 0); - GEQ_Handle add_GEQ(int preserves_level = 0); - EQ_Handle add_EQ(const Constraint_Handle &c, int preserves_level = 0); - GEQ_Handle add_GEQ(const Constraint_Handle &c, int preserves_level = 0); - - friend class GEQ_Handle; - friend class EQ_Handle; - friend class Sub_Handle; - friend class Constraint_Handle; - friend class Constraint_Iterator; - friend class GEQ_Iterator; - friend class EQ_Iterator; - friend class Sub_Iterator; - friend class Constr_Vars_Iter; - - - // FUNCTIONS HAVING TO DO WITH BUILDING FORMULAS/DNFs - bool can_add_child(); - void remap(); - void beautify(); - DNF* DNFize(); - int priority(); - virtual Conjunct *find_available_conjunct(); - void finalize(); - - friend class DNF; - - - - // CREATING CONJUNCTS - Conjunct(); - Conjunct(Conjunct &); - Conjunct(Formula *, Rel_Body *); - - friend class Formula; // add_conjunct (a private function) creates Conjuncts - friend class F_Not; - friend class F_Or; - // class F_And; is a friend below - - - // VARIOUS FUNCTIONS TO CREATE / WORK WITH VARIABLES - Variable_ID declare(Const_String s); - Variable_ID declare(); - Variable_ID declare(Variable_ID v); - - friend const char *get_var_name(unsigned int, void *); - void push_exists(Variable_ID_Tuple &S); - int get_column(Variable_ID); - int find_column(Variable_ID); - int map_to_column(Variable_ID); - void combine_columns(); - void reorder(); - void reorder_for_print(bool reverseOrder=false, - int first_pass_input=0, - int first_pass_output=0, - bool sort=false); - - friend void remap_DNF_vars(Rel_Body *new_rel, Rel_Body *old_rel); - - void localize_var(Variable_ID D); - - - // this creates variables in conjuncts for us: - friend int new_WC(Conjunct *nc, Problem *np); - - - // UFS/LEADING ZEROS STUFF - - void move_UFS_to_input(); - - void count_leading_0s(); - void invalidate_leading_info(int changed = -1); - void enforce_leading_info(int guaranteed, int possible, int dir); - - void reverse_leading_dir_info(); - - - - // CONJUNCT SPECIFIC STUFF - - void rm_color_constrs(); - inline int N_protected() { return problem->safeVars; } - - - void ordered_elimination(int symLen) { problem->ordered_elimination(symLen);} - void convertEQstoGEQs(bool excludeStrides); - - int cost(); - - inline Formula* copy(Formula *parent, Rel_Body *reln) - { return copy_conj_diff_relation(parent,reln); } - Conjunct* copy_conj_diff_relation(Formula *parent, Rel_Body *reln); - inline Conjunct* copy_conj_same_relation() - { return copy_conj_diff_relation(&(parent()), relation()); } - friend void internal_copy_conjunct(Conjunct* to, Conjunct* fr); - friend void copy_constraint(Constraint_Handle H, - const Constraint_Handle initial); - -#if defined STUDY_EVACUATIONS - // The core function of "evac.c" does lots of work with conjuncts: - friend bool check_subseq_n(Conjunct *c, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity, int n, bool allow_offset); - friend void assert_subbed_syms(Conjunct *c); - friend bool check_affine(Conjunct *d, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity); - friend evac study(Conjunct *C, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity); -#endif - - // The relational ops tend to do lots of demented things to Conjuncts: - friend class Rel_Body; - friend_rel_ops; - - // F_And sometimes absorbs conjuncts - friend class F_And; - - // Various DNFize functions also get a the problem: - - friend DNF* conj_and_not_dnf(Conjunct *pos_conj, DNF *neg_conjs, bool weak); - friend class F_Exists; - - // Substitutions are a wrapper around a low-level Problem operation - friend class Substitutions; - - // private functions to call problem functions - int simplifyProblem(); - int simplifyProblem(int verify, int subs, int redundantElimination); - int redSimplifyProblem(int effort, int computeGist); - - friend int simplify_conj(Conjunct* conj, int ver_sim, int elim_red, int color); - friend DNF* negate_conj(Conjunct* conj); - friend Conjunct* merge_conjs(Conjunct* conj1, Conjunct* conj2, - Merge_Action action, Rel_Body *body = 0); - friend void copy_conj_header(Conjunct* to, Conjunct* fr); - - - // === at last, the data === - - Variable_ID_Tuple mappedVars; - - int n_open_constraints; - bool cols_ordered; - bool simplified; - bool verified; - - int guaranteed_leading_0s; // -1 if unknown - int possible_leading_0s; // -1 if unknown - int leading_dir; // 0 if unknown, else +/- 1 - int leading_dir_valid_and_known(); - - bool exact; - - short r_constrs; // are redundant constraints eliminated? - Problem *problem; - - bool is_compressed(); - void compress(); - void uncompress(); - - friend class Comp_Problem; - Comp_Problem *comp_problem; -}; - - -/* === Misc. problem manipulation utilities === */ - -const int CantBeNegated = INT_MAX-10; -const int AvoidNegating = INT_MAX-11; - -void copy_column(Problem *tp, int to_col, - Problem *fp, int fr_col, - int start_EQ, int start_GEQ); -void zero_column(Problem *tp, int to_col, - int start_EQ, int start_GEQ, - int no_EQs, int no_GEQs); - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_decl.h b/omegalib/omega/include/omega/pres_decl.h deleted file mode 100644 index 7fec0bc..0000000 --- a/omegalib/omega/include/omega/pres_decl.h +++ /dev/null @@ -1,55 +0,0 @@ -#if ! defined _pres_decl_h -#define _pres_decl_h 1 - -#include <omega/pres_var.h> -#include <omega/pres_form.h> -#include <basic/Section.h> - -namespace omega { - -// -// Base class for presburger formula nodes with variables -// - -class F_Declaration : public Formula { -public: - virtual Variable_ID declare(Const_String s)=0; - virtual Variable_ID declare()=0; - virtual Variable_ID declare(Variable_ID)=0; - virtual Section<Variable_ID> declare_tuple(int size); - - void finalize(); - - inline Variable_ID_Tuple &locals() {return myLocals;} - -protected: - F_Declaration(Formula *, Rel_Body *); - F_Declaration(Formula *, Rel_Body *, Variable_ID_Tuple &); - ~F_Declaration(); - - Variable_ID do_declare(Const_String s, Var_Kind var_kind); - - void prefix_print(FILE *output_file, int debug = 1); - void print(FILE *output_file); - - void setup_names(); - void setup_anonymous_wildcard_names(); - - Variable_ID_Tuple myLocals; - friend class F_Forall; // rearrange needs to access myLocals - friend class F_Or; // push_exists - -private: - virtual bool can_add_child(); - - int priority(); - - friend void align(Rel_Body *originalr, Rel_Body *newr, F_Exists *fe, - Formula *f, const Mapping &mapping, bool &newrIsSet, - List<int> &seen_exists, - Variable_ID_Tuple &seen_exists_ids); -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_dnf.h b/omegalib/omega/include/omega/pres_dnf.h deleted file mode 100644 index 93d5942..0000000 --- a/omegalib/omega/include/omega/pres_dnf.h +++ /dev/null @@ -1,87 +0,0 @@ -#if ! defined _pres_dnf_h -#define _pres_dnf_h 1 - -#include <omega/pres_gen.h> - -namespace omega { - -// -// Disjunctive Normal Form -- list of Conjuncts -// -class DNF { -public: - void print(FILE *out_file); - void prefix_print(FILE *out_file, int debug = 1, bool parent_names_setup=false); - - bool is_definitely_false() const; - bool is_definitely_true() const; - int length() const; - - Conjunct *single_conjunct() const; - bool has_single_conjunct() const; - Conjunct *rm_first_conjunct(); - void clear(); - int query_guaranteed_leading_0s(int what_to_return_for_empty_dnf); - int query_possible_leading_0s(int what_to_return_for_empty_dnf); - int query_leading_dir(); - -private: - // all DNFize functions need to access the dnf builders: - friend class F_And; - friend class F_Or; - friend class Conjunct; - friend DNF * negate_conj(Conjunct *); - - friend class Rel_Body; - friend_rel_ops; - - DNF(); - ~DNF(); - - DNF* copy(Rel_Body *); - - void simplify(); - void make_level_carried_to(int level); - void count_leading_0s(); - - void add_conjunct(Conjunct*); - void join_DNF(DNF*); - void rm_conjunct(Conjunct *c); - - void rm_redundant_conjs(int effort); - void rm_redundant_inexact_conjs(); - void DNF_to_formula(Formula* root); - - - friend void remap_DNF_vars(Rel_Body *new_rel, Rel_Body *old_rel); - void remap(); - - void setup_names(); - - void remove_inexact_conj(); - - // These may need to get at the conjList itself: - friend DNF* DNF_and_DNF(DNF*, DNF*); - friend DNF* DNF_and_conj(DNF*, Conjunct*); - friend DNF* conj_and_not_dnf(Conjunct *pos_conj, DNF *neg_conjs, bool weak); - - friend class DNF_Iterator; - - List<Conjunct*> conjList; -}; - -DNF* conj_and_not_dnf(Conjunct *pos_conj, DNF *neg_conjs, bool weak=false); - -// -// DNF iterator -// -class DNF_Iterator : public List_Iterator<Conjunct*> { -public: - DNF_Iterator(DNF*dnf) : List_Iterator<Conjunct*>(dnf->conjList) {} - DNF_Iterator() {} - void curr_set(Conjunct *c) { *(*this) = c; } -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_form.h b/omegalib/omega/include/omega/pres_form.h deleted file mode 100644 index ed3258e..0000000 --- a/omegalib/omega/include/omega/pres_form.h +++ /dev/null @@ -1,112 +0,0 @@ -#if ! defined _pres_form_h -#define _pres_form_h 1 - -#include <omega/pres_gen.h> - -namespace omega { - -typedef enum {Op_Relation, Op_Not, Op_And, Op_Or, - Op_Conjunct, Op_Forall, Op_Exists} Node_Type; - - -// -// Presburger Formula base class -// - -class Formula { -public: - virtual Node_Type node_type()=0; - - F_Forall *add_forall(); - F_Exists *add_exists(); - virtual F_And *and_with(); - F_And *add_and(); - F_Or *add_or(); - F_Not *add_not(); - void add_unknown(); - - virtual void finalize(); - virtual void print(FILE *output_file); - - Rel_Body *relation() { return myRelation; } - -protected: - virtual ~Formula(); -private: - Formula(Formula *, Rel_Body *); - - // The relational operations need to work with formula trees - friend class Relation; - friend_rel_ops; - // as do the functions that build DNF's - friend class DNF; - // or other parts of the tree - friend class Conjunct; - friend class F_Declaration; - friend class F_Exists; - friend class F_Forall; - friend class F_Or; - friend class F_And; - friend class F_Not; - friend class Rel_Body; - - - // Operations needed for manipulation of formula trees: - - void remove_child(Formula *); - void replace_child(Formula *child, Formula *new_child); - virtual bool can_add_child(); - void add_child(Formula *); - - Conjunct *add_conjunct(); - virtual Conjunct *find_available_conjunct() = 0; - - virtual Formula *copy(Formula *parent, Rel_Body *reln); - F_Exists *add_exists(Variable_ID_Tuple &S); - virtual void push_exists(Variable_ID_Tuple &S); - - // Accessor functions for tree building - - List<Formula*> &children() {return myChildren;} - int n_children() const {return myChildren.length();} - const List<Formula*> &get_children() const {return myChildren;} - Formula &parent() {return *myParent;} - void set_parent(Formula *p) {myParent = p;} - - - virtual int priority(); - - void verify_tree(); // should be const, but iterators are used - - virtual void reverse_leading_dir_info(); - virtual void invalidate_leading_info(int changed = -1); - virtual void enforce_leading_info(int guaranteed, int possible, int dir); - - virtual void remap(); - virtual DNF* DNFize() = 0; - virtual void beautify(); - virtual void rearrange(); - virtual void setup_names(); - - virtual void print_separator(FILE *output_file); - virtual void combine_columns(); - virtual void prefix_print(FILE *output_file, int debug = 1); - void print_head(FILE *output_file); - - void set_relation(Rel_Body *r); - void set_parent(Formula *parent, Rel_Body *reln); - - void assert_not_finalized(); - - virtual Conjunct *really_conjunct(); // until we get RTTI - -private: - List<Formula*> myChildren; - Formula *myParent; - Rel_Body *myRelation; - -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_gen.h b/omegalib/omega/include/omega/pres_gen.h deleted file mode 100644 index ba6a793..0000000 --- a/omegalib/omega/include/omega/pres_gen.h +++ /dev/null @@ -1,192 +0,0 @@ -#if ! defined _pres_gen_h -#define _pres_gen_h 1 - -#include <omega/omega_core/oc.h> -#include <basic/ConstString.h> -#include <basic/Iterator.h> -#include <basic/List.h> -#include <basic/Tuple.h> -#include <assert.h> -#include <stdlib.h> - -namespace omega { - -// -// general presburger stuff thats needed everywhere -// - -/* The following allows us to avoid warnings about passing - temporaries as non-const references. This is useful but - has suddenly become illegal. */ - -#if !defined(LIE_ABOUT_CONST_TO_MAKE_ANSI_COMMITTEE_HAPPY) -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) -#define LIE_ABOUT_CONST_TO_MAKE_ANSI_COMMITTEE_HAPPY 1 -#else -#define LIE_ABOUT_CONST_TO_MAKE_ANSI_COMMITTEE_HAPPY 0 -#endif -#endif - -#if LIE_ABOUT_CONST_TO_MAKE_ANSI_COMMITTEE_HAPPY -#define NOT_CONST const -#else -#define NOT_CONST -#endif - -// -// I/O and error processing and control flags (also in omega_core/debugging.h) -// - -extern FILE *DebugFile; -extern int pres_debug; - -extern int mega_total; -extern int use_ugly_names; - -extern negation_control pres_legal_negations; - - -// -// Lots of things refer to each other, -// so we forward declare these classes: -// - -class Var_Decl; -typedef enum {Input_Var, Set_Var = Input_Var, Output_Var, - Global_Var, Forall_Var, Exists_Var, Wildcard_Var} Var_Kind; -class Global_Var_Decl; -typedef enum {Unknown_Tuple = 0, Input_Tuple = 1, Output_Tuple = 2, - Set_Tuple = Input_Tuple } Argument_Tuple; - -class Constraint_Handle; -class EQ_Handle; -class GEQ_Handle; -typedef EQ_Handle Stride_Handle; - -class Formula; -class F_Declaration; -class F_Forall; -class F_Exists; -class F_And; -class F_Or; -class F_Not; -class Conjunct; -class Relation; -class Rel_Body; -class DNF; -class Mapping; -class Omega_Var; -class Coef_Var_Decl; - -typedef Var_Decl *Variable_ID; -typedef Global_Var_Decl *Global_Var_ID; - -typedef Tuple<Variable_ID> Variable_ID_Tuple; -typedef Sequence<Variable_ID> Variable_ID_Sequence; // use only for rvalues -typedef Tuple_Iterator<Variable_ID> Variable_ID_Tuple_Iterator; -typedef Tuple_Iterator<Variable_ID> Variable_ID_Iterator; - -typedef Variable_ID_Iterator Variable_Iterator; - -typedef enum {Comb_Id, Comb_And, Comb_Or, Comb_AndNot} Combine_Type; - - -// things that are (hopefully) used only privately -class Comp_Problem; -class Comp_Constraints; - -// this has to be here rather than in pres_conj.h because -// MergeConj has to be a friend of Constraint_Handle -typedef enum {MERGE_REGULAR, MERGE_COMPOSE, MERGE_GIST} Merge_Action; - - -// Conjunct can be exact or lower or upper bound. -// For lower bound conjunct, the upper bound is assumed to be true; -// For upper bound conjunct, the lower bound is assumed to be false - -typedef enum {EXACT_BOUND, UPPER_BOUND, LOWER_BOUND, UNSET_BOUND} Bound_Type; - - -#if defined STUDY_EVACUATIONS -typedef enum { in_to_out = 0, out_to_in = 1} which_way; - -enum evac { evac_trivial = 0, - evac_offset = 1, - evac_subseq = 2, - evac_offset_subseq = 3, -// evac_permutation = , - evac_affine = 4, - evac_nasty = 5 }; - -extern char *evac_names[]; - -#endif - -// the following list should be updated in sync with Relations.h - -#define friend_rel_ops \ -friend Relation Union(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend Relation Intersection(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend Relation After(NOT_CONST Relation &R, int carried_by, int new_output, int dir);\ -friend Relation Extend_Domain(NOT_CONST Relation &R); \ -friend Relation Extend_Domain(NOT_CONST Relation &R, int more); \ -friend Relation Extend_Range(NOT_CONST Relation &R); \ -friend Relation Extend_Range(NOT_CONST Relation &R, int more); \ -friend Relation Extend_Set(NOT_CONST Relation &R); \ -friend Relation Extend_Set(NOT_CONST Relation &R, int more); \ -friend Relation Restrict_Domain(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend Relation Restrict_Range(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend Relation Domain(NOT_CONST Relation &r); \ -friend Relation Range(NOT_CONST Relation &r); \ -friend Relation Cross_Product(NOT_CONST Relation &A, NOT_CONST Relation &B); \ -friend Relation Inverse(NOT_CONST Relation &r); \ -friend Relation Deltas(NOT_CONST Relation &R); \ -friend Relation Deltas(NOT_CONST Relation &R, int eq_no); \ -friend Relation DeltasToRelation(NOT_CONST Relation &R, int n_input, int n_output); \ -friend Relation Complement(NOT_CONST Relation &r); \ -friend Relation Project(NOT_CONST Relation &R, Global_Var_ID v); \ -friend Relation Project(NOT_CONST Relation &r, int pos, Var_Kind vkind); \ -friend Relation Project(NOT_CONST Relation &S, Sequence<Variable_ID> &s); \ -friend Relation Project_Sym(NOT_CONST Relation &R); \ -friend Relation Project_On_Sym(NOT_CONST Relation &R, NOT_CONST Relation &context); \ -friend Relation GistSingleConjunct(NOT_CONST Relation &R1, NOT_CONST Relation &R2, int effort); \ -friend Relation Gist(NOT_CONST Relation &R1, NOT_CONST Relation &R2, int effort); \ -friend Relation Difference(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend Relation Approximate(NOT_CONST Relation &R, bool strides_allowed); \ -friend Relation Identity(int n_inp); \ -friend Relation Identity(NOT_CONST Relation &r); \ -friend bool do_subset_check(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend bool Must_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend bool Might_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend bool May_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend bool Is_Obvious_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2); \ -friend Relation Join(NOT_CONST Relation &G, NOT_CONST Relation &F); \ -friend Relation Composition(NOT_CONST Relation &F, NOT_CONST Relation &G); \ -friend bool can_do_exact_composition(NOT_CONST Relation &F, NOT_CONST Relation &G); \ -friend Relation EQs_to_GEQs(NOT_CONST Relation &, bool excludeStrides); \ -friend Relation Symbolic_Solution(NOT_CONST Relation &S); \ -friend Relation Symbolic_Solution(NOT_CONST Relation &S, Sequence<Variable_ID> &T); \ -friend Relation Sample_Solution(NOT_CONST Relation &S); \ -friend Relation Solution(NOT_CONST Relation &S, Sequence<Variable_ID> &T); \ -friend void MapRel1(Relation &inputRel, const Mapping &map, \ - Combine_Type ctype, int number_input, \ - int number_output, bool, bool); \ -friend Relation MapAndCombineRel2(Relation &R1, Relation &R2, \ - const Mapping &mapping1, \ - const Mapping &mapping2, \ - Combine_Type ctype, \ - int number_input, \ - int number_output); \ -friend void align(Rel_Body *, Rel_Body *, F_Exists *, \ - Formula *, const Mapping &, bool &, \ - List<int> &, Variable_ID_Tuple &); \ -friend Relation Lower_Bound(NOT_CONST Relation &r); \ -friend Relation Upper_Bound(NOT_CONST Relation &r) - - -// REMEMBER - THE LAST LINE OF THE MACRO SHOULD NOT HAVE A ; -/* TransitiveClosure doesn't need to be in friend_rel_ops */ - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_logic.h b/omegalib/omega/include/omega/pres_logic.h deleted file mode 100644 index 27c4553..0000000 --- a/omegalib/omega/include/omega/pres_logic.h +++ /dev/null @@ -1,90 +0,0 @@ -#if ! defined _pres_logic_h -#define _pres_logic_h 1 - -#include <omega/pres_form.h> - -namespace omega { -// -// Presburger formula classes for logical operations: and, or not -// - -class F_And : public Formula { -public: - inline Node_Type node_type() {return Op_And;} - - // "preserves level" should be 0 unless we know this will not - // change the "level" of the constraints - ie the number of - // leading corresponding in,out variables known to be equal - GEQ_Handle add_GEQ(int preserves_level = 0); - EQ_Handle add_EQ(int preserves_level = 0); - Stride_Handle add_stride(int step, int preserves_level = 0); - EQ_Handle add_EQ(const Constraint_Handle &c, int preserves_level = 0); - GEQ_Handle add_GEQ(const Constraint_Handle &c, int preserves_level = 0); - - F_And *and_with(); - void add_unknown(); - -private: - friend class Formula; // add_and() - F_And(Formula *p, Rel_Body *r); - -private: - Formula *copy(Formula *parent, Rel_Body *reln); - virtual Conjunct *find_available_conjunct(); - int priority(); - void print_separator(FILE *output_file); - void prefix_print(FILE *output_file, int debug = 1); - void beautify(); - DNF* DNFize(); - - Conjunct *pos_conj; -}; - - -class F_Or : public Formula { -public: - inline Node_Type node_type() {return Op_Or;} - -private: - friend class Formula; // add_or - F_Or(Formula *, Rel_Body *); - -private: - Formula *copy(Formula *parent, Rel_Body *reln); - - virtual Conjunct *find_available_conjunct(); - void print_separator(FILE *output_file); - void prefix_print(FILE *output_file, int debug = 1); - void beautify(); - int priority(); - DNF* DNFize(); - void push_exists(Variable_ID_Tuple &S); -}; - - -class F_Not : public Formula { -public: - inline Node_Type node_type() {return Op_Not;} - void finalize(); - -private: - friend class Formula; - F_Not(Formula *, Rel_Body *); - -private: - Formula *copy(Formula *parent, Rel_Body *reln); - - virtual Conjunct *find_available_conjunct(); - friend class F_Forall; - bool can_add_child(); - void beautify(); - void rearrange(); - int priority(); - DNF* DNFize(); - void print(FILE *output_file); - void prefix_print(FILE *output_file, int debug = 1); -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_quant.h b/omegalib/omega/include/omega/pres_quant.h deleted file mode 100644 index 98c30df..0000000 --- a/omegalib/omega/include/omega/pres_quant.h +++ /dev/null @@ -1,63 +0,0 @@ -#if ! defined _pres_quant_h -#define _pres_quant_h 1 - -#include <omega/pres_decl.h> - -namespace omega { - -// -// Presburger formula nodes for quantifiers -// - -class F_Exists : public F_Declaration { -public: - inline Node_Type node_type() {return Op_Exists;} - Variable_ID declare(Const_String s); - Variable_ID declare(); - Variable_ID declare(Variable_ID v); - virtual void push_exists(Variable_ID_Tuple &S); - -protected: - friend class Formula; - - F_Exists(Formula *, Rel_Body *); - F_Exists(Formula *, Rel_Body *, Variable_ID_Tuple &); - -private: - Formula *copy(Formula *parent, Rel_Body *reln); - - virtual Conjunct *find_available_conjunct(); - void print(FILE *output_file); - void prefix_print(FILE *output_file, int debug = 1); - void beautify(); - void rearrange(); - DNF* DNFize(); -}; - - -class F_Forall : public F_Declaration { -public: - inline Node_Type node_type() {return Op_Forall;} - Variable_ID declare(Const_String s); - Variable_ID declare(); - Variable_ID declare(Variable_ID v); - -protected: - friend class Formula; - - F_Forall(Formula *, Rel_Body *); - -private: - Formula *copy(Formula *parent, Rel_Body *reln); - - virtual Conjunct *find_available_conjunct(); - void print(FILE *output_file); - void prefix_print(FILE *output_file, int debug = 1); - void beautify(); - void rearrange(); - DNF* DNFize(); -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_subs.h b/omegalib/omega/include/omega/pres_subs.h deleted file mode 100644 index 8a9ee92..0000000 --- a/omegalib/omega/include/omega/pres_subs.h +++ /dev/null @@ -1,88 +0,0 @@ -#if !defined(pres_subs_h) -#define pres_subs_h - -/* Interface to omega core's substitutions. - - Creating an object of class Substitutions causes ordered elimination, - i.e. variables in the input and output tuples are substituted for by - functions of earlier variables. Could conceivablely create a more - flexible interface to orderedElimination if we developed a way to - specify the desired variable order. - - This is not an entirely consistent interface, since Sub_Handles - shouldn't really permit update_coef on SUBs. It is not a real - problem since subs are now no longer part of a conjunct, but it is - a slightly odd situation. - - Don't try to simplify r after performing orderedElimination. -*/ - - -#include <omega/pres_gen.h> -#include <omega/Relation.h> -#include <omega/pres_conj.h> -#include <omega/pres_cnstr.h> - -namespace omega { - -class Sub_Handle; -class Sub_Iterator; - -class Substitutions { -public: - Substitutions(Relation &input_R, Conjunct *input_c); - ~Substitutions(); - Sub_Handle get_sub(Variable_ID v); - bool substituted(Variable_ID v); - bool sub_involves(Variable_ID v, Var_Kind kind); -private: - friend class Sub_Iterator; - friend class Sub_Handle; - Relation *r; - Conjunct *c; - eqn *subs; - Variable_ID_Tuple subbed_vars; -}; - - -//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - - -class Sub_Handle: public Constraint_Handle { -public: - inline Sub_Handle() {} - - virtual std::string print_to_string() const; - virtual std::string print_term_to_string() const; - Variable_ID variable() {return v;} - -private: - friend class Substitutions; - friend class Sub_Iterator; - Sub_Handle(Substitutions *, int, Variable_ID); -// Sub_Handle(Substitutions *, int); - - Variable_ID v; -}; - -//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - - -class Sub_Iterator : public Generator<Sub_Handle> { -public: - Sub_Iterator(Substitutions *input_s): s(input_s), current(0), - last(s->c->problem->nSUBs-1) {} - int live() const; - void operator++(int); - void operator++(); - Sub_Handle operator* (); - Sub_Handle operator* () const; - -private: - Substitutions *s; - int current, last; -}; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/pres_tree.h b/omegalib/omega/include/omega/pres_tree.h deleted file mode 100644 index ad78ad0..0000000 --- a/omegalib/omega/include/omega/pres_tree.h +++ /dev/null @@ -1,15 +0,0 @@ -#if ! defined _pres_tree_h -#define _pres_tree_h 1 - -// -// Header to include if you need all the classes to build -// a Presburger formula: -// variables, constraints, nodes for logical operations & quantifiers -// - -#include <omega/pres_var.h> -#include <omega/pres_cnstr.h> -#include <omega/pres_logic.h> -#include <omega/pres_quant.h> - -#endif diff --git a/omegalib/omega/include/omega/pres_var.h b/omegalib/omega/include/omega/pres_var.h deleted file mode 100644 index bf60dcb..0000000 --- a/omegalib/omega/include/omega/pres_var.h +++ /dev/null @@ -1,230 +0,0 @@ -#if ! defined _pres_var_h -#define _pres_var_h 1 - -#include <omega/pres_gen.h> -#include <map> - -namespace omega { - -// -// Variable declaration. -// Variables are free or quantified. -// Free variables are classified as input, output and global. -// Quantified variables are classified as forall, exists and wildcard. -// All global variables are functions symbols of (possibly 0) arguments -// Local variables that correspond to >0-ary functions are identified -// as functions of a prefix of the input, output, or both tuples -// -// -// typedef enum {Input_Var, Output_Var, Set_Var, -// Global_Var, Forall_Var, Exists_Var, Wildcard_Var} Var_Kind; - -typedef enum {Free_Var, Coef_Var, Bomega_Var} Global_Kind; - -// NOW IN PRES_GEN.H, as its used as an argument and can't -// be forward declared: -// typedef enum {Unknown_Tuple = 0, Input_Tuple = 1, Output_Tuple = 2, -// Set_Tuple = Input_Tuple } Argument_Tuple; -// Only Input, Output, and Set can be passed to get_local, -// but the values 0 and 3 are also used internally. - - -class Var_Decl { -public: - inline Var_Kind kind() { return var_kind; } - int get_position(); - Global_Var_ID get_global_var(); - Argument_Tuple function_of(); // valid iff kind() == Global_var - - Const_String base_name; - void name_variable(char *newname); - - // The following should be used with care, as they are only valid - // after setup_names has been used on the relation containing this - // variable. - std::string name(); - const char* char_name(); - void set_kind(Var_Kind v) { var_kind = v; } - - // Operation to allow the remap field to be used for - // union-find operations on variables. - // Be sure to reset the remap fields afterward - void UF_union(Variable_ID v); - Variable_ID UF_owner(); - -private: - Var_Decl(Const_String name, Var_Kind vkind, int pos); - Var_Decl(Var_Kind vkind, int pos); - Var_Decl(Variable_ID v); - Var_Decl(Const_String name, Global_Var_ID v); - Var_Decl(Const_String name, Global_Var_ID v, Argument_Tuple function_of); - - friend class F_Declaration; // creates local variables - friend class Global_Var_Decl; // its constructors create Var_Decls. - - friend class Global_Input_Output_Tuple; - friend void copy_var_decls(Variable_ID_Tuple &new_vl, Variable_ID_Tuple &vl); - -private: - int instance; - void setup_name(); - - // these set up the names - friend class Rel_Body; -// friend class F_Declaration; already a friend - -private: - Variable_ID remap; // pointer to new copy of this node - - // lots of things need to get at "remap" - lots of relation ops, - // and functions that move UFS's around: - // dnf::make_level_carried_to and Conjunct::move_UFS_to_input() - // Also of course Conjunct::remap and push_exists - friend_rel_ops; - friend class DNF; - friend class Conjunct; - - // this prints remap to the debugging output - friend void print_var_addrs(std::string &s, Variable_ID v); - - friend void reset_remap_field(Variable_ID v); - friend void reset_remap_field(Sequence<Variable_ID> &S); - friend void reset_remap_field(Sequence<Variable_ID> &S, int var_no); - friend void reset_remap_field(Variable_ID_Tuple &S); - friend void reset_remap_field(Variable_ID_Tuple &S, int var_no); - -private: - - Var_Kind var_kind; - int position; // only for Input_Var, Output_Var - Global_Var_ID global_var; // only for Global_Var - Argument_Tuple of; // only for Global_Var -}; - -bool rm_variable(Variable_ID_Tuple &vl, Variable_ID v); -void reset_remap_field(Sequence<Variable_ID> &S); -void reset_remap_field(Sequence<Variable_ID> &S, int var_no); -void reset_remap_field(Variable_ID v); -void reset_remap_field(Variable_ID_Tuple &S); -void reset_remap_field(Variable_ID_Tuple &S, int var_no); - -class Global_Input_Output_Tuple: public Tuple<Variable_ID> { -public: - Global_Input_Output_Tuple(Var_Kind in_my_kind, int init=-1); - ~Global_Input_Output_Tuple(); - virtual Variable_ID &operator[](int index); - virtual const Variable_ID &operator[](int index) const; -private: - Var_Kind my_kind; - static const int initial_allocation; -}; - -extern Global_Input_Output_Tuple input_vars; -extern Global_Input_Output_Tuple output_vars; -// This allows the user to refer to set_vars to query sets, w/o knowing -// they are really inputs. -extern Global_Input_Output_Tuple &set_vars; - -Variable_ID input_var(int nth); -Variable_ID output_var(int nth); -Variable_ID set_var(int nth); - - - -// -// Global_Var_ID uniquely identifies global var-s through the whole program. -// Global_Var_Decl is an ADT with the following operations: -// - create global variable, -// - find the arity of the variable, (default = 0, for symbolic consts) -// - get the name of global variable, -// - tell if two variables are the same (if they are the same object) -// - -class Global_Var_Decl { -public: - Global_Var_Decl(Const_String baseName); - - virtual Const_String base_name() const - { - return loc_rep1.base_name; - } - - virtual void set_base_name(Const_String newName) - { - loc_rep1.base_name = newName; - loc_rep2.base_name = newName; - } - - virtual int arity() const - { - return 0; // default compatible with old symbolic constant stuff - } - - virtual Omega_Var *really_omega_var(); // until we get RTTI in C++ - virtual Coef_Var_Decl *really_coef_var(); // until we get RTTI in C++ - virtual Global_Kind kind() const; - -private: - - friend class Rel_Body; // Rel_Body::get_local calls this get_local - - Variable_ID get_local() - { - assert(arity() == 0); - return &loc_rep1; - } - Variable_ID get_local(Argument_Tuple of) - { - assert(arity() == 0 || of == Input_Tuple || of == Output_Tuple); - return ((arity() == 0 || of == Input_Tuple) ? &loc_rep1 : &loc_rep2); - } - - // local representative, there is just 1 for every 0-ary global variable - Var_Decl loc_rep1; // arity == 0, or arity > 0 and of == In - Var_Decl loc_rep2; // arity > 0 and of == Out - -public: -// friend class Rel_Body; // Rel_Body::setup_names sets instance - friend class Var_Decl; - int instance; -}; - - -class Coef_Var_Decl : public Global_Var_Decl { -public: - Coef_Var_Decl(int id, int var); - int stmt() const; - int var() const; - virtual Global_Kind kind() const; - virtual Coef_Var_Decl *really_coef_var(); // until we get RTTI in C++ - -private: - int i, v; -}; - - - -// -// Test subclass for Global_Var: named global variable -// -class Free_Var_Decl : public Global_Var_Decl { -public: - Free_Var_Decl(Const_String name); - Free_Var_Decl(Const_String name, int arity); - int arity() const; - virtual Global_Kind kind() const; - -private: - int _arity; -}; - - -/* === implementation functions === */ -void copy_var_decls(Variable_ID_Tuple &new_vl, Variable_ID_Tuple &vl); -void free_var_decls(Variable_ID_Tuple &vl); - -extern int wildCardInstanceNumber; - -} // namespace - -#endif diff --git a/omegalib/omega/include/omega/reach.h b/omegalib/omega/include/omega/reach.h deleted file mode 100644 index 76d7dee..0000000 --- a/omegalib/omega/include/omega/reach.h +++ /dev/null @@ -1,23 +0,0 @@ -#if ! defined _reach_h -#define _reach_h 1 - -namespace omega { - -class reachable_information { -public: - Tuple<std::string> node_names; - Tuple<int> node_arity; - DynamicArray1<Relation> start_nodes; - DynamicArray2<Relation> transitions; -}; - - -DynamicArray1<Relation> * -Reachable_Nodes(reachable_information * reachable_info); - -DynamicArray1<Relation> * -I_Reachable_Nodes(reachable_information * reachable_info); - -} // namespace - -#endif diff --git a/omegalib/omega/src/RelBody.cc b/omegalib/omega/src/RelBody.cc deleted file mode 100644 index 825b153..0000000 --- a/omegalib/omega/src/RelBody.cc +++ /dev/null @@ -1,906 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - class Rel_Body, internal Relation representation - - Notes: - - History: - 11/26/09 Remove unecessary mandatary checking for set or relation, - treat them uniformly for easy coding, by Chun Chen -*****************************************************************************/ - -#include <basic/util.h> -#include <omega/RelBody.h> -#include <omega/Relation.h> -#include <omega/pres_tree.h> -#include <omega/pres_conj.h> -#include <omega/omega_i.h> -#include <assert.h> - -namespace omega { - -Rel_Body null_rel; -bool Rel_Body::is_null() const { - return(this == &null_rel); -} - - -int Rel_Body::max_ufs_arity() { - int ma = 0, a; - for (Variable_ID_Iterator v(*global_decls()); v; v++) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - -int Rel_Body::max_ufs_arity_of_set() { - int ma = 0, a; - for (Variable_ID_Iterator v(*global_decls()); v; v++) - if ((*v)->function_of() == Set_Tuple) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - -int Rel_Body::max_ufs_arity_of_in() { - int ma = 0, a; - for (Variable_ID_Iterator v(*global_decls()); v; v++) - if ((*v)->function_of() == Input_Tuple) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - -int Rel_Body::max_ufs_arity_of_out() { - int ma = 0, a; - for (Variable_ID_Iterator v(*global_decls()); v; v++) - if ((*v)->function_of() == Output_Tuple) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - -int Rel_Body::max_shared_ufs_arity() { - int ma = 0, a; - for (Variable_ID_Iterator v(*global_decls()); v; v++) - for (Variable_ID_Iterator v2(*global_decls()); v2; v2++) - if (*v != *v2 - && (*v)->get_global_var() == (*v2)->get_global_var() - && (*v)->function_of() != (*v2)->function_of()) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - -// -// Input and output variables. -// -void Rel_Body::name_input_var(int nth, Const_String S) { - // assert(1 <= nth && nth <= number_input && (!is_set() || skip_set_checks > 0)); - if (is_null()) - throw std::invalid_argument("empty relation"); - if (nth < 1 || nth > number_input) - throw std::invalid_argument("invalid input var number"); - In_Names[nth] = S; -} - -void Rel_Body::name_output_var(int nth, Const_String S) { - // assert(1<= nth && nth <= number_output && (!is_set() || skip_set_checks > 0)); - if (is_null()) - throw std::invalid_argument("empty relation"); - if (nth < 1 || nth > number_output) - throw std::invalid_argument("invalid output var number"); - Out_Names[nth] = S; -} - -void Rel_Body::name_set_var(int nth, Const_String S) { - if (number_output != 0) - throw std::runtime_error("relation is not a set"); - name_input_var(nth, S); -} - -int Rel_Body::n_inp() const { - // assert(!is_null() && (!is_set()||skip_set_checks>0)); - if (is_null()) - return 0; - else - return number_input; -} - -int Rel_Body::n_out() const { - // assert(!is_null() && (!is_set()||skip_set_checks>0)); - if (is_null()) - return 0; - else - return number_output; -} - -int Rel_Body::n_set() const { - if (number_output != 0) - throw std::runtime_error("relation is not a set"); - return n_inp(); -} - -Variable_ID Rel_Body::input_var(int nth) { - // assert(!is_null()); - // assert(!is_set() || skip_set_checks>0); - // assert(1 <= nth && nth <= number_input); - if (is_null()) - throw std::invalid_argument("empty relation"); - if (nth < 1 || nth > number_input) - throw std::invalid_argument("invalid input var number"); - input_vars[nth]->base_name = In_Names[nth]; - return input_vars[nth]; -} - -Variable_ID Rel_Body::output_var(int nth) { - // assert(!is_null()); - // assert(!is_set() || skip_set_checks>0); - // assert(1<= nth && nth <= number_output); - if (is_null()) - throw std::invalid_argument("empty relation"); - if (nth < 1 || nth > number_output) - throw std::invalid_argument("invalid output var number"); - output_vars[nth]->base_name = Out_Names[nth]; - return output_vars[nth]; -} - -Variable_ID Rel_Body::set_var(int nth) { - if (number_output != 0) - throw std::runtime_error("relation is not a set"); - return input_var(nth); -} - -// -// Add the AND node to the relation. -// Useful for adding restraints. -// -F_And *Rel_Body::and_with_and() { - assert(!is_null()); - if (is_simplified()) - DNF_to_formula(); - relation()->finalized = false; - Formula *f = rm_formula(); - F_And *a = add_and(); - a->add_child(f); - return a; -} - -// -// Add constraint to relation at the upper level. -// -EQ_Handle Rel_Body::and_with_EQ() { - assert(!is_null()); - if (is_simplified()) - DNF_to_formula(); - assert(! is_shared()); // The relation has been split. - relation()->finalized = false; - return find_available_conjunct()->add_EQ(); -} - -EQ_Handle Rel_Body::and_with_EQ(const Constraint_Handle &initial) { - assert(!is_null()); - assert(initial.relation()->is_simplified()); - EQ_Handle H = and_with_EQ(); - copy_constraint(H, initial); - return H; -} - -GEQ_Handle Rel_Body::and_with_GEQ() { - assert(!is_null()); - if (is_simplified()) - DNF_to_formula(); - assert(! is_shared()); // The relation has been split. - relation()->finalized = false; // We are giving out a handle. - // We should evantually implement finalization - // of subtrees, so the existing formula cannot - // be modified. - return find_available_conjunct()->add_GEQ(); -} - -GEQ_Handle Rel_Body::and_with_GEQ(const Constraint_Handle &initial) { - assert(!is_null()); - assert(initial.relation()->is_simplified()); - GEQ_Handle H = and_with_GEQ(); - copy_constraint(H, initial); - return H; -} - - - -Conjunct *Rel_Body::find_available_conjunct() { - Conjunct *c; - assert(!is_null()); - - if (children().empty()) { - c = add_conjunct(); - } - else { - assert(children().length() == 1); - Formula *kid = children().front(); // RelBodies have only one child - c = kid->find_available_conjunct(); - if (c==NULL) { - remove_child(kid); - F_And *a = add_and(); - a->add_child(kid); - c = a->add_conjunct(); - } - } - return c; -} - -void Rel_Body::finalize() { - assert(!is_null()); - if (!is_finalized()) - assert(! is_shared()); // no other pointers into here - finalized = true; - if (! children().empty()) - children().front()->finalize(); // Can have at most one child -} - -// Null Rel_Body -// This is the only rel_body constructor that has ref_count initialized to 1; -// That's because it's used to construct the global Rel_Body "null_rel". -// Unfortunately because we don't know in what order global constructors will -// be called, we could create a global relation with the default relation -// constructor (which would set the null_rel ref count to 1), and *then* -// call Rel_Body::Rel_Body(), which would set it back to 0, leaving a relation -// that points to a rel_body with it's ref_count set to 0! So this is done as -// a special case, in which the ref_count is always 1. -Rel_Body::Rel_Body(): - Formula(0, this), - ref_count(1), - status(under_construction), - number_input(0), number_output(0), - In_Names(0), Out_Names(0), - simplified_DNF(NULL), - r_conjs(0), - finalized(true), - _is_set(false) { -} - - -Rel_Body::Rel_Body(int n_input, int n_output): - Formula(0, this), - ref_count(0), - status(under_construction), - number_input(n_input), number_output(n_output), - In_Names(n_input), Out_Names(n_output), - simplified_DNF(NULL), - r_conjs(0), - finalized(false) { - if (n_output == 0) - _is_set = true; - else - _is_set = false; - if(pres_debug) { - fprintf(DebugFile, "+++ Create Rel_Body::Rel_Body(%d, %d) = 0x%p +++\n", - n_input, n_output, this); - } - int i; - for(i=1; i<=number_input; i++) { - In_Names[i] = Const_String(); - } - for(i=1; i<=number_output; i++) { - Out_Names[i] = Const_String(); - } -} - -// Rel_Body::Rel_Body(Rel_Body *r): -// Formula(0, this), -// ref_count(0), -// status(r->status), -// number_input(r->number_input), number_output(r->number_output), -// In_Names(r->number_input), Out_Names(r->number_output), -// simplified_DNF(NULL), -// r_conjs(r->r_conjs), -// finalized(r->finalized), -// _is_set(r->_is_set) { -// if(pres_debug) { -// fprintf(DebugFile, "+++ Copy Rel_Body::Rel_Body(Rel_Body * 0x%p) = 0x%p +++\n", r, this); -// prefix_print(DebugFile); -// } - -// int i; -// for(i=1;i<=r->number_input;i++) In_Names[i] = r->In_Names[i]; -// for(i=1;i<=r->number_output;i++) Out_Names[i] = r->Out_Names[i]; -// copy_var_decls(Symbolic,r->Symbolic); - -// if(!r->children().empty() && r->simplified_DNF==NULL) { -// Formula *f = r->formula()->copy(this,this); -// f->remap(); -// children().append(f); -// } -// else if(r->children().empty() && r->simplified_DNF!=NULL) { -// simplified_DNF = r->simplified_DNF->copy(this); -// simplified_DNF->remap(); -// } -// else { // copy NULL relation -// } - -// reset_remap_field(r->Symbolic); -// } - -Rel_Body *Rel_Body::clone() { - Rel_Body *b = new Rel_Body(); - - b->ref_count = 0; - b->status = status; - b->number_input = number_input; - b->number_output = number_output; - b->r_conjs = r_conjs; - b->finalized = finalized; - b->_is_set = _is_set; - - b->In_Names = Tuple<Const_String>(number_input); - b->Out_Names = Tuple<Const_String>(number_output); - for(int i = 1; i <= number_input; i++) - b->In_Names[i] = In_Names[i]; - for(int i = 1; i <= number_output; i++) - b->Out_Names[i] = Out_Names[i]; - - copy_var_decls(b->Symbolic, Symbolic); - - if(!children().empty() && simplified_DNF==NULL) { - Formula *f = formula()->copy(b, b); - f->remap(); - b->children().append(f); - } - else if(children().empty() && simplified_DNF!=NULL) { - b->simplified_DNF = simplified_DNF->copy(b); - b->simplified_DNF->remap(); - } - else { // copy NULL relation - } - - reset_remap_field(Symbolic); - return b; -} - - -Rel_Body::Rel_Body(Rel_Body *r, Conjunct *c): - Formula(0, this), - ref_count(0), - status(uncompressed), - number_input(r->number_input), number_output(r->number_output), - In_Names(r->number_input), Out_Names(r->number_output), - r_conjs(0), - finalized(r->finalized), - _is_set(r->_is_set) { - if(pres_debug) { - fprintf(DebugFile, "+++ Copy Rel_Body::Rel_Body(Rel_Body * 0x%p, Conjunct * 0x%p) = 0x%p +++\n",r,c,this); - } - - int i; - for(i=1;i<=r->number_input;i++) In_Names[i] = r->In_Names[i]; - for(i=1;i<=r->number_output;i++) Out_Names[i] = r->Out_Names[i]; - copy_var_decls(Symbolic,r->Symbolic); - - // assert that r has as many variables as c requires, or that c is from r - assert(r == c->relation()); - assert(r->simplified_DNF != NULL); - simplified_DNF = new DNF; - simplified_DNF->add_conjunct(c->copy_conj_diff_relation(this,this)); - single_conjunct()->remap(); - - reset_remap_field(r->Symbolic); -} - -Rel_Body::~Rel_Body() { - if(pres_debug) { - fprintf(DebugFile, "+++ Destroy Rel_Body::~Rel_Body() 0x%p +++\n", this); - } - free_var_decls(Symbolic); - if(simplified_DNF != NULL) { - delete simplified_DNF; - } -} - -// -// Take a relation that has been simplified and convert it -// back to formula form. -// -void Rel_Body::DNF_to_formula() { - assert(!is_null()); - if (simplified_DNF != NULL) { - simplified_DNF->DNF_to_formula(this); - simplified_DNF = NULL; - status = under_construction; - } -} - -bool Rel_Body::can_add_child() { - assert(this != &null_rel); - return n_children() < 1; -} - - - -// ******************** -// Simplify functions -// ******************** - - -extern int s_rdt_constrs; - - -// -// Simplify a given relation. -// Store the resulting DNF in the relation, clean out the formula. -// -void Rel_Body::simplify(int rdt_conjs, int rdt_constrs) { - if(simplified_DNF == NULL) { - finalized = true; - if(children().empty()) { - simplified_DNF = new DNF; - } - else { - if(pres_debug) { - if(DebugFile==NULL) { - DebugFile = fopen("test.out", "w"); - if(DebugFile==NULL) - fprintf(stderr, "Can not open file test.out\n"); - } - } - - assert(children().length()==1); - if(pres_debug) { - fprintf(DebugFile, "=== %p Rel_Body::simplify(%d, %d) Input tree (%d) ===\n", this,rdt_conjs,rdt_constrs,r_conjs); - prefix_print(DebugFile); - } - verify_tree(); - - beautify(); - verify_tree(); - - rearrange(); - verify_tree(); - - beautify(); - verify_tree(); - - s_rdt_constrs = rdt_constrs; - if(pres_debug) { - fprintf(DebugFile, "\n=== In simplify, before DNFize ===\n"); - prefix_print(DebugFile); - } - DNFize(); - if(pres_debug) { - fprintf(DebugFile, "\n=== In simplify, after DNFize ===\n"); - prefix_print(DebugFile); - } - verify_tree(); - - - simplified_DNF->rm_redundant_inexact_conjs(); - verify_tree(); - - if (rdt_conjs > 0 && !simplified_DNF->is_definitely_false() && simplified_DNF->length() > 1) { - simplified_DNF->rm_redundant_conjs(rdt_conjs-1); - verify_tree(); - } - - if(pres_debug) { - fprintf(DebugFile, "\n=== Resulting Relation ===\n"); - prefix_print(DebugFile); - } - } - } - else { - /* Reprocess DNF to get rid of redundant stuff */ - - if (rdt_constrs < 0) return; - simplified_DNF->rm_redundant_inexact_conjs(); - - if (rdt_conjs > r_conjs) { - if(pres_debug) - fprintf(DebugFile,"=== Rel_Body::simplify() redundant CONJUNCTS ===\n"); - simplified_DNF->rm_redundant_conjs(rdt_conjs-1); - } - if (rdt_constrs > 0 ) { - if(pres_debug) - fprintf(DebugFile,"=== Rel_Body::simplify() redundant CONSTR-S ===\n"); - s_rdt_constrs = rdt_constrs; - simplified_DNF->simplify(); - } - } - - r_conjs = rdt_conjs; - - for(DNF_Iterator D(simplified_DNF); D.live(); D.next()) { - D.curr()->set_relation(this); - D.curr()->set_parent(this); - } -} - - -// ****************** -// Query functions -// ****************** - - -// -// Check if relation has a single conjunct formula and return this conjunct. -// -Conjunct *Rel_Body::single_conjunct() { - simplify(); - return simplified_DNF->single_conjunct(); -} - -bool Rel_Body::has_single_conjunct() { - simplify(); - return simplified_DNF->has_single_conjunct(); -} - -// -// Remove and return first conjunct -// -Conjunct *Rel_Body::rm_first_conjunct() { - simplify(); - return simplified_DNF->rm_first_conjunct(); -} - - -void Rel_Body::query_difference(Variable_ID v1, Variable_ID v2, coef_t &lowerBound, coef_t &upperBound, bool &guaranteed) { - simplify(); - - coef_t _lb, _ub; - int first = 1; - bool _g; - lowerBound = negInfinity; // default values if no DNF's - upperBound = posInfinity; - guaranteed = 0; - - for (DNF_Iterator D(simplified_DNF); D.live(); D.next()) { - (*D)->query_difference(v1, v2, _lb, _ub, _g); - if (first) { - lowerBound = _lb; - upperBound = _ub; - guaranteed = _g; - first = 0; - } - else { - guaranteed = guaranteed && _g; - lowerBound = min(lowerBound, _lb); - upperBound = max(upperBound, _ub); - } - } -} - - -void Rel_Body::query_variable_bounds(Variable_ID v, coef_t &lowerBound, coef_t &upperBound) { - simplify(); - - coef_t _lb, _ub; - int first = 1; - lowerBound = negInfinity; // default values if no DNF's - upperBound = posInfinity; - - for (DNF_Iterator D(simplified_DNF); D.live(); D.next()) { - (*D)->query_variable_bounds(v, _lb, _ub); - if (first) { - lowerBound = _lb; - upperBound = _ub; - first = 0; - } - else { - lowerBound = min(lowerBound, _lb); - upperBound = max(upperBound, _ub); - } - } -} - -coef_t Rel_Body::query_variable_mod(Variable_ID v, coef_t factor) { - simplify(); - - bool first = true; - coef_t result; - - for (DNF_Iterator D(simplified_DNF); D.live(); D.next()) { - coef_t t = (*D)->query_variable_mod(v, factor); - if (t == posInfinity) - return posInfinity; - - if (first) { - result = t; - first = false; - } - else { - if (result != t) - return posInfinity; - } - } - - return result; -} - - - -// -// Simplify formula if needed and return the resulting DNF. -// -DNF* Rel_Body::query_DNF() { - return(query_DNF(false,false)); -} - -DNF* Rel_Body::query_DNF(int rdt_conjs, int rdt_constrs) { - simplify(rdt_conjs, rdt_constrs); - return(simplified_DNF); -} - -// -// Other formula queries. -// - -// Interpret UNKNOWN as true, then check satisfiability -// i.e., check if the formula simplifies to FALSE, since the library -// will never say that if the *known* constraints are unsatisfiable by -// themselves. -bool Rel_Body::is_upper_bound_satisfiable() { - int tmp = s_rdt_constrs; - s_rdt_constrs = -1; - simplify(); - s_rdt_constrs = tmp; - return(!simplified_DNF->is_definitely_false()); -} - -// Interpret UNKNOWN as false, then check satisfiability -// i.e., check if there exist any exact conjuncts in the solution -bool Rel_Body::is_lower_bound_satisfiable() { - int tmp = s_rdt_constrs; - s_rdt_constrs = -1; - simplify(); - s_rdt_constrs = tmp; - for(DNF_Iterator d(simplified_DNF); d; d++) - if((*d)->is_exact()) return true; - return false; -} - -bool Rel_Body::is_satisfiable() { - assert(is_lower_bound_satisfiable() == is_upper_bound_satisfiable()); - return is_upper_bound_satisfiable(); -} - -// Check if we can easily determine if the formula evaluates to true. -bool Rel_Body::is_obvious_tautology() { - int tmp = s_rdt_constrs; - s_rdt_constrs = 0; - simplify(); - s_rdt_constrs = tmp; - return(simplified_DNF->is_definitely_true()); -} - -// Expensive check to determine if the formula evaluates to true. -bool Rel_Body::is_definite_tautology() { - if(is_obvious_tautology()) return true; - Relation l = Lower_Bound(Relation(*this,1)); - return !(Complement(l).is_upper_bound_satisfiable()); -} - -bool Rel_Body::is_unknown() { - simplify(); - return(has_single_conjunct() && single_conjunct()->is_unknown()); -} - -// -// Get accuracy status of the relation -// - -Rel_Unknown_Uses Rel_Body::unknown_uses() { - if (!is_simplified()) - simplify(); - - Rel_Unknown_Uses local_status=0; - int n_conj=0; - - for (DNF_Iterator c(simplified_DNF); c; c++) { - n_conj++; - if ((*c)->is_exact()) - local_status |= no_u; - else if ((*c)->is_unknown()) - local_status |= or_u; - else - local_status |= and_u; - } - - if (n_conj == 0) { - assert(local_status == 0); - local_status = no_u; - } - assert(local_status); -#if ! defined NDEBUG - Rel_Unknown_Uses impossible = (and_u | or_u); - assert( (local_status & impossible) != impossible); -#endif - - return local_status; -} - -void Rel_Body::interpret_unknown_as_false() { - simplify(); - simplified_DNF->remove_inexact_conj(); -} - -void Rel_Body::interpret_unknown_as_true() { - simplify(); - for(DNF_Iterator d(simplified_DNF); d; d++) - (*d)->interpret_unknown_as_true(); -} - - -void Rel_Body::reverse_leading_dir_info() { - if (is_simplified()) { - for (DNF_Iterator c(simplified_DNF); c; c++) - (*c)->reverse_leading_dir_info(); - } - else { - assert(!simplified_DNF); - assert(children().size() == 1); - children().front()->reverse_leading_dir_info(); - } -} - -// -// Rel_Body::DNFize just DNF-izes its child node and calls verify -// - -DNF* Rel_Body::DNFize() { -#if defined(INCLUDE_COMPRESSION) - assert(!this->is_compressed()); -#endif - if (! simplified_DNF) { - simplified_DNF = children().remove_front()->DNFize(); - - int mua = max_shared_ufs_arity(); - if (mua > 0) { - if (pres_debug) { - fprintf(DebugFile, "\n=== In DNFize, before LCDNF ===\n"); - prefix_print(DebugFile); - } - - simplified_DNF->make_level_carried_to(mua); - } - - if(pres_debug) { - fprintf(DebugFile, "\n=== In DNFize, before verify ===\n"); - prefix_print(DebugFile); - } - - simplified_DNF->simplify(); - } - - assert(children().length() == 0); - - return simplified_DNF; -} - -void Rel_Body::make_level_carried_to(int level) { - if (!simplified_DNF) { - DNFize(); - } - - assert(simplified_DNF && children().empty()); - - simplified_DNF->make_level_carried_to(level); -} - -// -// if direction==0, move all conjuncts with >= level leading 0's to return -// else move all conjuncts with level-1 0's followed by -// the appropriate signed difference to returned Relation -// - -Relation Rel_Body::extract_dnf_by_carried_level(int level, int direction) { - if (!simplified_DNF) { - DNFize(); - } - - assert(simplified_DNF && children().empty()); - - simplified_DNF->make_level_carried_to(level); - - Relation extracted(n_inp(), n_out()); - extracted.copy_names(*this); - assert(extracted.rel_body->children().empty()); - assert(extracted.rel_body->simplified_DNF == NULL); - extracted.rel_body->simplified_DNF = new DNF; - extracted.rel_body->Symbolic = Symbolic; - - DNF *remaining = new DNF; - Conjunct *curr; - - for (curr = simplified_DNF->rm_first_conjunct(); - curr; - curr = simplified_DNF->rm_first_conjunct()) { - assert(curr->guaranteed_leading_0s >= level || curr->guaranteed_leading_0s == curr->possible_leading_0s); - assert(curr->possible_leading_0s >= 0); - - curr->assert_leading_info(); - - if ((direction == 0 && curr->guaranteed_leading_0s >= level) || - (curr->guaranteed_leading_0s == level-1 && - curr->leading_dir_valid_and_known() && - curr->leading_dir * direction > 0)) { - extracted.rel_body->simplified_DNF->add_conjunct(curr); - } - else { - remaining->add_conjunct(curr); - } - } - delete simplified_DNF; - simplified_DNF = remaining; - -#if ! defined NDEBUG - for (DNF_Iterator rc(simplified_DNF); rc; rc++) - (*rc)->assert_leading_info(); - - for (DNF_Iterator ec(extracted.rel_body->simplified_DNF); ec; ec++) - (*ec)->assert_leading_info(); -#endif - - finalize(); - extracted.finalize(); - return extracted; -} - -//Compress/uncompress functions - -bool Rel_Body::is_compressed() { -#if defined(INCLUDE_COMPRESSION) - if(is_simplified()) { - for(DNF_Iterator p(simplified_DNF); p.live(); p.next()) { - if(p.curr()->is_compressed()) - return true; - } - } - return false; -#else - return true; // This allows is_compressed assertions to work -#endif -} - -void Rel_Body::compress() { -#if !defined(INCLUDE_COMPRESSION) - return; -#else - if (status == compressed) - return; - if (pres_debug) - fprintf(DebugFile,">>> Compressing relation %p\n",this); - simplify(); - for(DNF_Iterator p(simplified_DNF); p.live(); p.next()) { - p.curr()->compress(); - status = compressed; - } -#endif -} - -void Rel_Body::uncompress() { -#if !defined(INCLUDE_COMPRESSION) - return; -#else - if (pres_debug) - fprintf(DebugFile,"<<< Uncompressing relation %p\n",this); - assert(is_simplified()); - for(DNF_Iterator p(simplified_DNF); p.live(); p.next()) { - p.curr()->uncompress(); - status = uncompressed; - } -#endif -} - -} diff --git a/omegalib/omega/src/RelVar.cc b/omegalib/omega/src/RelVar.cc deleted file mode 100644 index d9b977c..0000000 --- a/omegalib/omega/src/RelVar.cc +++ /dev/null @@ -1,71 +0,0 @@ -#include <omega/RelBody.h> -#include <omega/omega_i.h> - -namespace omega { - -Variable_ID Rel_Body::get_local(const Variable_ID v) { - Global_Var_ID g; - if (v->kind() == Global_Var) { - g = v->get_global_var(); - if (g->arity()) return get_local(g,v->function_of()); - return get_local(g); - } - if (is_set()) return set_var(v->get_position()); - if (v->kind() == Input_Var) return input_var(v->get_position()); - if (v->kind() == Output_Var) return output_var(v->get_position()); - assert(0 && "Can only get local for variable with global scope"); - exit(1); - return 0; -} - -// -// Find or declare global variable. -// If the VarID does not exist, it is created. Otherwise it's returned. -// Note that this version now works only for 0-ary functions. -// -Variable_ID Rel_Body::get_local(const Global_Var_ID G) { - assert(G->arity() == 0); - for(Variable_Iterator i(Symbolic); i; i++) - if ((*i)->get_global_var() == G) - return (*i); - - Variable_ID v = G->get_local(); - Symbolic.append(v); - return v; -} - - -Variable_ID Rel_Body::get_local(const Global_Var_ID G, Argument_Tuple of) { - assert(G->arity() == 0 || of == Input_Tuple || of == Output_Tuple); - - for(Variable_Iterator i = Symbolic; i; i++) - if ((*i)->get_global_var() == G && (G->arity() == 0 || - of == (*i)->function_of())) - return (*i); - - Variable_ID V = G->get_local(of); - Symbolic.append(V); - return V; -} - - -bool Rel_Body::has_local(const Global_Var_ID G) { - assert(G->arity() == 0); - for(Variable_Iterator i = Symbolic; i; i++) - if ((*i)->get_global_var() == G) - return true; - return false; -} - - -bool Rel_Body::has_local(const Global_Var_ID G, Argument_Tuple of) { - assert(G->arity() == 0 || of == Input_Tuple || of == Output_Tuple); - - for(Variable_Iterator i = Symbolic; i; i++) - if ((*i)->get_global_var() == G && (G->arity() == 0 || - of == (*i)->function_of())) - return true; - return false; -} - -} // namespace diff --git a/omegalib/omega/src/Relation.cc b/omegalib/omega/src/Relation.cc deleted file mode 100644 index 1cca43a..0000000 --- a/omegalib/omega/src/Relation.cc +++ /dev/null @@ -1,279 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - class Relation - - Notes: - - History: -*****************************************************************************/ - -#include <omega/Relation.h> -#include <omega/Relations.h> -#include <omega/pres_dnf.h> -#include <omega/pres_conj.h> -#include <omega/Rel_map.h> -#include <omega/omega_i.h> -#include <omega/omega_core/debugging.h> - -namespace omega { - -// copy function for Relation, will be removed in the future -// in favor of correct C++ copy constructor and const paramater passing -Relation copy(const Relation &t) { - Relation r = t; - return r; -} - -// -// Create null relation. -// -Relation::Relation() : rel_body(&null_rel) { - rel_body->ref_count = 1; -} - -Relation Relation::Null() { - return Relation(); -} - -bool Relation::is_null() const { - return(rel_body == &null_rel); -} - - -// -// Create a relation. Its will be built later. -// -Relation::Relation(int n_input, int n_output) { - rel_body = new Rel_Body(n_input,n_output); - rel_body->ref_count = 1; -} - -Relation::Relation(Rel_Body &r, int) { - rel_body = &r; - r.ref_count++; -} - -Relation Relation::Empty(const Relation &R) { - if (R.is_set()) return Relation(R.n_set()); - else return Relation(R.n_inp(),R.n_out()); -} - -// -// Create relation which is FALSE or TRUE. -// - -Relation Relation::True(const Relation &R) { - if (R.is_set()) return True(R.n_set()); - else return True(R.n_inp(),R.n_out()); -} - -Relation Relation::False(const Relation &R) { - if (R.is_set()) return False(R.n_set()); - else return False(R.n_inp(),R.n_out()); -} - -Relation Relation::Unknown(const Relation &R) { - if (R.is_set()) return Unknown(R.n_set()); - else return Unknown(R.n_inp(), R.n_out()); -} - - -Relation Relation::True(int setvars) { - Relation R(setvars); - R.add_and(); - R.finalize(); - return R; -} - -Relation Relation::True (int in, int out) { - Relation R(in,out); - R.add_and(); - R.finalize(); - return R; -} - -Relation Relation::False (int setvars) { - Relation R(setvars); - R.add_or(); - R.finalize(); - return R; -} - -Relation Relation::False (int in, int out) { - Relation R(in,out); - R.add_or(); - R.finalize(); - return R; -} - - -Relation Relation::Unknown (int setvars) { - Relation R(setvars); - R.add_and(); - R.finalize(); - R.simplify(); - Conjunct * c= R.single_conjunct(); - c->make_inexact(); - return R; -} - -Relation Relation::Unknown (int in, int out) { - Relation R(in,out); - R.add_and(); - R.finalize(); - R.simplify(); - Conjunct * c= R.single_conjunct(); - c->make_inexact(); - return R; -} - - -// -// Copy a relation. -// -Relation::Relation(const Relation &r) { -#if defined(INCLUDE_COMPRESSION) - assert(!r.is_compressed()); -#endif - if (r.is_finalized()) { - rel_body = r.rel_body; - rel_body->ref_count++; - } else { - assert(! r.rel_body->is_shared()); - // rel_body = new Rel_Body(r.rel_body); - rel_body = r.rel_body->clone(); - rel_body->ref_count = 1; - } -} - -// -// Copy relation r and replace formula in it with conjunct c. -// Wayne (TM) function. -// -Relation::Relation(const Relation &r, Conjunct *c) { - rel_body = new Rel_Body(r.rel_body, c); - rel_body->ref_count = 1; -} - - -// -// Assign a relation r to this relation. -// -Relation &Relation::operator=(const Relation &r) { -#if defined(INCLUDE_COMPRESSION) - assert (!r.is_compressed()); -#endif - - /* === Destroy this === */ - assert(rel_body->ref_count >= 1); - if(rel_body!=&null_rel && --(rel_body->ref_count)==0) { - delete rel_body; - } - - /* === Copy r to this === */ - if (r.is_finalized()) { - rel_body = r.rel_body; - rel_body->ref_count++; - } else { - assert(! r.rel_body->is_shared()); - // rel_body = new Rel_Body(r.rel_body); - rel_body = r.rel_body->clone(); - rel_body->ref_count = 1; - } - return *this; -} - -void Relation::copy_names(Rel_Body &r) { - int t; - for(t = 1; t <= r.n_inp(); t++) - name_input_var(t,r.input_var(t)->base_name); - for(t = 1; t <= r.n_out(); t++) - name_output_var(t,r.output_var(t)->base_name); -} - - -// Like makeSet (see Relations.c), but won't invert the relation -- -// fails if it has output instead of input variables. Called in Relation -// functions just after a MapRel, so that we know there are no outputs anyway. - -void Relation::markAsSet() { - assert(!is_null()); - assert(is_set() || (n_inp() >= 0 && n_out() == 0)); - if (!is_set()) split(); // split if we'll modify this - rel_body->_is_set = true; - invalidate_leading_info(); -} - -void Relation::markAsRelation() { - assert(!is_null()); - if (is_set()) split(); // split if we'll modify this - rel_body->_is_set = false; -} - - -Relation::~Relation() { - assert(rel_body->ref_count >= 1); - assert(this->is_null() == (rel_body == &null_rel)); - if(rel_body!=&null_rel && --(rel_body->ref_count)==0) { - if (rel_body == &null_rel) abort(); - delete rel_body; - } -} - - - -// -// One of the representatives using the body wants to be changed. -// Create a separate body for this rep not to damage other reps. -// Return address of the body. Old rep point to new body. -// -Rel_Body *Relation::split() { - assert(rel_body != &null_rel && "Error: Attempt to modify a null relation"); - assert (rel_body->ref_count >= 1); - if(!(rel_body==&null_rel || rel_body->ref_count==1)) { - if(pres_debug) { - fprintf(DebugFile, "+++ SPLIT relation +++\n"); - } - // Rel_Body *new_body = new Rel_Body(rel_body); - Rel_Body *new_body = rel_body->clone(); - new_body->ref_count = 1; - rel_body->ref_count--; - rel_body = new_body; - if(pres_debug>=2) { - fprintf(DebugFile, " copying 0x%p to give 0x%p\n", this, rel_body); - } - } - return (rel_body); -} - - -void Relation::dimensions(int & ndim_all, int &ndim_domain) { - ndim_all = ndim_domain = 0; - int a,d; - simplify(2,2); - for (DNF_Iterator s(query_DNF()); s.live(); s.next()) { - s.curr()->calculate_dimensions(*this, a, d); - if (a > ndim_all) ndim_all = a; - if (d > ndim_domain) ndim_domain = d; - } -} - -// Make a set: assert that it had only input or output variables, make it -// it have only input, set a flag. Called from domain, range, and difference, -// as well as functions that require a set as input. -void Relation::makeSet() { - assert(!is_null()); - // Assert that it is a set... - assert((n_inp() == 0 && n_out() >= 0) || (n_inp() >= 0 && n_out() == 0)); - - if ((n_inp() == 0 && n_out() != 0) || !is_set()) split(); // split if we'll modify this - if (n_inp() == 0 && n_out() != 0) //Inverse the relation - Inverse(*this); // Modifies "this"; also returns this but we ignore it - rel_body->_is_set = true; -} - -} // namespace diff --git a/omegalib/omega/src/Relations.cc b/omegalib/omega/src/Relations.cc deleted file mode 100644 index d7dbe86..0000000 --- a/omegalib/omega/src/Relations.cc +++ /dev/null @@ -1,2882 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Integer set and relation operations. - - Notes: - - History: - 04/22/09 merge_rels, Chun Chen -*****************************************************************************/ - -#include <omega/Relation.h> -#include <omega/Rel_map.h> -#include <omega/pres_tree.h> -#include <omega/pres_dnf.h> -#include <omega/pres_conj.h> -#include <omega/hull.h> -#include <basic/Tuple.h> -#include <basic/Map.h> -#include <basic/util.h> -#include <omega/omega_i.h> -#if defined STUDY_EVACUATIONS -#include <omega/evac.h> -#endif -#include <assert.h> - -namespace omega { - -#define CHECK_MAYBE_SUBSET 1 - -int relation_debug=0; - -namespace { - int leave_pufs_untouched = 0; - Variable_ID_Tuple exists_ids; - List<int> exists_numbers; - F_And * and_below_exists; -} - -/* The following allows us to avoid warnings about passing - temporaries as non-const references. This is useful but - has suddenly become illegal. */ - -Relation consume_and_regurgitate(NOT_CONST Relation &R) { - if(!R.is_null()) - ((Relation &) R).finalize(); - Relation S = (Relation &) R; - (Relation &) R = Relation::Null(); - return S; -} - - -// -// r1 Union r2. -// align the input tuples (if any) for F and G -// align the output tuples (if any) for F and G -// match named variables in F and G -// formula is f | g -// -Relation Union(NOT_CONST Relation &input_r1, - NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - if (r1.is_null()) - return r2; - else if (r2.is_null()) - return r1; - if (r1.n_inp() != r2.n_inp() || r1.n_out() != r2.n_out()) - throw std::invalid_argument("relation arity does not match"); - - // skip_set_checks++; - // assert(r1.n_inp() == r2.n_inp()); - // assert(r1.n_out() == r2.n_out()); - // assert(!r1.is_null() && !r2.is_null()); - int in = r1.n_inp(), out = r1.n_out(); - // skip_set_checks--; - - return MapAndCombineRel2(r1, r2, Mapping::Identity(in, out), - Mapping::Identity(in,out), Comb_Or); -} - - -// -// F intersection G -// align the input tuples (if any) for F and G -// align the output tuples (if any) for F and G -// match named variables in F and G -// formula is f & g -// -Relation Intersection(NOT_CONST Relation &input_r1, - NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - if (r1.is_null()) - return r2; - else if (r2.is_null()) - return r1; - if (r1.n_inp() != r2.n_inp() || r1.n_out() != r2.n_out()) - throw std::invalid_argument("relation arity does not match"); - - // skip_set_checks++; - // assert(r1.n_inp() == r2.n_inp()); - // assert(r1.n_out() == r2.n_out()); - // assert(!r1.is_null() && !r2.is_null()); - int in = r1.n_inp(), out = r1.n_out(); - // skip_set_checks--; - - return MapAndCombineRel2(r1, r2, Mapping::Identity(in,out), - Mapping::Identity(in,out), Comb_And); -} - - -// -// F \ G (the relation F restricted to domain G) -// align the input tuples for F and G -// match named variables in F and G -// formula is f & g -// -Relation Restrict_Domain(NOT_CONST Relation &input_r1, - NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - if (r1.is_null()) - return r1; - else if (r2.is_null()) - return r1; - if (r1.n_inp() != r2.n_set()) - throw std::invalid_argument("relation arity does not match"); - - // assert(!r1.is_null() && !r2.is_null()); - // skip_set_checks++; - // assert(r1.n_inp() == r2.n_set()); - // assert(r2.is_set()); - int in = r1.n_inp(), out = r1.n_out(); - // skip_set_checks--; - - int i; - Mapping m2(r2.n_set()); - for(i=1; i<=r2.n_set(); i++) m2.set_map_set(i, Input_Var,i); - - // skip_set_checks++; - assert(r2.query_guaranteed_leading_0s() == -1 && - r2.query_possible_leading_0s() == -1); - // skip_set_checks--; - - Relation result = MapAndCombineRel2(r1, r2, Mapping::Identity(in,out), - m2, Comb_And); - // FERD -- update leading 0's - the may close up? - //result.invalidate_leading_info(); // could do better - return result; -} - -// -// -// F / G (the relation F restricted to range G) -// align the output tuples for F and G -// match named variables in F and G -// formula is f & g -// -Relation Restrict_Range(NOT_CONST Relation &input_r1, - NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - if (r1.is_null()) - return r1; - else if (r2.is_null()) - return r1; - if (r1.n_out() != r2.n_set()) - throw std::invalid_argument("relation arity does not match"); - - // skip_set_checks++; - // assert(r1.n_out() == r2.n_set()); - // assert(r2.is_set()); - // assert(!r1.is_null() && !r2.is_null()); - int in = r1.n_inp(), out = r1.n_out(); - // skip_set_checks--; - - int i; - Mapping m2(r2.n_set()); - for(i=1; i<=r2.n_set(); i++) m2.set_map_set(i, Output_Var,i); - - // skip_set_checks++; - assert(r2.query_guaranteed_leading_0s() == -1 && - r2.query_possible_leading_0s() == -1); - // skip_set_checks--; - - Relation result = MapAndCombineRel2(r1, r2, Mapping::Identity(in, out), - m2, Comb_And); - // FERD -- update leading 0's - the may close up? - // result.invalidate_leading_info(); // could do better - return result; -} - - -// -// Add input variable to relation. -// -Relation Extend_Domain(NOT_CONST Relation &S) { - Relation R = consume_and_regurgitate(S); - if (R.is_null()) - throw std::invalid_argument("cannot extend domain on null relation"); - - // assert(!R.is_null() && (skip_set_checks || !R.is_set())); - // assert(!R.is_null()); - Rel_Body *r = R.split(); - r->In_Names.append(Const_String()); - r->number_input++; - assert(!r->is_null()); - - if (r->number_input <= r->number_output) - R.invalidate_leading_info(r->number_input); - - return R; -} - -// -// Add more input variables to relation. -// -Relation Extend_Domain(NOT_CONST Relation &S, int more) { - Relation R = consume_and_regurgitate(S); - if (R.is_null()) - throw std::invalid_argument("cannot extend domain on null relation"); - - // assert(!R.is_null()); - R.split(); - for (int i=1; i<=more; i++) R = Extend_Domain(R); - return R; -} - - -// -// Add output variable to relation. -// -Relation Extend_Range(NOT_CONST Relation &S) { - Relation R = consume_and_regurgitate(S); - if (R.is_null()) - throw std::invalid_argument("cannot extend range on null relation"); - - // assert(!R.is_null() && !R.is_set()); - // assert(!R.is_null()); - Rel_Body *r = R.split(); - r->Out_Names.append(Const_String()); - r->number_output++; - assert(!r->is_null()); - - if (r->number_output <= r->number_input) - R.invalidate_leading_info(r->number_output); - - return R; -} - -// -// Add more output variables to relation. -// -Relation Extend_Range(NOT_CONST Relation &S, int more) { - Relation R = consume_and_regurgitate(S); - - // assert(!R.is_null()); - R.split(); - for (int i=1; i<=more; i++) R = Extend_Range(R); - return R; -} - - -// -// Add set variable to set. -// -Relation Extend_Set(NOT_CONST Relation &S) { - Relation R = consume_and_regurgitate(S); - if (R.is_null()) - throw std::invalid_argument("cannot extend set on null relation"); - if (R.n_out() > 0) - throw std::invalid_argument("relation must be a set"); - - // assert(!R.is_null() && R.is_set()); - Rel_Body *r = R.split(); - r->In_Names.append(Const_String()); - r->number_input++; - assert(!r->is_null()); - return R; -} - -// -// Add more variables to set -// -Relation Extend_Set(NOT_CONST Relation &S, int more) { - Relation R = consume_and_regurgitate(S); - R.split(); - for (int i=1; i<=more; i++) R = Extend_Set(R); - return R; -} - - - -// -// Domain and Range. -// Make output (input) variables wildcards and simplify. -// Move all UFS's to have have the remaining tuple as an argument, -// and maprel will move them to the set tuple -// RESET all leading 0's -// -Relation Domain(NOT_CONST Relation &S) { - Relation r = consume_and_regurgitate(S); - if (r.is_null()) - return r; - - // assert(!S.is_null()); - // assert(!r.is_set()); - // skip_set_checks++; - int i; - Mapping m1(r.n_inp(), r.n_out()); - for(i=1; i<=r.n_inp(); i++) m1.set_map_in (i, Set_Var,i); - for(i=1; i<=r.n_out(); i++) m1.set_map_out(i, Exists_Var,i); - // skip_set_checks--; - - int a = r.max_ufs_arity_of_out(); - if (a > 0) { - // UFS's must evacuate from the output tuple - Variable_ID_Tuple remapped; - - r.simplify(); - DNF *d = r.split()->DNFize(); - d->count_leading_0s(); - // Any conjucts with leading_0s == -1 must have >= "a" leading 0s - // What a gross way to do this. Ferd - - for (DNF_Iterator conj(d); conj; conj++) { -#if defined STUDY_EVACUATIONS - study_evacuation(*conj, out_to_in, a); -#endif - - int cL0 = (*conj)->guaranteed_leading_0s; - - for (Variable_ID_Iterator func((*conj)->mappedVars); func; func++) - if ((*func)->kind() == Global_Var) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() > 0 && (*func)->function_of()==Output_Tuple) { - if (cL0 >= f->arity()) { - (*func)->remap = r.get_local(f, Input_Tuple); - } - else { - (*func)->remap = (*conj)->declare(); - (*conj)->make_inexact(); - } - remapped.append(*func); - } - } - (*conj)->remap(); - reset_remap_field(remapped); - remapped.clear(); - - (*conj)->guaranteed_leading_0s = (*conj)->possible_leading_0s = -1; - (*conj)->leading_dir = 0; - } - } - - MapRel1(r, m1, Comb_Id); // this invalidates leading0s - assert(r.is_set() || m1.n_in() == 0); // MapRel can't tell to make a set - r.markAsSet(); // if there were no inputs. - - // skip_set_checks++; - assert(r.query_guaranteed_leading_0s() == -1 && r.query_possible_leading_0s() == -1); - // skip_set_checks--; - - return r; -} - - -Relation Range(NOT_CONST Relation &S) { - Relation r = consume_and_regurgitate(S); - if (r.is_null()) - return r; - - //assert(!r.is_null()); - // skip_set_checks++; - - int i; - Mapping m1(r.n_inp(), r.n_out()); - for(i=1; i<=r.n_inp(); i++) m1.set_map_in (i, Exists_Var,i); - for(i=1; i<=r.n_out(); i++) m1.set_map_out(i, Set_Var,i); - // skip_set_checks--; - - int a = r.max_ufs_arity_of_in(); - if (a > 0) { - // UFS's must evacuate from the input tuple - Variable_ID_Tuple remapped; - - r.simplify(); - DNF *d = r.split()->DNFize(); - d->count_leading_0s(); - // Any conjucts with leading_0s == -1 must have >= "a" leading 0s - // What a gross way to do this. Ferd - - for (DNF_Iterator conj(d); conj; conj++) { -#if defined STUDY_EVACUATIONS - study_evacuation(*conj, in_to_out, a); -#endif - - int cL0 = (*conj)->guaranteed_leading_0s; - for (Variable_ID_Iterator func((*conj)->mappedVars); func; func++) - if ((*func)->kind() == Global_Var) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() > 0 && (*func)->function_of()==Input_Tuple) { - if (cL0 >= f->arity()) { - (*func)->remap = r.get_local(f, Output_Tuple); - } - else { - (*func)->remap = (*conj)->declare(); - (*conj)->make_inexact(); - } - remapped.append(*func); - } - } - (*conj)->remap(); - reset_remap_field(remapped); - remapped.clear(); - - (*conj)->guaranteed_leading_0s = (*conj)->possible_leading_0s = -1; - (*conj)->leading_dir = 0; - } - } - - MapRel1(r, m1, Comb_Id); // this invalidates leading0s - assert(r.is_set() || m1.n_out() == 0); // MapRel can't tell to make a set - r.markAsSet(); // if there were no outputs. - - // skip_set_checks++; - assert(r.query_guaranteed_leading_0s() == -1 && r.query_possible_leading_0s() == -1); - // skip_set_checks--; - - return r; -} - - -// -// Cross Product. Give two sets, A and B, create a relation whose -// domain is A and whose range is B. -// -Relation Cross_Product(NOT_CONST Relation &input_A, - NOT_CONST Relation &input_B) { - Relation A = consume_and_regurgitate(input_A); - Relation B = consume_and_regurgitate(input_B); - if (A.is_null() || B.is_null()) - throw std::invalid_argument("null relation"); - if (!A.is_set() || !B.is_set()) - throw std::invalid_argument("cross product must be on two set"); - - // assert(A.is_set()); - // assert(B.is_set()); - - // skip_set_checks++; - assert(A.query_guaranteed_leading_0s() == -1 && - A.query_possible_leading_0s() == -1); - assert(B.query_guaranteed_leading_0s() == -1 && - B.query_possible_leading_0s() == -1); - // skip_set_checks--; - - Mapping mA(A.n_set()); - Mapping mB(B.n_set()); - int i; - for(i = 1; i <= B.n_set(); i++) mB.set_map_set(i, Output_Var,i); - for(i = 1; i <= A.n_set(); i++) mA.set_map_set(i, Input_Var,i); - return MapAndCombineRel2(A, B, mA, mB, Comb_And); -} - - -// -// inverse F -// reverse the input and output tuples -// -Relation Inverse(NOT_CONST Relation &S) { - Relation r = consume_and_regurgitate(S); - if (r.is_null()) - return r; - - // assert(!r.is_null()); - // assert(!r.is_set()); - int i; - - Mapping m1(r.n_inp(), r.n_out()); - for(i=1; i<=r.n_inp(); i++) m1.set_map_in (i, Output_Var,i); - for(i=1; i<=r.n_out(); i++) m1.set_map_out(i, Input_Var,i); - - MapRel1(r, m1, Comb_Id, -1, -1, false); - - r.reverse_leading_dir_info(); - - return r; -} - -Relation After(NOT_CONST Relation &input_S, - int carried_by, int new_output,int dir) { - Relation S = consume_and_regurgitate(input_S); - assert(!S.is_null()); - assert(!S.is_set()); - int i; - Relation r(*S.split(),42); - - int a = r.max_ufs_arity_of_out(); - int preserved_positions = min(carried_by-1,new_output); - if (a >= preserved_positions) { - // UFS's must evacuate from the output tuple - Variable_ID_Tuple remapped; - - r.simplify(); - DNF *d = r.split()->DNFize(); - d->count_leading_0s(); - // Any conjucts with leading_0s == -1 must have >= "a" leading 0s - // What a gross way to do this. Ferd - - for (DNF_Iterator conj(d); conj; conj++) { - int cL0 = (*conj)->guaranteed_leading_0s; - - for (Variable_ID_Iterator func((*conj)->mappedVars); func; func++) - if ((*func)->kind() == Global_Var) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() > preserved_positions - && (*func)->function_of()==Output_Tuple) { - if (cL0 >= f->arity()) { - (*func)->remap = r.get_local(f, Input_Tuple); - } - else { - (*func)->remap = (*conj)->declare(); - (*conj)->make_inexact(); - } - remapped.append(*func); - } - } - (*conj)->remap(); - reset_remap_field(remapped); - remapped.clear(); - - (*conj)->guaranteed_leading_0s = - (*conj)->possible_leading_0s = -1; - (*conj)->leading_dir = 0; - } - } - - Mapping m1(r.n_inp(), r.n_out()); - for(i=1; i<=r.n_inp(); i++) m1.set_map_in (i, Input_Var,i); - if (carried_by > new_output) { - int preserve = min(new_output,r.n_out()); - for(i=1; i<=preserve; i++) m1.set_map_out(i, Output_Var,i); - for(i=preserve+1; i<=r.n_out(); i++) m1.set_map_out(i, Exists_Var,-1); - MapRel1(r, m1, Comb_Id, -1, -1, true); - if (new_output > preserve) - r = Extend_Range(r,new_output-r.n_out()); - return r; - } - - for(i=1; i<carried_by; i++) m1.set_map_out(i, Output_Var,i); - m1.set_map_out(carried_by, Exists_Var,1); - for(i=carried_by+1; i<=r.n_out(); i++) m1.set_map_out(i, Exists_Var,-1); - - MapRel1(r, m1, Comb_Id, -1, -1, true,false); - - Rel_Body *body = r.split(); - body->Out_Names.append(Const_String()); - body->number_output++; - assert(body->n_out() <= input_vars.size()); - - - GEQ_Handle h = and_below_exists->add_GEQ(0); - assert(carried_by < 128); - h.update_coef(exists_ids[1],-dir); - h.update_coef(r.output_var(carried_by),dir); - h.update_const(-1); - h.finalize(); - r.finalize(); - if (new_output > r.n_out()) - r = Extend_Range(r,new_output-r.n_out()); - return r; -} - -// -// Identity. -// -Relation Identity(int n_inp) { - Relation rr(n_inp, n_inp); - F_And *f = rr.add_and(); - for(int i=1; i<=n_inp; i++) { - EQ_Handle e = f->add_EQ(); - e.update_coef(rr.input_var(i), -1); - e.update_coef(rr.output_var(i), 1); - e.finalize(); - } - rr.finalize(); - assert(!rr.is_null()); - return rr; -} - -Relation Identity(NOT_CONST Relation &input_r) { - Relation r = consume_and_regurgitate(input_r); - return Restrict_Domain(Identity(r.n_set()),r); -} - -// -// Deltas(F) -// Return a set such that the ith variable is old Out_i - In_i -// Delta variables are created as input variables. -// Then input and output variables are projected out. -// -Relation Deltas(NOT_CONST Relation &S) { - Relation R = consume_and_regurgitate(S); - assert(!R.is_null()); - // skip_set_checks++; - assert(R.n_inp()==R.n_out()); - int in = R.n_inp(); - // skip_set_checks--; - return Deltas(R,in); -} - -Relation Deltas(NOT_CONST Relation &S, int eq_no) { - Relation R = consume_and_regurgitate(S); - // skip_set_checks++; - assert(!R.is_null()); - assert(eq_no<=R.n_inp()); - assert(eq_no<=R.n_out()); - // R.split(); - - int no_inp = R.n_inp(); - int no_out = R.n_out(); - - if(relation_debug) { - fprintf(DebugFile,"Computing Deltas:\n"); - R.prefix_print(DebugFile); - } - int a = R.max_ufs_arity(); - if (a > 0) { - Variable_ID_Tuple remapped; - - // UFS's must evacuate from all tuples - we need to go to DNF - // to enumerate the variables, I think... - R.simplify(); - if(relation_debug) { - fprintf(DebugFile,"Relation simplified:\n"); - R.prefix_print(DebugFile); - } - DNF *d = R.split()->DNFize(); - - for (DNF_Iterator conj(d); conj; conj++) { - for (Variable_ID_Iterator func((*conj)->mappedVars); func; func++) - if ((*func)->kind() == Global_Var) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() > 0) { - (*func)->remap = (*conj)->declare(); - (*conj)->make_inexact(); - remapped.append(*func); - } - } - (*conj)->remap(); - reset_remap_field(remapped); - remapped.clear(); - } - } - - R = Extend_Domain(R, eq_no); // add eq_no Delta vars - Mapping M(no_inp+eq_no, no_out); - int i; - for(i=1; i<=eq_no; i++) { // Set up Deltas equalities - EQ_Handle E = R.and_with_EQ(); - /* delta_i - w_i + r_i = 0 */ - E.update_coef(R.input_var(i), 1); - E.update_coef(R.output_var(i), -1); - E.update_coef(R.input_var(no_inp+i), 1); - E.finalize(); - M.set_map(Input_Var, no_inp+i, Set_Var, i); // Result will be a set - } - for(i=1; i<=no_inp; i++) { // project out input variables - M.set_map(Input_Var, i, Exists_Var, i); - } - for(i=1; i<=no_out; i++) { // project out output variables - M.set_map(Output_Var, i, Exists_Var, no_inp+i); - } - MapRel1(R, M, Comb_Id, eq_no, 0); - - if(relation_debug) { - fprintf(DebugFile,"Computing deltas:\n"); - R.prefix_print(DebugFile); - }; - R.finalize(); - assert(R.is_set()); // Should be since we map things to Set_Var - assert(R.n_set() == eq_no); - // skip_set_checks--; - return R; -} - - - - -Relation DeltasToRelation(NOT_CONST Relation &D, int n_inputs, int n_outputs) { - Relation R = consume_and_regurgitate(D); - - // skip_set_checks++; - assert(!R.is_null()); - R.markAsRelation(); - int common = R.n_inp(); - assert(common <= n_inputs); - assert(common <= n_outputs); - R.split(); - - if (R.max_ufs_arity() > 0) { - assert(R.max_ufs_arity() == 0 && - "'Deltas' not ready for UFS yet"); // FERD - fprintf(stderr, "'Deltas' not ready for UFS yet"); - exit(1); - } - - R = Extend_Domain(R, n_inputs); - R = Extend_Range(R, n_outputs); - Mapping M(common+n_inputs, n_outputs); - int i; - for(i=1; i<=common; i++) { // Set up Deltas equalities - EQ_Handle E = R.and_with_EQ(); - /* delta_i - w_i + r_i = 0 */ - E.update_coef(R.input_var(i), 1); - E.update_coef(R.output_var(i), -1); - E.update_coef(R.input_var(common+i), 1); - E.finalize(); - M.set_map(Input_Var, i, Exists_Var, i); // Result will be a set - } - for(i=1; i<=n_inputs; i++) { // project out input variables - M.set_map(Input_Var, common+i, Input_Var, i); - } - for(i=1; i<=n_outputs; i++) { // project out output variables - M.set_map(Output_Var, i, Output_Var, i); - } - MapRel1(R, M, Comb_Id, n_inputs, n_outputs); - - if(relation_debug) { - fprintf(DebugFile,"Computed DeltasToRelation:\n"); - R.prefix_print(DebugFile); - } - R.finalize(); - assert(!R.is_set()); - // skip_set_checks--; - return R; -} - - - -Relation Join(NOT_CONST Relation &G, NOT_CONST Relation &F) { - return Composition(F, G); -} - -bool prepare_relations_for_composition(Relation &r1,Relation &r2) { - assert(!r2.is_null() && !r1.is_null()); - - if(r2.is_set()) { - int a1 = r1.max_ufs_arity_of_in(), a2 = r2.max_ufs_arity_of_set(); - - if (a1 == 0 && a2 == 0) - return true; - else { - assert(0 && "Can't compose relation and set with function symbols"); - fprintf(stderr, "Can't compose relation and set with function symbols"); - exit(1); - return false; // make compiler shut up - } - } - - assert(r2.n_out() == r1.n_inp()); - - int zeros = max(r1.query_guaranteed_leading_0s(), - r2.query_guaranteed_leading_0s()); - return (zeros >= r1.max_ufs_arity_of_in() - && zeros >= r2.max_ufs_arity_of_out()); -} - -// -// Composition(F, G) = F o G, where F o G (x) = F(G(x)) -// That is, if F = { [i] -> [j] : ... } -// and G = { [x] -> [y] : ... } -// then Composition(F, G) = { [x] -> [j] : ... } -// -// align the output tuple for G and the input tuple for F, -// these become existensially quantified variables -// use the output tuple from F and the input tuple from G for the result -// match named variables in G and F -// formula is g & f -// -// If there are function symbols of arity > 0, we call special case -// code to handle them. This is not set up for the r2.is_set case yet. -// - -Relation Composition(NOT_CONST Relation &input_r1, NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - assert(!r2.is_null() && !r1.is_null()); - - if(r2.is_set()) { - int a1 = r1.max_ufs_arity_of_in(), a2 = r2.max_ufs_arity_of_set(); - if (r2.n_set() != r1.n_inp()) { - fprintf(stderr,"Illegal composition/application, arities don't match\n"); - fprintf(stderr,"Trying to compute r1(r2)\n"); - fprintf(stderr,"arity of r2 must match input arity of r1\n"); - fprintf(stderr,"r1: "); - r1.print_with_subs(stderr); - fprintf(stderr,"r2: "); - r2.print_with_subs(stderr); - fprintf(stderr,"\n"); - assert(r2.n_set() == r1.n_inp()); - exit(1); - } - // skip_set_checks++; - int i; - if (a1 == 0 && a2 == 0) { - int x = r1.n_out(); - Mapping m1(r1.n_inp(), r1.n_out()); - for(i=1; i<=r1.n_out(); i++) m1.set_map_out(i, Set_Var,i); - for(i=1; i<=r1.n_inp(); i++) m1.set_map_in (i, Exists_Var,i); - Mapping m2(r2.n_set()); - for(i=1; i<=r2.n_set(); i++) m2.set_map_set(i, Exists_Var,i); - Relation R3 = MapAndCombineRel2(r2, r1, m2, m1, Comb_And); - // skip_set_checks--; - if (x == 0) - R3.markAsSet(); - return R3; - } - else { - assert(0 && - "Can't compose relation and set with function symbols"); - fprintf(stderr, - "Can't compose relation and set with function symbols"); - exit(1); - return Identity(0); // make compiler shut up - } - } - - if (r2.n_out() != r1.n_inp()) { - fprintf(stderr,"Illegal composition, arities don't match\n"); - fprintf(stderr,"Trying to compute r1 compose r2\n"); - fprintf(stderr,"Output arity of r2 must match input arity of r1\n"); - fprintf(stderr,"r1: "); - r1.print_with_subs(stderr); - fprintf(stderr,"r2: "); - r2.print_with_subs(stderr); - fprintf(stderr,"\n"); - assert(r2.n_out() == r1.n_inp()); - exit(1); - } - - int a1 = r1.max_ufs_arity_of_in(), a2 = r2.max_ufs_arity_of_out(); - - if (a1 == 0 && a2 == 0 && 0 /* FERD - leading 0's go wrong here */ ) { - // If no real UFS's, we can just use the general code: - int i; - Mapping m1(r1.n_inp(), r1.n_out()); - for(i=1; i<=r1.n_inp(); i++) m1.set_map_in (i, Exists_Var,i); - for(i=1; i<=r1.n_out(); i++) m1.set_map_out(i, Output_Var,i); - Mapping m2(r2.n_inp(), r2.n_out()); - for(i=1; i<=r2.n_inp(); i++) m2.set_map_in (i, Input_Var,i); - for(i=1; i<=r2.n_out(); i++) m2.set_map_out(i, Exists_Var,i); - - return MapAndCombineRel2(r2, r1, m2, m1, Comb_And); - } - else { - Relation result(r2.n_inp(), r1.n_out()); - int mid_size = r2.n_out(); - int i; - for(i =1; i<=r2.n_inp(); i++) - result.name_input_var(i,r2.input_var(i)->base_name); - for(i =1; i<=r1.n_out(); i++) - result.name_output_var(i,r1.output_var(i)->base_name); - - r1.simplify(); - r2.simplify(); - - Rel_Body *b1 = r1.split(), *b2 = r2.split(); - - if (b1 == b2) { - assert(0 && "Compose: not ready to handle b1 == b2 yet."); - fprintf(stderr, "Compose: not ready to handle b1 == b2 yet.\n"); - exit(1); - } - - DNF *d1 = b1->DNFize(); - DNF *d2 = b2->DNFize(); - - d1->count_leading_0s(); - d2->count_leading_0s(); - // Any conjucts with leading_0s == -1 must have >= max_arity leading 0s - // What a gross way to do this. Ferd - - F_Exists *exists = result.add_exists(); - Section<Variable_ID> middle_tuple = exists->declare_tuple(mid_size); - Map<Global_Var_ID, Variable_ID> lost_functions((Variable_ID)0); - - F_Or *result_conjs = exists->add_or(); - - for (DNF_Iterator conj1(d1); conj1; conj1++) - for (DNF_Iterator conj2(d2); conj2; conj2++) { - // combine conj1 and conj2: - // conj2's in becomes result's in; conj1's out becomes out - // conj2's out and conj1's in get merged and exist. quant. - // conj2's f(in) and conj1's f(out) become f(in) and f(out) - // conj2's f(out) and conj1's f(in) get merged, evacuate: - // if conj1 has f.arity leading 0s, they become f(out), - // if conj2 has f.arity leading 0s, they become f(in) - // if neither has enough 0s, they become a wildcard - // and the result is inexact - // old wildcards stay wildcards - -#if defined STUDY_EVACUATIONS - study_evacuation(*conj1, *conj2, max(a1, a2)); -#endif - - Conjunct *copy1, *copy2; - copy2 = (*conj2)->copy_conj_same_relation(); - copy1 = (*conj1)->copy_conj_same_relation(); - - Variable_ID_Tuple remapped; - - int c1L0 = copy1->guaranteed_leading_0s; - int c2L0 = copy2->guaranteed_leading_0s; - - int inexact = 0; - - // get rid of conj2's f(out) - { - for (Variable_ID_Iterator func(copy2->mappedVars); func; func++) - if ((*func)->kind() == Global_Var) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() > 0 && (*func)->function_of()==Output_Tuple) { - if (c2L0 >= f->arity()) { - (*func)->remap = r2.get_local(f, Input_Tuple); - remapped.append(*func); - } - else if (c1L0 >= f->arity()) { - // f->remap = copy1->get_local(f, Output_Tuple); - // this should work with the current impl. - // SHOULD BE A NO-OP? - assert((*func)==r1.get_local(f,Output_Tuple)); - } - else { - Variable_ID f_quantified = lost_functions[f]; - if (!f_quantified) { - f_quantified = exists->declare(); - lost_functions[f] = f_quantified; - } - inexact = 1; - (*func)->remap = f_quantified; - remapped.append(*func); - } - } - } - } - - // remap copy2's out - for (i=1; i<=mid_size; i++) { - r2.output_var(i)->remap = middle_tuple[i]; - } - - // do remapping for conj2, then reset everything so - // we can go on with conj1 - - copy2->remap(); - reset_remap_field(remapped); - reset_remap_field(output_vars,mid_size); - - - remapped.clear(); - - // get rid of conj1's f(in) - { - for (Variable_ID_Iterator func(copy1->mappedVars); func; func++) - if ((*func)->kind() == Global_Var) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() > 0 && (*func)->function_of()==Input_Tuple) { - if (c1L0 >= f->arity()) { - (*func)->remap = r1.get_local(f,Output_Tuple); - remapped.append(*func); - } - else if (c2L0 >= f->arity()) { - // f->remap = copy2->get_local(f, Input_Tuple); - // this should work with the current impl. - // SHOULD BE A NO-OP? - assert((*func)==r2.get_local(f,Input_Tuple)); - } - else { - Variable_ID f_quantified = lost_functions[f]; - if (!f_quantified) { - f_quantified = exists->declare(); - lost_functions[f] = f_quantified; - } - inexact = 1; - (*func)->remap = f_quantified; - remapped.append(*func); - } - } - } - } - - // merge copy1's in with the already remapped copy2's out - for (i=1; i<=mid_size; i++) { - r1.input_var(i)->remap = middle_tuple[i]; - } - - copy1->remap(); - reset_remap_field(remapped); - reset_remap_field(input_vars,mid_size); - - Conjunct *conj3 = merge_conjs(copy1, copy2, MERGE_COMPOSE, exists->relation()); - result_conjs->add_child(conj3); - delete copy1; - delete copy2; - - // make sure all variables used in the conjunct - // are listed in the "result" relation - - for (Variable_ID_Iterator func(conj3->mappedVars); func; func++) - if ((*func)->kind() == Global_Var) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() > 0) - result.get_local(f, (*func)->function_of()); - else - result.get_local(f); - } - - if (inexact) - conj3->make_inexact(); - } - - // result.simplify(2, 4); // can't really do that now, will cause failure in chill - result.finalize(); - r1 = r2 = Relation(); - return result; - } -} - - - -bool Is_Obvious_Subset(NOT_CONST Relation &input_r1, NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - - assert(!r1.is_null() && !r2.is_null()); - Rel_Body *rr1 = r1.split(); - Rel_Body *rr2 = r2.split(); - rr1->simplify(); - rr2->simplify(); - use_ugly_names++; - - remap_DNF_vars(rr2, rr1); - - for(DNF_Iterator pd1(rr1->query_DNF()); pd1.live(); pd1.next()) { - Conjunct *conj1 = pd1.curr(); - int found = false; - for(DNF_Iterator pd2(rr2->query_DNF()); pd2.live(); pd2.next()) { - Conjunct *conj2 = pd2.curr(); - if (!conj2->is_exact()) continue; - - Conjunct *cgist = merge_conjs(conj1, conj2, MERGE_GIST, conj2->relation()); -#ifndef NDEBUG - cgist->setup_names(); -#endif - if (cgist->redSimplifyProblem(2, 0) == noRed) { - delete cgist; - found = true; - break; - } - delete cgist; - } - if (! found) { - use_ugly_names--; - r1 = r2 = Relation(); - return false; - } - } - use_ugly_names--; - r1 = r2 = Relation(); - return true; -} /* Is_Obvious_Subset */ - - -bool do_subset_check(NOT_CONST Relation &input_r1, - NOT_CONST Relation &input_r2); - -// do_subset_check really implements Must_Be_Subset anyway (due to -// correct handling of inexactness in the negation code), but -// still take upper and lower bounds here -bool Must_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2) { - Relation s1 = Upper_Bound(consume_and_regurgitate(r1)); - Relation s2 = Lower_Bound(consume_and_regurgitate(r2)); - return do_subset_check(s1,s2); -} - -bool Might_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2) { - Relation s1 = Lower_Bound(consume_and_regurgitate(r1)); - Relation s2 = Upper_Bound(consume_and_regurgitate(r2)); - return do_subset_check(s1,s2); -} - -bool May_Be_Subset(NOT_CONST Relation &r1, NOT_CONST Relation &r2){ - return Might_Be_Subset(r1,r2); -} - - - - -// -// F Must_Be_Subset G -// Test that (f => g) === (~f | g) is a Tautology -// or that (f & ~g) is unsatisfiable: -// align the input tuples (if any) for F and G -// align the output tuples (if any) for F and G -// Special case: if r2 has a single conjunct then use HasRedQeuations. -// - -bool do_subset_check(NOT_CONST Relation &input_r1, - NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - if (r1.is_null() || r2.is_null()) - throw std::invalid_argument("null relation"); - if (r1.n_inp() != r2.n_inp() || r1.n_out() != r2.n_out()) - throw std::invalid_argument("relation arity does not match"); - - // assert(!r1.is_null() && !r2.is_null()); - // skip_set_checks++; - // assert(r1.n_inp() == r2.n_inp()); - // assert(r1.n_out() == r2.n_out()); - // skip_set_checks--; - r1.simplify(1,0); - r2.simplify(2,2); - Rel_Body *rr1 = r1.split(); - - if(relation_debug) { - fprintf(DebugFile, "\n$$$ Must_Be_Subset IN $$$\n"); - } - - bool c = true; - - // Check each conjunct separately - for(DNF_Iterator pd(rr1->query_DNF()); c && pd.live(); ) { - Relation tmp(r1,pd.curr()); - pd.next(); -#ifndef CHECK_MAYBE_SUBSET - if (pd.live()) - c = !Difference(tmp,copy(r2)).is_upper_bound_satisfiable(); - else - c = !Difference(tmp,r2).is_upper_bound_satisfiable(); -#else - Relation d=Difference(copy(tmp), copy(r2)); - c=!d.is_upper_bound_satisfiable(); - if (!c && !d.is_exact()) { // negation-induced inexactness - static int OMEGA_WHINGE = -1; - if (OMEGA_WHINGE < 0) { - OMEGA_WHINGE = getenv("OMEGA_WHINGE") ? atoi(getenv("OMEGA_WHINGE")) : 0; - } - if (OMEGA_WHINGE) { - fprintf(DebugFile,"\n===== r1 is maybe a Must_Be_Subset of r2 ========\n"); - fprintf(DebugFile,"-------> r1:\n"); - tmp.print_with_subs(DebugFile); - fprintf(DebugFile,"-------> r2:\n"); - r2.print_with_subs(DebugFile); - fprintf(DebugFile,"-------> r1-r2:\n"); - d.print_with_subs(DebugFile); - } - } -#endif - } - - if(relation_debug) { - fprintf(DebugFile, "$$$ Must_Be_Subset OUT $$$\n"); - } - r1 = r2 = Relation(); - return c; -} - - -// -// F minus G -// -Relation Difference(NOT_CONST Relation &input_r1, - NOT_CONST Relation &input_r2) { - Relation r1 = consume_and_regurgitate(input_r1); - Relation r2 = consume_and_regurgitate(input_r2); - if (r1.is_null() || r2.is_null()) - return r1; - if (r1.n_inp() != r2.n_inp() || r1.n_out() != r2.n_out()) - throw std::invalid_argument("relation arity does not match"); - - //assert(!r1.is_null() && !r2.is_null()); - // skip_set_checks++; - // assert(r1.n_inp() == r2.n_inp()); - // assert(r1.n_out() == r2.n_out()); - - int i; - Mapping m1(r1.n_inp(), r1.n_out()); - for(i=1; i<=r1.n_inp(); i++) m1.set_map_in (i, Input_Var,i); - for(i=1; i<=r1.n_out(); i++) m1.set_map_out(i, Output_Var,i); - Mapping m2(r2.n_inp(), r2.n_out()); - for(i=1; i<=r2.n_inp(); i++) m2.set_map_in (i, Input_Var,i); - for(i=1; i<=r2.n_out(); i++) m2.set_map_out(i, Output_Var,i); - // skip_set_checks--; - - return MapAndCombineRel2(r1, r2, m1, m2, Comb_AndNot); -} - -// -// complement F -// not F -// -Relation Complement(NOT_CONST Relation &S) { - Relation r = consume_and_regurgitate(S); - if (r.is_null()) - return r; - - // assert(!r.is_null()); - // skip_set_checks++; - int i; - Mapping m(r.n_inp(), r.n_out()); - for(i=1; i<=r.n_inp(); i++) m.set_map_in (i, Input_Var,i); - for(i=1; i<=r.n_out(); i++) m.set_map_out(i, Output_Var,i); - // skip_set_checks--; - - MapRel1(r, m, Comb_AndNot, -1, -1, false); - return r; -} - - -// -// Compute (gist r1 given r2). -// Currently we assume that r2 has only one conjunct. -// r2 may have zero input and output OR may have # in/out vars equal to r1. -// -Relation GistSingleConjunct(NOT_CONST Relation &input_R1, - NOT_CONST Relation &input_R2, int effort) { - Relation R1 = consume_and_regurgitate(input_R1); - Relation R2 = consume_and_regurgitate(input_R2); - - // skip_set_checks++; - assert(!R1.is_null() && !R2.is_null()); - assert((R1.n_inp() == R2.n_inp() && R1.n_out() == R2.n_out()) || - (R2.n_inp() == 0 && R2.n_out() == 0)); - R1.simplify(); - R2.simplify(); - Rel_Body *r1 = R1.split(); - Rel_Body *r2 = R2.split(); - - if(relation_debug) { - fprintf(DebugFile, "\n### GIST computation start ### [\n"); - R1.prefix_print(DebugFile); - R2.prefix_print(DebugFile); - fprintf(DebugFile, "### ###\n"); - } - - -// The merged conjunct has to have the variables of either r1 or r2, but -// not both. Use r1's, since it'll be cheaper to remap r2's single conj. - remap_DNF_vars(r2, r1); - assert(r2->is_upper_bound_satisfiable() && "Gist: second operand is FALSE"); - // skip_set_checks--; - - Conjunct *known = r2->single_conjunct(); - assert(known != NULL && "Gist: second operand has more than 1 conjunct"); - - DNF *new_dnf = new DNF(); - for(DNF_Iterator pd(r1->simplified_DNF); pd.live(); pd.next()) { - Conjunct *conj = pd.curr(); - Conjunct *cgist = merge_conjs(known, conj, MERGE_GIST, conj->relation()); // Uses r1's vars - cgist->set_relation(r1); // Thinks it's part of r1 now, for var. purposes - if(simplify_conj(cgist, true, effort+1, EQ_RED)) { - /* Throw out black constraints, turn red constraints into black */ - cgist->rm_color_constrs(); - if(cgist->is_true()) { - delete new_dnf; - delete cgist; - // skip_set_checks++; - Relation retval = Relation::True(r1->n_inp(), r2->n_out()); - // retval.finalize(); - retval.simplify(); - if(R1.is_set() && R2.is_set()) retval.markAsSet(); - // skip_set_checks--; - return retval; - } - else { - // since modular equations might be changed, simplify again! - simplify_conj(cgist, true, effort+1, EQ_BLACK); - - new_dnf->add_conjunct(cgist); - } - } - } - delete r1->simplified_DNF; - r1->simplified_DNF = new_dnf; - assert(!r1->is_null()); - R1.finalize(); - if(relation_debug) { - fprintf(DebugFile, "] ### GIST computation end ###\n"); - R1.prefix_print(DebugFile); - fprintf(DebugFile, "### ###\n"); - } - return(R1); -} - - -// -// Compute gist r1 given r2. r2 can have multiple conjuncts, -// return result is always simplified. -// -Relation Gist(NOT_CONST Relation &input_R1, - NOT_CONST Relation &input_R2, int effort) { - Relation R1 = consume_and_regurgitate(input_R1); - Relation R2 = consume_and_regurgitate(input_R2); - if (R1.is_null()) - return R1; - // change the Gist semantics to allow r2 be null -- by chun 07/30/2007 - if (R2.is_null()) { - R1.simplify(); - return R1; - } - if (!(R1.n_inp() == 0 && R2.n_out() == 0) && - (R1.n_inp() != R2.n_inp() || R1.n_out() != R2.n_out())) - throw std::invalid_argument("relation arity does not match"); - - // skip_set_checks++; - // assert(!R1.is_null()); - // assert(R2.is_null() || - // (R1.n_inp() == R2.n_inp() && R1.n_out() == R2.n_out()) || - // (R2.n_inp() == 0 && R2.n_out() == 0)); - // skip_set_checks--; - R2.simplify(); - - if(relation_debug) { - fprintf(DebugFile, "\n### multi-GIST computation start ### [\n"); - R1.prefix_print(DebugFile); - R2.prefix_print(DebugFile); - fprintf(DebugFile, "### ###\n"); - } - - if (!R2.is_upper_bound_satisfiable()) - return Relation::True(R1); - if (R2.is_obvious_tautology()) { - R1.simplify(); - return R1; - } - R1.simplify(); - - if (!Intersection(copy(R1), copy(R2)).is_upper_bound_satisfiable()) - return Relation::False(R1); - - int nconj1=0; - for (DNF_Iterator di(R1.simplified_DNF()); di.live(); di.next()) - nconj1++; - int nconj2=0; - for (DNF_Iterator di2(R2.simplified_DNF()); di2.live(); di2.next()) - nconj2++; - - { - static int OMEGA_WHINGE = -1; - if (OMEGA_WHINGE < 0) { - OMEGA_WHINGE = getenv("OMEGA_WHINGE") ? atoi(getenv("OMEGA_WHINGE")) : 0; - } - if (OMEGA_WHINGE && (nconj1 + nconj2 > 50)) { - fprintf(DebugFile,"WOW!!!! - Gist (%d conjuncts, %d conjuncts)!!!\n", - nconj1,nconj2); - fprintf(DebugFile,"Base:\n"); - R1.prefix_print(DebugFile); - fprintf(DebugFile,"Context:\n"); - R2.prefix_print(DebugFile); - } - } - - if (nconj2==1) - return GistSingleConjunct(R1,R2, effort); - else { - R1.simplify(0,1); - R2.simplify(0,1); - Relation G = Relation::True(R1); - for (DNF_Iterator di2(R2.simplified_DNF()); di2.live(); di2.next()) { - Conjunct * c2 = di2.curr(); - Relation G2 = Relation::False(R1); - for (DNF_Iterator di1(R1.simplified_DNF()); di1.live(); di1.next()) { - Conjunct * c1 = di1.curr(); - Relation G1=GistSingleConjunct(Relation(R1,c1), Relation(R2,c2),effort); - - if (G1.is_obvious_tautology()) { - G2 = G1; - break; - } - else if (!G1.is_upper_bound_satisfiable() || !G1.is_exact()) { - if(relation_debug) { - fprintf(DebugFile, "gist A given B is unsatisfiable\n"); - fprintf(DebugFile, "A:\n"); - Relation(R1,c1).prefix_print(DebugFile); - fprintf(DebugFile, "B:\n"); - Relation(R2,c2).prefix_print(DebugFile); - fprintf(DebugFile, "\n"); - } - //G1 = Relation(R1,c1); - return R1; - } - else if(0 && G1.is_exact() && !Must_Be_Subset(Relation(R1,c1),copy(G1))) { - fprintf(DebugFile,"Unexpected non-Must_Be_Subset gist result!\n"); - fprintf(DebugFile,"base: \n"); - Relation(R1,c1).prefix_print(DebugFile); - fprintf(DebugFile,"context: \n"); - Relation(R2,c2).prefix_print(DebugFile); - fprintf(DebugFile,"result: \n"); - G1.prefix_print(DebugFile); - fprintf(DebugFile,"base not subseteq result: \n"); - assert(!G1.is_exact() || Must_Be_Subset(Relation(R1,c1),copy(G1))); - } - G2=Union(G2,G1); - } - G2.simplify(0,1); - G = Intersection(G,G2); - G.simplify(0,1); - if(relation_debug) { - fprintf(DebugFile, "result so far is:\n"); - G.prefix_print(DebugFile); - } - } - - if(relation_debug) { - fprintf(DebugFile, "\n### end multi-GIST computation ### ]\n"); - fprintf(DebugFile, "G is:\n"); - G.prefix_print(DebugFile); - fprintf(DebugFile, "### ###\n"); - } -#if ! defined NDEBUG - Relation S1 = Intersection(copy(R1), copy(R2)); - Relation S2 = Intersection(copy(G), copy(R2)); - - - if(relation_debug) { - fprintf(DebugFile, "\n---->[Checking validity of the GIST result\n"); - fprintf(DebugFile, "for G=gist R1 given R2:\n"); - fprintf(DebugFile, "R1 intersect R2 is:\n"); - S1.print_with_subs(DebugFile); - fprintf(DebugFile, "\nG intersect R2 is:\n"); - S2.print_with_subs(DebugFile); - fprintf(DebugFile, "---->]\n"); - } - assert (!S1.is_exact() || !S2.is_exact() || (Must_Be_Subset(copy(S1),copy(S2)) && Must_Be_Subset(copy(S2),copy(S1)))); -#endif - return G; - } -} - - -// Project away all input and output variables. -Relation Project_On_Sym(NOT_CONST Relation &S, - NOT_CONST Relation &input_context) { - Relation R = consume_and_regurgitate(S); - Relation context = consume_and_regurgitate(input_context); - int i; - - // skip_set_checks++; - leave_pufs_untouched++; - int in_arity = R.max_ufs_arity_of_in(); - int out_arity = R.max_ufs_arity_of_out(); - assert(!R.is_null()); - R.split(); - - int no_inp = R.n_inp(); - int no_out = R.n_out(); - Mapping M(no_inp, no_out); - - for(i=1; i<=no_inp; i++) { // project out input variables - M.set_map(Input_Var, i, Exists_Var, i); - } - for(i=1; i<=no_out; i++) { // project out output variables - M.set_map(Output_Var, i, Exists_Var, no_inp+i); - } - MapRel1(R, M, Comb_Id, 0, 0); - - R.finalize(); - if (in_arity) R = Extend_Domain(R,in_arity); - if (out_arity) R = Extend_Range(R,out_arity); - - int d = min(in_arity,out_arity); - if (d && !context.is_null()) { - int g = min(d,context.query_guaranteed_leading_0s()); - int p = min(d,context.query_possible_leading_0s()); - int dir = context.query_leading_dir(); - R.enforce_leading_info(g,p,dir); - } - - leave_pufs_untouched--; - // skip_set_checks--; - if(relation_debug) { - fprintf(DebugFile,"\nProjecting onto symbolic (%d,%d):\n",in_arity,out_arity); - R.prefix_print(DebugFile); - } - return R; -} - - -// -// Project out global variable g from relation r -// -Relation Project(NOT_CONST Relation &S, Global_Var_ID g) { - Relation R = consume_and_regurgitate(S); - assert(!R.is_null()); - - skip_finalization_check++; - - Rel_Body *r = R.split(); - r->DNF_to_formula(); - Formula *f = r->rm_formula(); - F_Exists *ex = r->add_exists(); - ex->add_child(f); - - if (g->arity() == 0) { - assert(R.has_local(g) && "Project: Relation doesn't contain variable to be projected"); - Variable_ID v = R.get_local(g); - - bool rmd = rm_variable(r->Symbolic,v); - assert(rmd && "Project: Variable to be projected doesn't exist"); - - v->remap = ex->declare(v->base_name); - f->remap(); - v->remap = v; - } - else { - assert((R.has_local(g, Input_Tuple) || R.has_local(g, Output_Tuple)) && "Project: Relation doesn't contain variable to be projected"); - - if (R.has_local(g, Input_Tuple)) { - Variable_ID v = R.get_local(g, Input_Tuple); - - bool rmd = rm_variable(r->Symbolic,v); - assert(rmd && "Project: Variable to be projected doesn't exist"); - - v->remap = ex->declare(v->base_name); - f->remap(); - v->remap = v; - } - if (R.has_local(g, Output_Tuple)) { - Variable_ID v = R.get_local(g, Output_Tuple); - - bool rmd = rm_variable(r->Symbolic,v); - assert(rmd && "Project: Variable to be projected doesn't exist"); - - v->remap = ex->declare(v->base_name); - f->remap(); - v->remap = v; - } - } - - skip_finalization_check--; - - R.finalize(); - return R; -} - - -// -// Project all symbolic variables from relation r -// -Relation Project_Sym(NOT_CONST Relation &S) { - Relation R = consume_and_regurgitate(S); - assert(!R.is_null()); - - Rel_Body *r = R.split(); - r->DNF_to_formula(); - - Formula *f = r->rm_formula(); - - skip_finalization_check++; - F_Exists *ex = r->add_exists(); - for(Variable_ID_Iterator R_Sym(r->Symbolic); R_Sym; R_Sym++) { - Variable_ID v = *R_Sym; - v->remap = ex->declare(v->base_name); - } - ex->add_child(f); - skip_finalization_check--; - - f->remap(); - - reset_remap_field(r->Symbolic); - r->Symbolic.clear(); - - R.finalize(); - return R; -} - -// -// Project specified variables, leaving those variables with no constraints. -// -Relation Project(NOT_CONST Relation &S, Sequence<Variable_ID> &s) { - // This is difficult to do with mappings. This cheats, since it is - // much easier and more straightforward. - - Relation R = consume_and_regurgitate(S); - assert(!R.is_null()); - - Rel_Body *r = R.split(); - r->DNF_to_formula(); - Formula *f = r->rm_formula(); - bool need_symbolic_clear = false; - - skip_finalization_check++; - F_Exists *ex = r->add_exists(); - for(int i = 1; i <= s.size(); i++) { - if (s[i]->kind() == Global_Var) - need_symbolic_clear = true; - s[i]->remap = ex->declare(s[i]->base_name); - } - ex->add_child(f); - skip_finalization_check--; - - f->remap(); - - reset_remap_field(s); - if (need_symbolic_clear) - r->Symbolic.clear(); - - R.finalize(); - return R; -} - -Relation Project(NOT_CONST Relation &S, int pos, Var_Kind vkind) { - Variable_ID v = 0; // shut the compiler up - switch (vkind) { - case Input_Var: - v = input_vars[pos]; - break; - case Output_Var: - v = output_vars[pos]; - break; - // case Set_Var: - // v = set_vars[pos]; - // break; - default: - assert(0); - } - - return Project(S, v); -} - -Relation Project(NOT_CONST Relation &S, Variable_ID v) { - Tuple<Variable_ID> s; - s.append(v); - return Project(S, s); -} - -// -// Variables in DNF of map_rel reference declarations of map_rel (or not). -// remap_DNF_vars makes them to reference declarations of ref_rel. -// Ref_rel can get new global variable declarations in the process. -// -void remap_DNF_vars(Rel_Body *map_rel, Rel_Body *ref_rel) { - // skip_set_checks++; - assert (map_rel->simplified_DNF); - assert (ref_rel->simplified_DNF); - - // skip_set_checks++; - - for(DNF_Iterator pd(map_rel->simplified_DNF); pd.live(); pd.next()) { - Conjunct *cc = pd.curr(); - Variable_ID_Tuple &mvars = cc->mappedVars; - for(Variable_Iterator mvarsIter=mvars; mvarsIter; mvarsIter++) { - Variable_ID v = *mvarsIter; - switch(v->kind()) { - case Input_Var: - assert(ref_rel->n_inp() >= v->get_position()); - break; - case Output_Var: - assert(ref_rel->n_out() >= v->get_position()); - break; - case Global_Var: - // The assignment is a noop, but tells ref_rel that the global may be - // used inside it, which is required. - *mvarsIter = ref_rel->get_local(v->get_global_var(),v->function_of()); - break; - case Wildcard_Var: - break; - default: - assert(0 && "bad variable kind"); - } - } - } - // skip_set_checks--; -} - - -Relation projectOntoJust(Relation R, Variable_ID v) { - // skip_set_checks++; - - int ivars = R.n_inp(), ovars = R.n_out(); - int ex_ivars= 0, ex_ovars = 0; - - assert(v->kind() == Input_Var || v->kind() == Output_Var); - if (v->kind() == Input_Var) { - ex_ivars = 1; - R = Extend_Domain(R,1); - } - else { - ex_ovars = 1; - R = Extend_Range(R,1); - } - - // Project everything except v - Mapping m(ivars+ex_ivars,ovars+ex_ovars); - int j; - for(j = 1; j <=ivars+ex_ivars; j++) m.set_map_in(j, Exists_Var, j); - for(j = 1; j <=ovars+ex_ovars; j++) m.set_map_out(j, Exists_Var, j+ivars+ex_ivars); - m.set_map(v->kind(), v->get_position(), v->kind(), v->get_position()); - - MapRel1(R, m, Comb_Id,-1,-1); - R.finalize(); - // skip_set_checks--; - return R; -} - -//static -//void copyEQtoGEQ(GEQ_Handle &g, const EQ_Handle &e, bool negate) { -//extern void copy_constraint(Constraint_Handle H, Constraint_Handle initial); -// copy_constraint(g, e); -//} - - -Relation EQs_to_GEQs(NOT_CONST Relation &S, bool excludeStrides) { - Relation R = consume_and_regurgitate(S); - assert(R.is_simplified()); - use_ugly_names++; - for (DNF_Iterator s(R.query_DNF()); s.live(); s.next()) - s.curr()->convertEQstoGEQs(excludeStrides); - use_ugly_names--; - return R; -} - - -// Tuple to find values for is input+output -Relation Symbolic_Solution(NOT_CONST Relation &R) { - Relation S = consume_and_regurgitate(R); - Tuple<Variable_ID> vee; - // skip_set_checks++; - int i; - for(i = 1; i <= S.n_inp(); i++) vee.append(input_var(i)); - for(i = 1; i <= S.n_out(); i++) vee.append(output_var(i)); - // skip_set_checks--; - - return Solution(S, vee); -} - - -// Tuple to find values for is given as arg, plus input and output -Relation Symbolic_Solution(NOT_CONST Relation &R, Sequence<Variable_ID> &for_these){ - Relation S = consume_and_regurgitate(R); - Tuple<Variable_ID> vee; - // skip_set_checks++; - int i; - for(Any_Iterator<Variable_ID> it(for_these); it; it++) - vee.append(*it); - for(i = 1; i <= S.n_inp(); i++) vee.append(input_var(i)); - for(i = 1; i <= S.n_out(); i++) vee.append(output_var(i)); - // skip_set_checks--; - - return Solution(S, vee); -} - - -// Tuple to find values for is input+output+global_decls -Relation Sample_Solution(NOT_CONST Relation &R) { - Relation S = consume_and_regurgitate(R); - - Tuple<Variable_ID> vee; - - // skip_set_checks++; - int i; - for(i = 1; i <= S.global_decls()->size(); i++) - vee.append((*S.global_decls())[i]); - for(i = 1; i <= S.n_inp(); i++) vee.append(input_var(i)); - for(i = 1; i <= S.n_out(); i++) vee.append(output_var(i)); - // skip_set_checks--; - - return Solution(S,vee); -} - - -// Tuple to find values is given as arg -Relation Solution(NOT_CONST Relation &S, Sequence<Variable_ID> &for_these ) { - Relation R = consume_and_regurgitate(S); - if (R.is_null()) - return R; - - //assert(!R.is_null()); - - if(!R.is_upper_bound_satisfiable()) { - return Relation::False(R); - } - - bool inexactAnswer=false; - if(R.is_inexact()) { - if(R.is_lower_bound_satisfiable()) - R = Lower_Bound(R); // a solution to LB is a solution to the relation - else { - // A solution to the UB may not be a solution to the relation: - // There may be a solution which satisfies all known constraints, but - // we have no way of knowing if it satisifies the unknown constraints. - inexactAnswer = true; - R = Upper_Bound(R); - } - } - - Sequence<Variable_ID> &vee = for_these; - for (DNF_Iterator di(R.query_DNF()); di; di++) { - Relation current(R, *di); - int i; - for(i = vee.size()-1; i >= 0; i--) { - bool some_constraints = false, one_stride = false; - - int current_var = vee.size()-i; - Section<Variable_ID> s(&vee,current_var+1,i); - - // Query variable in vee[current_var] - Relation projected = Project(copy(current), s); - - retry_solution: - assert(projected.has_single_conjunct()); - DNF_Iterator one = projected.query_DNF(); - - // Look for candidate EQ's - EQ_Handle stride; - EQ_Iterator ei(*one); - for(; ei; ei++) { - if((*ei).get_coef(vee[current_var]) != 0) { - if(!Constr_Vars_Iter(*ei,true).live()) { // no wildcards - some_constraints = true; - // Add this constraint to the current as an EQ - current.and_with_EQ(*ei); - break; - } - else { - one_stride = !one_stride && !some_constraints; - stride = *ei; - } - } - } - if(ei) - continue; // Found an EQ, skip to next variable - else if (one_stride && !some_constraints) { - // if unconstrained except for a stride, pick stride as value - Constr_Vars_Iter cvi(stride,true); - assert(cvi.live()); - cvi++; - if(!cvi) { // Just one existentially quantified variable - Relation current_copy = current; - EQ_Handle eh = current_copy.and_with_EQ(); - for(Constr_Vars_Iter si = stride; si; si++) - if((*si).var->kind() != Wildcard_Var){ - // pick "0" for wildcard, don't set its coef - eh.update_coef((*si).var, (*si).coef); - } - eh.update_const(stride.get_const()); - if(current_copy.is_upper_bound_satisfiable()){ - current = current_copy; - continue; // skip to next var - } - } - some_constraints = true; // count the stride as a constraint - } - - // Can we convert a GEQ? - GEQ_Iterator gi(*one); - for(; gi; gi++) { - if((*gi).get_coef(vee[current_var]) != 0) { - some_constraints = true; - if(!Constr_Vars_Iter(*gi,true).live()) { // no wildcards - Relation current_copy = current; - // Add this constraint to the current as an EQ & test - current_copy.and_with_EQ(*gi); - if (current_copy.is_upper_bound_satisfiable()) { - current = current_copy; - break; - } - } - } - } - if (gi) continue; // Turned a GEQ into EQ, skip to next - - // Remove wildcards, try try again - Relation approx = Approximate(copy(projected)); - assert(approx.has_single_conjunct()); - DNF_Iterator d2 = approx.query_DNF(); - - EQ_Iterator ei2(*d2); - for(; ei2; ei2++) { - if((*ei2).get_coef(vee[current_var]) != 0) { - some_constraints = true; - assert(!Constr_Vars_Iter(*ei2,true).live()); // no wildcards - Relation current_copy = current; - // Add this constraint to the current as an EQ & test - current_copy.and_with_EQ(*ei2); - if (current_copy.is_upper_bound_satisfiable()) { - current = current_copy; - break; - } - } - } - if(ei2) continue; // Found an EQ, skip to next variable - - GEQ_Iterator gi2(*d2); - for(; gi2; gi2++) { - if((*gi2).get_coef(vee[current_var]) != 0) { - some_constraints = true; - assert(!Constr_Vars_Iter(*gi2,true).live()); // no wildcards - Relation current_copy = current; - // Add this constraint to the current as an EQ & test - current_copy.and_with_EQ(*gi2); - if (current_copy.is_upper_bound_satisfiable()) { - current = current_copy; - break; - } - } - } - if(gi2) continue; - - if(!some_constraints) { // No constraints on this variable were found - EQ_Handle e = current.and_with_EQ(); - e.update_const(-42); // Be creative - e.update_coef(vee[current_var], 1); - continue; - } - else { // What to do? Find a wildcard to discard - Variable_ID wild = NULL; - - for (GEQ_Iterator gi(*one); gi; gi++) - if ((*gi).get_coef(vee[current_var]) != 0 && (*gi).has_wildcards()) { - Constr_Vars_Iter cvi(*gi, true); - wild = (*cvi).var; - break; - } - if (wild == NULL) - for (EQ_Iterator ei(*one); ei; ei++) - if ((*ei).get_coef(vee[current_var]) != 0 && (*ei).has_wildcards()) { - Constr_Vars_Iter cvi(*ei, true); - wild = (*cvi).var; - break; - } - - if (wild != NULL) { - // skip_set_checks++; - - Relation R2; - { - Tuple<Relation> r(1); - r[1] = projected; - Tuple<std::map<Variable_ID, std::pair<Var_Kind, int> > > mapping(1); - mapping[1][wild] = std::make_pair(vee[current_var]->kind(), vee[current_var]->get_position()); - mapping[1][vee[current_var]] = std::make_pair(Exists_Var, 1); - Tuple<bool> inverse(1); - inverse[1] = false; - R2 = merge_rels(r, mapping, inverse, Comb_And); - } - - Variable_ID R2_v; - switch (vee[current_var]->kind()) { - // case Set_Var: - case Input_Var: { - int pos = vee[current_var]->get_position(); - R2_v = R2.input_var(pos); - break; - } - case Output_Var: { - int pos = vee[current_var]->get_position(); - R2_v = R2.output_var(pos); - break; - } - case Global_Var: { - Global_Var_ID g = vee[current_var]->get_global_var(); - if (g->arity() == 0) - R2_v = R2.get_local(g); - else - R2_v = R2.get_local(g, vee[current_var]->function_of()); - } - default: - assert(0); - } - - Relation S2; - { - Tuple<Variable_ID> vee; - vee.append(R2_v); - S2 = Solution(R2, vee); - } - - Variable_ID S2_v; - switch (vee[current_var]->kind()) { - // case Set_Var: - case Input_Var: { - int pos = vee[current_var]->get_position(); - S2_v = S2.input_var(pos); - break; - } - case Output_Var: { - int pos = vee[current_var]->get_position(); - S2_v = S2.output_var(pos); - break; - } - case Global_Var: { - Global_Var_ID g = vee[current_var]->get_global_var(); - if (g->arity() == 0) - S2_v = S2.get_local(g); - else - S2_v = S2.get_local(g, vee[current_var]->function_of()); - } - default: - assert(0); - } - - Relation R3; - { - Tuple<Relation> r(2); - r[1] = projected; - r[2] = S2; - Tuple<std::map<Variable_ID, std::pair<Var_Kind, int> > > mapping(2); - mapping[1][wild] = std::make_pair(Exists_Var, 1); - mapping[2][S2_v] = std::make_pair(Exists_Var, 1); - Tuple<bool> inverse(2); - inverse[1] = inverse[2] = false; - R3 = merge_rels(r, mapping, inverse, Comb_And); - } - - // skip_set_checks--; - - if (R3.is_upper_bound_satisfiable()) { - projected = R3; - goto retry_solution; - } - } - } - - // If we get here, we failed to find a suitable constraint for - // this variable at this conjunct, look for another conjunct. - break; - } - - if (i < 0) { // solution found - if(inexactAnswer) - current.and_with_and()->add_unknown(); - current.finalize(); - return current; - } - } - - // No solution found for any conjunct, we bail out. - fprintf(stderr,"Couldn't find suitable constraint for variable\n"); - return Relation::Unknown(R); -} - - -Relation Approximate(NOT_CONST Relation &input_R, bool strides_allowed) { - Relation R = consume_and_regurgitate(input_R); - if (R.is_null()) - return R; - - // assert(!R.is_null()); - Rel_Body *r = R.split(); - - // approximate can be used to remove lambda variables from farkas, - // so be careful not to invoke simplification process for integers. - r->simplify(-1,-1); - - if (pres_debug) { - fprintf(DebugFile,"Computing approximation "); - if (strides_allowed) fprintf(DebugFile,"with strides allowed "); - fprintf(DebugFile,"[ \n"); - r->prefix_print(DebugFile); - } - - use_ugly_names++; - for (DNF_Iterator pd(r->simplified_DNF); pd.live(); ) { - Conjunct *C = pd.curr(); - pd.next(); - - for(int i = 0; i < C->problem->nGEQs; i++) - C->problem->GEQs[i].touched = 1; - - C->reorder(); - if(C->problem->simplifyApproximate(strides_allowed)==0) { - r->simplified_DNF->rm_conjunct(C); - delete C; - } - else { - C->simplifyProblem(1,0,1); - - free_var_decls(C->myLocals); C->myLocals.clear(); - - Problem *p = C->problem; - Variable_ID_Tuple new_mapped(0); // This is expanded by "append" - for (int i = 1; i <= p->safeVars; i++) { - // what is now in column i used to be in column p->var[i] - Variable_ID v = C->mappedVars[p->var[i]]; - assert (v->kind() != Wildcard_Var); - new_mapped.append(v); - } - assert(strides_allowed || C->problem->nVars == C->problem->safeVars); - C->mappedVars = new_mapped; - for (int i = p->safeVars+1; i <= p->nVars; i++) { - Variable_ID v = C->declare(); - C->mappedVars.append(v); - } - - - // reset var and forwarding address if desired. - p->variablesInitialized = 0; - for(int i = 1; i < C->problem->nVars; i++) - C->problem->var[i] = C->problem->forwardingAddress[i] = i; - } - } - - if (pres_debug) - fprintf(DebugFile,"] done Computing approximation\n"); - use_ugly_names--; - return R; -} - - -Relation Lower_Bound(NOT_CONST Relation &r) { - Relation s = consume_and_regurgitate(r); - s.interpret_unknown_as_false(); - return s; -} - - -Relation Upper_Bound(NOT_CONST Relation &r) { - Relation s = consume_and_regurgitate(r); - s.interpret_unknown_as_true(); - return s; -} - - -bool operator==(const Relation &, const Relation &) { - assert(0 && "You rilly, rilly don't want to do this.\n"); - abort(); - return false; -} - - -namespace { // supporting stuff for MapRel1 and MapAndCombine2 - // Determine if a mapping requires an f_exists node - bool has_existentials(const Mapping &m) { - for(int i=1;i<=m.n_in(); i++) - if (m.get_map_in_kind(i) == Exists_Var) return true; - for(int j=1;j<=m.n_out(); j++) - if (m.get_map_out_kind(j) == Exists_Var) return true; - return false; - } - - void get_relation_arity_from_one_mapping(const Mapping &m1, - int &in_req, int &out_req) { - int j, i; - in_req = 0; out_req = 0; - for(i = 1; i <= m1.n_in(); i++) { - j = m1.get_map_in_pos(i); - switch(m1.get_map_in_kind(i)) { - case Input_Var: in_req = max(in_req, j); break; - // case Set_Var: in_req = max(in_req, j); break; - case Output_Var: out_req = max(out_req, j); break; - default: break; - } - } - for(i = 1; i <= m1.n_out(); i++) { - j = m1.get_map_out_pos(i); - switch(m1.get_map_out_kind(i)) { - case Input_Var: in_req = max(in_req, j); break; - // case Set_Var: in_req = max(in_req, j); break; - case Output_Var: out_req = max(out_req, j); break; - default: break; - } - } - } - - // Scan mappings to see how many input and output variables they require. - void get_relation_arity_from_mappings(const Mapping &m1, - const Mapping &m2, - int &in_req, int &out_req) { - int inreq1, inreq2, outreq1, outreq2; - get_relation_arity_from_one_mapping(m1, inreq1, outreq1); - get_relation_arity_from_one_mapping(m2, inreq2, outreq2); - in_req = max(inreq1, inreq2); - out_req = max(outreq1, outreq2); - } -} - - -// -// Build lists of variables that need to be replaced in the given -// Formula. Declare globals in new relation. Then call -// map_vars to do the replacements. -// -// Obnoxiously many arguments here: -// Relation arguments contain declarations of symbolic and in/out vars. -// F_Exists argument is where needed existentially quant. vars can be decl. -// -// Mapping specifies how in/out vars are mapped -// Two lists are required to be able to map in/out variables from the first -// and second relations to the same existentially quantified variable. -// -void align(Rel_Body *originalr, Rel_Body *newr, F_Exists *fe, - Formula *f, const Mapping &mapping, bool &newrIsSet, - List<int> &seen_exists, Variable_ID_Tuple &seen_exists_ids) { - int i, cur_ex = 0; // initialize cur_ex to shut up the compiler - - f->set_relation(newr); // Might not need to do this anymore, if bugs were fixed - int input_remapped = 0; - int output_remapped = 0; - int sym_remapped = 0; - // skip_set_checks++; - - Variable_ID new_var; - Const_String new_name; - int new_pos; - - // MAP old input variables by setting their remap fields - for(i = 1; i <= originalr->n_inp(); i++) { - Variable_ID this_var = originalr->input_var(i), New_E; - Const_String this_name = originalr->In_Names[i]; - - switch (mapping.get_map_in_kind(i)) { - case Input_Var: - // case Set_Var: - // if (mapping.get_map_in_kind(i) == Set_Var) - // newrIsSet = true; // Don't mark it just yet; we still need to - // // refer to its "input" vars internally - - // assert((newrIsSet && mapping.get_map_in_kind(i) == Set_Var) - // || ((!newrIsSet &&mapping.get_map_in_kind(i) == Input_Var))); - - new_pos = mapping.get_map_in_pos(i); - new_var = newr->input_var(new_pos); - if (this_var != new_var) { - input_remapped = 1; - this_var->remap = new_var; - } - new_name = newr->In_Names[new_pos]; - if (!this_name.null()) { // should we name this? - if (!new_name.null()) { // already named, anonymize - if (new_name != this_name) - newr->name_input_var(new_pos, Const_String()); - } - else - newr->name_input_var(new_pos, this_name); - } - break; - case Output_Var: - assert(!newr->is_set()); - input_remapped = 1; - new_pos = mapping.get_map_in_pos(i); - this_var->remap = new_var = newr->output_var(new_pos); - new_name = newr->Out_Names[new_pos]; - if (!this_name.null()) { - if (!new_name.null()) { // already named, anonymize - if (new_name != this_name) - newr->name_output_var(new_pos, Const_String()); - } - else - newr->name_output_var(new_pos, this_name); - } - break; - case Exists_Var: - input_remapped = 1; - // check if we have declared it, use that if so. - // create it if not. - if (mapping.get_map_in_pos(i) <= 0 || - (cur_ex = seen_exists.index(mapping.get_map_in_pos(i))) == 0){ - if (!this_name.null()) - New_E = fe->declare(this_name); - else - New_E = fe->declare(); - this_var->remap = New_E; - if (mapping.get_map_in_pos(i) > 0) { - seen_exists.append(mapping.get_map_in_pos(i)); - seen_exists_ids.append(New_E); - } - } - else { - this_var->remap = new_var = seen_exists_ids[cur_ex]; - if (!this_name.null()) { // Have we already assigned a name? - if (!new_var->base_name.null()) { - if (new_var->base_name != this_name) - new_var->base_name = Const_String(); - } - else { - new_var->base_name = this_name; - assert(!this_name.null()); - } - } - } - break; - default: - assert(0 && "Unsupported var type in MapRel2"); - break; - } - } - - // MAP old output variables. - for(i = 1; i <= originalr->n_out(); i++) { - Variable_ID this_var = originalr->output_var(i), New_E; - Const_String this_name = originalr->Out_Names[i]; - - switch (mapping.get_map_out_kind(i)) { - case Input_Var: - // case Set_Var: - // if (mapping.get_map_out_kind(i) == Set_Var) - // newrIsSet = true; // Don't mark it just yet; we still need to refer to its "input" vars internally - - // assert((newrIsSet && mapping.get_map_out_kind(i) == Set_Var) - // ||((!newrIsSet &&mapping.get_map_out_kind(i) == Input_Var))); - - output_remapped = 1; - new_pos = mapping.get_map_out_pos(i); - this_var->remap = new_var = newr->input_var(new_pos); - new_name = newr->In_Names[new_pos]; - if (!this_name.null()) { - if (!new_name.null()) { // already named, anonymize - if (new_name != this_name) - newr->name_input_var(new_pos, Const_String()); - } - else - newr->name_input_var(new_pos, this_name); - } - break; - case Output_Var: - assert(!newr->is_set()); - new_pos = mapping.get_map_out_pos(i); - new_var = newr->output_var(new_pos); - if (new_var != this_var) { - output_remapped = 1; - this_var->remap = new_var; - } - new_name = newr->Out_Names[new_pos]; - if (!this_name.null()) { - if (!new_name.null()) { // already named, anonymize - if (new_name != this_name) - newr->name_output_var(new_pos, Const_String()); - } - else - newr->name_output_var(new_pos, this_name); - } - break; - case Exists_Var: - // check if we have declared it, create it if not. - output_remapped = 1; - if (mapping.get_map_out_pos(i) <= 0 || - (cur_ex = seen_exists.index(mapping.get_map_out_pos(i))) == 0) { // Declare it. - New_E = fe->declare(this_name); - this_var->remap = New_E; - if (mapping.get_map_out_pos(i) > 0) { - seen_exists.append(mapping.get_map_out_pos(i)); - seen_exists_ids.append(New_E); - } - } - else { - this_var->remap = new_var = seen_exists_ids[cur_ex]; - if (!this_name.null()) { - if (!new_var->base_name.null()) { - if (new_var->base_name != this_name) - new_var->base_name = Const_String(); - } - else { - new_var->base_name = this_name; - } - } - } - break; - default: - assert(0 &&"Unsupported var type in MapRel2"); - break; - } - } - - Variable_ID_Tuple *oldSym = originalr->global_decls(); - for(i=1; i<=(*oldSym).size(); i++) { - Variable_ID v = (*oldSym)[i]; - assert(v->kind()==Global_Var); - if (v->get_global_var()->arity() > 0) { - Argument_Tuple new_of = v->function_of(); - if (!leave_pufs_untouched) - new_of = mapping.get_tuple_fate(new_of, v->get_global_var()->arity()); - if (new_of == Unknown_Tuple) { - // hopefully v is not really used - // if we get here, f should have been in DNF, - // now an OR node with conjuncts below - // we just need to check that no conjunct uses v -#if ! defined NDEBUG - if (f->node_type() == Op_Conjunct) { - assert(f->really_conjunct()->mappedVars.index(v)==0 - && "v unused"); - } -#if 0 - else { - // assert(f->node_type() == Op_Or); - for (List_Iterator<Formula *> conj(f->children()); conj; conj++) { - assert((*conj)->really_conjunct()->mappedVars.index(v)==0 - && "v unused"); - } - } -#endif -#endif - // since its not really used, don't bother adding it to - // the the global_vars list of the new relation - continue; - } - if (v->function_of() != new_of) { - Variable_ID new_v=newr->get_local(v->get_global_var(),new_of); - assert(v != new_v); - v->remap = new_v; - sym_remapped = 1; - } - else { - // add symbolic to symbolic list -#if ! defined NDEBUG - Variable_ID new_v = -#endif - newr->get_local(v->get_global_var(), v->function_of()); -#if ! defined NDEBUG - assert(v == new_v); -#endif - } - } - else { - // add symbolic to symbolic list -#if ! defined NDEBUG - Variable_ID new_v = -#endif - newr->get_local(v->get_global_var()); -#if ! defined NDEBUG - assert(v == new_v); -#endif - } - } - - if (sym_remapped || input_remapped || output_remapped) { - f->remap(); - - // If 2 vars mapped to same variable, combine them - //There's a column to combine only when there are two equal remap fields. - Tuple<Variable_ID> vt(0); - bool combine = false; - Tuple_Iterator<Variable_ID> t(input_vars); - for(i=1; !combine && i<=originalr->n_inp(); t++, i++) - if (vt.index((*t)->remap)) - combine = true; - else - vt.append((*t)->remap); - Tuple_Iterator<Variable_ID> t2(output_vars); - for(i=1; !combine && i <= originalr->n_out(); t2++, i++) - if (vt.index((*t2)->remap)) - combine = true; - else - vt.append((*t2)->remap); - if (combine) f->combine_columns(); - - if (sym_remapped) - reset_remap_field(originalr->Symbolic); - if (input_remapped) - reset_remap_field(input_vars,originalr->n_inp()); - if (output_remapped) - reset_remap_field(output_vars,originalr->n_out()); - } - - // skip_set_checks--; - -#ifndef NDEBUG - if (fe) - foreach(v,Variable_ID,fe->myLocals,assert(v == v->remap)); -#endif -} - - -// MapRel1, MapAndCombineRel2 can be replaced by merge_rels -void MapRel1(Relation &R, const Mapping &map, Combine_Type ctype, - int number_input, int number_output, - bool invalidate_resulting_leading_info, - bool finalize) { -#if defined(INCLUDE_COMPRESSION) - assert(!R.is_compressed()); -#endif - assert(!R.is_null()); - - Relation inputRel = R; - R = Relation(); - Rel_Body *inputRelBody = inputRel.split(); - - int in_req=0, out_req=0; - get_relation_arity_from_one_mapping(map, in_req, out_req); - - R = Relation(number_input == -1 ? in_req : number_input, - number_output == -1 ? out_req : number_output); - - Rel_Body *outputRelBody = R.split(); - - inputRelBody->DNF_to_formula(); - Formula *f1 = inputRelBody->rm_formula(); - - F_Exists *fe; - Formula *f; - if (has_existentials(map)) { - f = fe = outputRelBody->add_exists(); - } - else { - fe = NULL; - f = outputRelBody; - } - and_below_exists = NULL; - if (finalize) and_below_exists = NULL; - else f = and_below_exists = f->add_and(); - if(ctype == Comb_AndNot) { - f = f->add_not(); - } - f->add_child(f1); - - exists_ids.clear(); - exists_numbers.clear(); - - bool returnAsSet=false; - align(inputRelBody, outputRelBody, fe, f1, map, returnAsSet, - exists_numbers, exists_ids); - - if (returnAsSet || - (inputRelBody->is_set() && outputRelBody->n_out() == 0)) { - R.markAsSet(); - R.invalidate_leading_info(); // nonsensical for a set - } - - if (finalize) R.finalize(); - inputRel = Relation(); - if (invalidate_resulting_leading_info) - R.invalidate_leading_info(); -} - - -Relation MapAndCombineRel2(Relation &R1, Relation &R2, const Mapping &mapping1, - const Mapping &mapping2, Combine_Type ctype, - int number_input, int number_output) { -#if defined(INCLUDE_COMPRESSION) - assert(!R1.is_compressed()); - assert(!R2.is_compressed()); -#endif - assert(!R1.is_null() && !R2.is_null()); - Rel_Body *r1 = R1.split(); - Rel_Body *r2 = R2.split(); - - int in_req, out_req; // Create the new relation - get_relation_arity_from_mappings(mapping1, mapping2, in_req, out_req); - Relation R3(number_input == -1 ? in_req : number_input, - number_output == -1 ? out_req : number_output); - Rel_Body *r3 = R3.split(); // This is just to get the pointer, it's cheap - - /* permit the add_{exists,and} below, reset after they are done.*/ - skip_finalization_check++; - - F_Exists *fe = NULL; - Formula *f; - if (has_existentials(mapping1) || has_existentials(mapping2)) { - fe = r3->add_exists(); - f = fe; - } - else { - f = r3; - } - - r1->DNF_to_formula(); - Formula *f1 = r1->rm_formula(); - r2->DNF_to_formula(); - Formula *f2 = r2->rm_formula(); - - // align: change r1 vars to r3 vars in formula f1 via map mapping1, - // declaring needed exists vars in F_Exists *fe - // Also maps symbolic variables appropriately, sets relation ptrs in f1. - // In order to map variables of both relations to the same variables, - // we keep a list of new existentially quantified vars between calls. - // returnAsSet means mark r3 as set before return. Don't mark it yet, - // because internally we need to refer to "input_vars" of a set, and that - // would blow assertions. - - bool returnAsSet=false; - exists_ids.clear(); - exists_numbers.clear(); - align(r1, r3, fe, f1, mapping1, returnAsSet, exists_numbers, exists_ids); - // align: change r2 vars to r3 vars in formula f2 via map mapping2 - align(r2, r3, fe, f2, mapping2, returnAsSet, exists_numbers, exists_ids); - - switch (ctype) { - case Comb_Or: - if(f1->node_type() == Op_Or) { - f->add_child(f1); - f = f1; - } - else { - f = f->add_or(); - f->add_child(f1); - } - break; - case Comb_And: - case Comb_AndNot: - if(f1->node_type() == Op_And) { - f->add_child(f1); - f = f1; - } - else { - f = f->add_and(); - f->add_child(f1); - } - break; - default: - assert(0 && "Invalid combine type in MapAndCombineRel2"); - } - - Formula *c2; - if (ctype==Comb_AndNot) { - c2 = f->add_not(); - } - else { - c2 = f; - } - c2->add_child(f2); - - skip_finalization_check--; /* Set this back for return */ - R3.finalize(); - - if (returnAsSet || - (R1.is_set() && R2.is_set() && R3.n_inp() >= 0 && R3.n_out() == 0)){ - R3.markAsSet(); - R3.invalidate_leading_info(); - } - R1 = Relation(); - R2 = Relation(); - return R3; -} - - -// -// Scramble each relation's variables and merge these relations -// together. Support variable mapping to and from existentials. -// Unspecified variables in mapping are mapped to themselves by -// default. It intends to replace MapRel1 and MapAndCombineRel2 -// functions (the time saved by grafting formula tree might be -// neglegible when compared to the simplification cost). -// -Relation merge_rels(Tuple<Relation> &R, const Tuple<std::map<Variable_ID, std::pair<Var_Kind, int> > > &mapping, const Tuple<bool> &inverse, Combine_Type ctype, int number_input, int number_output) { - const int m = R.size(); - assert(mapping.size() == m && inverse.size() == m); - // skip_set_checks++; - - // if new relation's arity is not given, calculate it on demand - if (number_input == -1) { - number_input = 0; - for (int i = 1; i <= m; i++) { - for (int j = R[i].n_inp(); j >= 1; j--) { - Variable_ID v = R[i].input_var(j); - std::map<Variable_ID, std::pair<Var_Kind, int> >::const_iterator p = mapping[i].find(v); - if (p == mapping[i].end()) { - number_input = j; - break; - } - } - - for (std::map<Variable_ID, std::pair<Var_Kind, int> >::const_iterator j = mapping[i].begin(); j != mapping[i].end(); j++) { - if ((*j).second.first == Input_Var || (*j).second.first == Set_Var) - number_input = max(number_input, (*j).second.second); - } - } - } - - if (number_output == -1) { - number_output = 0; - for (int i = 1; i <= m; i++) { - for (int j = R[i].n_out(); j >= 1; j--) { - Variable_ID v = R[i].output_var(j); - std::map<Variable_ID, std::pair<Var_Kind, int> >::const_iterator p = mapping[i].find(v); - if (p == mapping[i].end()) { - number_output = j; - break; - } - } - for (std::map<Variable_ID, std::pair<Var_Kind, int> >::const_iterator j = mapping[i].begin(); j != mapping[i].end(); j++) { - if ((*j).second.first == Output_Var) - number_output = max(number_output, (*j).second.second); - } - } - } - - Relation R2(number_input, number_output); - F_Exists *fe = R2.add_exists(); - Formula *f_root; - switch (ctype) { - case Comb_And: - f_root = fe->add_and(); - break; - case Comb_Or: - f_root = fe->add_or(); - break; - default: - assert(0); // unsupported merge type - } - - std::map<int, Variable_ID> seen_exists_by_num; - std::map<Variable_ID, Variable_ID> seen_exists_by_id; - - for (int i = 1; i <= m; i++) { - F_Or *fo; - if (inverse[i]) - fo = f_root->add_not()->add_or(); - else - fo = f_root->add_or(); - - for (DNF_Iterator di(R[i].query_DNF()); di; di++) { - F_And *f = fo->add_and(); - - for (GEQ_Iterator gi(*di); gi; gi++) { - GEQ_Handle h = f->add_GEQ(); - for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - std::map<Variable_ID, std::pair<Var_Kind, int> >::const_iterator p = mapping[i].find(v); - if (p == mapping[i].end()) { - switch (v->kind()) { - // case Set_Var: - case Input_Var: { - int pos = v->get_position(); - h.update_coef(R2.input_var(pos), cvi.curr_coef()); - break; - } - case Output_Var: { - int pos = v->get_position(); - h.update_coef(R2.output_var(pos), cvi.curr_coef()); - break; - } - case Exists_Var: - case Wildcard_Var: { - std::map<Variable_ID, Variable_ID>::iterator p2 = seen_exists_by_id.find(cvi.curr_var()); - Variable_ID e; - if (p2 == seen_exists_by_id.end()) { - e = fe->declare(); - seen_exists_by_id[cvi.curr_var()] = e; - } - else - e = (*p2).second; - h.update_coef(e, cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = R2.get_local(g); - else - v2 = R2.get_local(g, v->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(0); // shouldn't happen if input relations are simplified - } - } - else { - switch ((*p).second.first) { - // case Set_Var: - case Input_Var: { - int pos = (*p).second.second; - h.update_coef(R2.input_var(pos), cvi.curr_coef()); - break; - } - case Output_Var: { - int pos = (*p).second.second; - h.update_coef(R2.output_var(pos), cvi.curr_coef()); - break; - } - case Exists_Var: - case Wildcard_Var: { - int pos = (*p).second.second; - std::map<int, Variable_ID>::iterator p2 = seen_exists_by_num.find(pos); - Variable_ID e; - if (p2 == seen_exists_by_num.end()) { - e = fe->declare(); - seen_exists_by_num[pos] = e; - } - else - e = (*p2).second; - h.update_coef(e, cvi.curr_coef()); - break; - } - default: - assert(0); // mapped to unsupported variable type - } - } - } - h.update_const((*gi).get_const()); - } - - for (EQ_Iterator ei(*di); ei; ei++) { - EQ_Handle h = f->add_EQ(); - for (Constr_Vars_Iter cvi(*ei); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - std::map<Variable_ID, std::pair<Var_Kind, int> >::const_iterator p = mapping[i].find(v); - if (p == mapping[i].end()) { - switch (v->kind()) { - // case Set_Var: - case Input_Var: { - int pos = v->get_position(); - h.update_coef(R2.input_var(pos), cvi.curr_coef()); - break; - } - case Output_Var: { - int pos = v->get_position(); - h.update_coef(R2.output_var(pos), cvi.curr_coef()); - break; - } - case Exists_Var: - case Wildcard_Var: { - std::map<Variable_ID, Variable_ID>::iterator p2 = seen_exists_by_id.find(v); - Variable_ID e; - if (p2 == seen_exists_by_id.end()) { - e = fe->declare(); - seen_exists_by_id[v] = e; - } - else - e = (*p2).second; - h.update_coef(e, cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = R2.get_local(g); - else - v2 = R2.get_local(g, v->function_of()); - h.update_coef(v2, cvi.curr_coef()); - break; - } - default: - assert(0); // shouldn't happen if input relations are simplified - } - } - else { - switch ((*p).second.first) { - // case Set_Var: - case Input_Var: { - int pos = (*p).second.second; - h.update_coef(R2.input_var(pos), cvi.curr_coef()); - break; - } - case Output_Var: { - int pos = (*p).second.second; - h.update_coef(R2.output_var(pos), cvi.curr_coef()); - break; - } - case Exists_Var: - case Wildcard_Var: { - int pos = (*p).second.second; - std::map<int, Variable_ID>::iterator p2 = seen_exists_by_num.find(pos); - Variable_ID e; - if (p2 == seen_exists_by_num.end()) { - e = fe->declare(); - seen_exists_by_num[pos] = e; - } - else - e = (*p2).second; - h.update_coef(e, cvi.curr_coef()); - break; - } - default: - assert(0); // mapped to unsupported variable type - } - } - } - h.update_const((*ei).get_const()); - } - } - } - - // skip_set_checks--; - - if (number_output == 0) { - R2.markAsSet(); - // R2.invalidate_leading_info(); - } - - return R2; -} - -} // namespace diff --git a/omegalib/omega/src/basic/ConstString.cc b/omegalib/omega/src/basic/ConstString.cc deleted file mode 100644 index 7d2ec1e..0000000 --- a/omegalib/omega/src/basic/ConstString.cc +++ /dev/null @@ -1,134 +0,0 @@ -#include <basic/ConstString.h> -#include <stdlib.h> -#include <stdio.h> -#include <assert.h> -#include <string> -#include <string.h> - -/* static const int CS_HashTable_Size = 1000; */ -/* static ConstStringRep *hashTable[CS_HashTable_Size] = {0}; */ - -namespace omega { - -const int CS_HashTable_Size = 1000; -class CS_HashTable { -public: - ConstStringRep *p[CS_HashTable_Size]; - CS_HashTable(); - ~CS_HashTable(); -}; - -namespace { - CS_HashTable hashTable; -} - -CS_HashTable::CS_HashTable() { - for (int i = 0; i < CS_HashTable_Size; i++) - p[i] = NULL; - } - -CS_HashTable::~CS_HashTable() { - for (int i = 0; i < CS_HashTable_Size; i++) { - ConstStringRep *t = p[i]; - while (t != NULL) { - ConstStringRep *tt = t->nextInBucket; - delete []t->name; - delete t; - t = tt; - } - } -} - -Const_String::Const_String() { - rep = 0; -} - -void Const_String::buildRep(const char* t) { - int hash = 0; - const char *s = t; - while (*s != '\0') - hash = hash*33 + *s++; - int hashBucket = hash % CS_HashTable_Size; - if (hashBucket < 0) hashBucket += CS_HashTable_Size; - assert(0 <= hashBucket && hashBucket < CS_HashTable_Size); - ConstStringRep **q = &(hashTable.p[hashBucket]); - ConstStringRep *p = *q; - while (p != 0) { - if (strcmp(p->name,t) == 0) break; - q = &p->nextInBucket; - p = *q; - } - if (p!= 0) rep = p; - else { - rep = new ConstStringRep(t); - *q = rep; - } -} - -Const_String::Const_String(const char * t) { - buildRep(t); -} - -Const_String::Const_String(const std::string &s) { - buildRep(s.c_str()); -} - -Const_String::operator const char*() const { - if (!rep) return 0; - return rep->name; -} - -Const_String::operator std::string() const { - if (!rep) return std::string(""); - return std::string(rep->name); -} - -int Const_String::operator++(int) { - return rep->count++; -} - -int Const_String::operator++() { - return ++rep->count; -} - -int Const_String:: operator--(int) { - return rep->count--; -} - -int Const_String:: operator--() { - return --rep->count; -} - -int operator ==(const Const_String &x, const Const_String &y) { - return x.rep == y.rep; -} - -int operator !=(const Const_String &x, const Const_String &y) { - return x.rep != y.rep; -} - -int operator <(const Const_String &x, const Const_String &y) { - return (strcmp(x.rep->name,y.rep->name) < 0); -} - -int operator >(const Const_String &x, const Const_String &y) { - return (strcmp(x.rep->name,y.rep->name) > 0); -} - -Const_String:: operator int() const { - return rep != 0; -} - -int Const_String::null() const { - return rep == 0; -} - -ConstStringRep:: ConstStringRep(const char *t) { - count = 0; - nextInBucket = 0; - char *s = new char[1+strlen(t)]; - strcpy(s,t); - name = s; -} - -} // namespace diff --git a/omegalib/omega/src/basic/Link.cc b/omegalib/omega/src/basic/Link.cc deleted file mode 100644 index 50b9441..0000000 --- a/omegalib/omega/src/basic/Link.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include <basic/Link.h> - -namespace omega { - -#if ListElementFreeList - static List_Element<void*> *_kludgy_List_Element_free_list_pointer; -// we rely on the fact that that is initialized to 0 before any -// constructor-based initialization that could call List_Element::new. - - void *kludgy_List_Element_new(size_t size) - { - void *mem; - if (size == sizeof(List_Element<void*>) && - _kludgy_List_Element_free_list_pointer) - { - List_Element<void*> *it = _kludgy_List_Element_free_list_pointer; - _kludgy_List_Element_free_list_pointer = it->tail; - mem = it; - } - else - mem = ::operator new(size); - - return mem; - } - - void kludgy_List_Element_delete(void *ptr, size_t size) - { - if (ptr) - if (size == sizeof(List_Element<void*>)) - { - List_Element<void*> *it = (List_Element<void*> *) ptr; - it->tail = _kludgy_List_Element_free_list_pointer; - _kludgy_List_Element_free_list_pointer = it; - } - else - ::operator delete(ptr); - } - -#endif - -} // namespace diff --git a/omegalib/omega/src/closure.cc b/omegalib/omega/src/closure.cc deleted file mode 100644 index 416a3e7..0000000 --- a/omegalib/omega/src/closure.cc +++ /dev/null @@ -1,2100 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - Copyright (C) 2009-2011 West Pomeranian University of Technology, Szczecin - All Rights Reserved. - - Purpose: - All calculations of closure are now here. - - Notes: - Related paper: - - "Transitive closure of infinite graphs and its applications", - Wayne Kelly, William Pugh, Evan Rosser and Tatiana Shpeisman, IJPP 1996. - - "Computing the Transitive Closure of a Union of Affine Integer Tuple - Relations", Anna Beletska, Denis Barthou, Wlodzimierz Bielecki and - Albert Cohen, COCOA 2009. - - "An Iterative Algorithm of Computing the Transitive Closure of a Union - of Parameterized Affine Integer Tuple Relations", Bielecki Wlodzimierz, - Klimek Tomasz, Palkowski Marek and Anna Beletska, COCOA 2010. - - History: - 12/27/09 move ConicClosure here, Chun Chen - 01/19/11 new closure algorithms, Klimek Tomzsz - 02/02/11 move VennDiagramFrom here, Chun Chen -*****************************************************************************/ - -#include <typeinfo> -#include <assert.h> -#include <omega.h> -#include <omega/hull.h> -#include <basic/Iterator.h> -#include <basic/List.h> -#include <basic/SimpleList.h> - -namespace omega { - -void InvestigateClosure(Relation r, Relation r_closure, Relation bounds); -void print_given_bounds(const Relation & R1, NOT_CONST Relation& input_Bounds); -#define printConjunctClosure (closure_presburger_debug & 0x1) -#define detailedClosureDebug (closure_presburger_debug & 0x2) - - -#ifdef TC_STATS -extern int clock_diff(); -extern void start_clock(); -FILE *statsfile; -int singles, totals=0; -#endif - -int closure_presburger_debug = 0; - - -Relation VennDiagramForm(NOT_CONST Relation &Context_In, - Tuple<Relation> &Rs, - int next, - bool anyPositives, - int weight) { - Relation Context = consume_and_regurgitate(Context_In); - if (hull_debug) { - fprintf(DebugFile,"[VennDiagramForm, next = %d, anyPositives = %d, weight = %d \n", next,anyPositives,weight); - fprintf(DebugFile,"context:\n"); - Context.prefix_print(DebugFile); - } - if (anyPositives && weight > 3) { - Context.simplify(); - if (!Context.is_upper_bound_satisfiable()) { - if (hull_debug) - fprintf(DebugFile,"] not satisfiable\n"); - return Context; - } - weight = 0; - } - if (next > Rs.size()) { - if (!anyPositives) { - if (hull_debug) - fprintf(DebugFile,"] no positives\n"); - return Relation::False(Context); - } - Context.simplify(); - if (hull_debug) { - fprintf(DebugFile,"] answer is:\n"); - Context.prefix_print(DebugFile); - } - return Context; - } - Relation Pos = VennDiagramForm(Intersection(copy(Context),copy(Rs[next])), - Rs, - next+1, - true, - weight+2); - Relation Neg = VennDiagramForm(Difference(Context,copy(Rs[next])), - Rs, - next+1, - anyPositives, - weight+1); - if (hull_debug) { - fprintf(DebugFile,"] VennDiagramForm\n"); - fprintf(DebugFile,"pos part:\n"); - Pos.prefix_print(DebugFile); - fprintf(DebugFile,"neg part:\n"); - Neg.prefix_print(DebugFile); - } - return Union(Pos,Neg); -} - - -Relation VennDiagramForm(Tuple<Relation> &Rs, NOT_CONST Relation &Context_In) { - Relation Context = consume_and_regurgitate(Context_In); - if (Context.is_null()) Context = Relation::True(Rs[1]); - if (hull_debug) { - fprintf(DebugFile,"Starting computation of VennDiagramForm\n"); - fprintf(DebugFile,"Context:\n"); - Context.prefix_print(DebugFile); - for(int i = 1; i <= Rs.size(); i++) { - fprintf(DebugFile,"#%d:\n",i); - Rs[i].prefix_print(DebugFile); - } - } - return VennDiagramForm(Context,Rs,1,false,0); -} - -Relation VennDiagramForm(NOT_CONST Relation &R_In, NOT_CONST Relation &Context_In) { - Relation R = consume_and_regurgitate(R_In); - Relation Context = consume_and_regurgitate(Context_In); - Tuple<Relation> Rs; - for (DNF_Iterator c(R.query_DNF()); c.live(); ) { - Rs.append(Relation(R,c.curr())); - c.next(); - } - return VennDiagramForm(Rs,Context); -} - - -Relation ConicClosure (NOT_CONST Relation &R) { - int n = R.n_inp(); - if (n != R.n_out()) - throw std::invalid_argument("conic closure must have the same input arity and output arity"); - - return DeltasToRelation(ConicHull(Deltas(R)), n, n); -} - - -bool is_lex_forward(Relation R) { - if(R.n_inp() != R.n_out()) { - fprintf(stderr, "relation has wrong inputs/outpts\n"); - exit(1); - } - Relation forw(R.n_inp(), R.n_out()); - F_Or * o = forw.add_or(); - for(int a = 1; a <= forw.n_inp(); a++) { - F_And * andd = o->add_and(); - GEQ_Handle g = andd->add_GEQ(); - g.update_coef(input_var(a), -1); - g.update_coef(output_var(a), 1); - g.update_const(1); - for(int b = 1; b < a; b++) { - EQ_Handle e = andd->add_EQ(); - e.update_coef(input_var(a),1); - e.update_coef(output_var(a),-1); - } - } - Relation test = Difference(R, forw); - return !test.is_upper_bound_satisfiable(); -} - - -static Relation compose_n(NOT_CONST Relation &input_r, int n) { - Relation r = consume_and_regurgitate(input_r); - if (n == 1) - return r; - else - return Composition(r, compose_n(copy(r), n-1)); -} /* compose_n */ - - - - -Relation approx_closure(NOT_CONST Relation &input_r, int n) { - Relation r = consume_and_regurgitate(input_r); - Relation r_closure; - - r_closure=r; - int i; - for(i=2; i<=n; i++) - r_closure=Union(r_closure,compose_n(copy(r), n)); - r_closure = Union(r_closure, Relation::Unknown(r_closure)); - - return r_closure; -} /* approx_closure */ - - -static bool is_closure_itself(NOT_CONST Relation &r) { - return Must_Be_Subset(Composition(copy(r),copy(r)),copy(r)); -} - - -/***** - * get a D form of the Relation (single conjunct). - * D = {[ i_1,i_2,...,i_m] -> [j_1, j_2, ..., j_m ] : - * (forall p, 1<= p <= m) L_p <= j_p - i_p <= U_p && - * j_p - i_p == M_p alpha_p}; - * Right now only wildcards that are in stride constraints are treated. - *****/ - -Relation get_D_form (Relation & R) { - Relation D(R.n_inp(), R.n_out()); - - R.make_level_carried_to(R.n_inp()); - assert(R.has_single_conjunct()); - int n_zero=0; - for (DNF_Iterator d(R.query_DNF()); d.live(); d.next()) - n_zero=d.curr()->query_guaranteed_leading_0s(); - - Relation Diff=Deltas(copy(R)); - - if (detailedClosureDebug) { - fprintf(DebugFile, "The relation projected onto differencies is:\n"); - Diff.print_with_subs(DebugFile); - } - - - /* now form D */ - - int i; - coef_t l,u; - F_And * N = D.add_and(); - GEQ_Handle g; - for (i=1; i<=Diff.n_set(); i++) { - Diff.query_variable_bounds(Diff.set_var(i), l,u); -/* if (i== n_zero+1 && l==negInfinity) - l=1; */ - if (l!=negInfinity) { - g=N->add_GEQ(); - g.update_coef(D.input_var(i),-1); - g.update_coef(D.output_var(i),1); - g.update_const(-l); - g.finalize(); - } - if (u!=posInfinity) { - g=N->add_GEQ(); - g.update_coef(D.input_var(i),1); - g.update_coef(D.output_var(i),-1); - g.update_const(u); - g.finalize(); - } - } - - /* add all stride constrains if they do exist */ - - Conjunct *c = Diff.single_conjunct(); - - if (c->locals().size()>0) {// there are local variables - // now go through all the equalities - - coef_t coef=0; - int pos=0; - for (EQ_Iterator eq = c->EQs(); eq.live(); eq.next()) { - // constraint is in stride form if it has 2 vars, - // one of which is wildcard. Count number if vars and wildcard vars - int nwild=0,nvar=0; - - for (Constr_Vars_Iter cvi(*eq, false); cvi; cvi++) { - if ((*cvi).var->kind() == Global_Var) - continue; - else if ((*cvi).var->kind() == Wildcard_Var) { - coef=(*cvi).coef; - nwild++; - } - else - pos=(*cvi).var->get_position(); - nvar++; - } - if (nvar==2 && nwild==1) { //stride constraint - EQ_Handle e=N->add_stride(coef); - e.update_coef(D.input_var(pos),-1); - e.update_coef(D.output_var(pos),1); - e.finalize(); - } - } - } // end search of stride constrains - - D.finalize(); - D.simplify(); - return D; -} /* end get_D_form */ - -/**** - * get relation A x A describing a region of domain and range: - * A=Hull(Domain(R), Range(R)) intersection IterationSpace - * returns cross product A x A - ***/ - -Relation form_region(const Relation &R, const Relation& IterationSpace) { - Relation H=Union(Domain(copy(R)), Range(copy(R))); - H.simplify(1,1); - H = EQs_to_GEQs(H); - H=Hull(H); - Relation A=Intersection(H, copy(IterationSpace)); - Relation A1=A; - return Cross_Product(A,A1); -} - -Relation form_region1(const Relation &R, const Relation& IterationSpace) { - Relation Dom=Intersection(Domain(copy(R)), copy(IterationSpace)); - Relation Ran=Intersection(Range(copy(R)), copy(IterationSpace)); - return Cross_Product(Dom,Ran); -} - - -/**** - * Check if we can use D instead of R - * i.e. D intersection (A cross A) is Must_Be_Subset of R - ***/ - -bool isD_OK(Relation &R, Relation &D, Relation &AxA) { - Relation B=Intersection(copy(D), copy(AxA)); - B.simplify(); - - if (detailedClosureDebug) { - fprintf(DebugFile, "Intersection of D and AxA is:\n"); - B.print_with_subs(DebugFile); - } - assert (Must_Be_Subset(copy(R),copy(B))); - - return Must_Be_Subset(B, copy(R)); -} - - - -/**** - * check if the constraint is a stride one. Here we say that an equality - * constraint is a stride constraint if it has exatly one wildcard. - * The function returns number of the wildcards in the constraint. - * So if we know that constraint is from the relation in D form, then - * it cannot have more than 1 wildcard variables, and the result of - * this functions can be treated as bool. - ***/ - -static int is_stride(const EQ_Handle &eq) { - int n=0; - - for (Constr_Vars_Iter cvi(eq,true); cvi; cvi++) - n++; - - return n; -} - - - -/***** - * check if the constraint is in the form i_k' - i_k comp_op c - * return v - the number of the var and the type of the comp_op: - * 1 - >, -1 - <, 0 - not in the right form - * if this is equality constraint in the right form any 1 or -1 can be - * returned - ******/ - -static coef_t is_constraint_in_D_form(Relation &r, const Constraint_Handle &h, int &v) { - v=-1; - coef_t c_out = 0; - for (int i = 1; i <= r.n_inp(); i++) { - coef_t c_in = h.get_coef(r.input_var(i)); - if (c_in) { - if (v!=-1) - return 0; - v=i; - c_out = h.get_coef(r.output_var(i)); - - // special case for modular constraint -- by chun 04/02/2009 - if (h.has_wildcards() && typeid(h) == typeid(EQ_Handle)) { - coef_t g = 0; - for (Constr_Vars_Iter cvi(h, true); cvi; cvi++) - g = gcd(g, abs(cvi.curr_coef())); - c_in = int_mod_hat(c_in, g); - c_out = int_mod_hat(c_out, g); - - if (g == 2) { - if (c_in * c_out == 1) { - c_out = -1; - } - else - return 0; - } - else if (c_in * c_out != -1) - return 0; - } - // other cases - else if (c_in * c_out != -1) - return 0; - } - } - return c_out; -} - - -/*** - * Check if relation is in the D form - * D = {[ i_1,i_2,...,i_m] -> [j_1, j_2, ..., j_m ] : - * (forall p, 1<= p <= m) L_p <= j_p - i_p <= U_p && - * j_p - i_p == M_p alpha_p}; - * Right now we do not check for multiple stride constraints for one var. - * Probably they cannot exist in simplified conjunct - * This function will be used in assertions - *****/ - -bool is_in_D_form(Relation & D) { - /* check that D has one conjunct */ - - if (! D.has_single_conjunct()) - return false; - - Conjunct * c=D.single_conjunct(); - - if (D.global_decls()->size() != 0) // there are symbolic vars - return false; - - if (D.n_inp() != D.n_out()) - return false; - - int n=D.n_inp(); - - Tuple<int> bl(n), bu(n); - - for (int i=1; i<= n; i++) - bl[i]=bu[i]=0; - - int v; - coef_t res; - - for (EQ_Iterator eq = c->EQs(); eq.live(); eq.next()) { - if ((res=is_constraint_in_D_form(D,*eq,v))==0) - return false; - int n_wild=is_stride(*eq); - if (n_wild>=2) - return false; - if (n_wild==0) { // not stride constraint - if (bl[v] || bu[v]) - return false; - bl[v]=bu[v]=1; - } - } - - for (GEQ_Iterator geq = c->GEQs(); geq.live(); geq.next()) { - if ((res=is_constraint_in_D_form(D,*geq,v))==0) - return false; - if ((res>0 && bl[v]) || (res<0 && bu[v])) - return false; - if (res>0) - bl[v]=1; - else - bu[v]=1; - } - - return true; -} - - -#define get_D_plus_form(R) (get_D_closure(R,1)) -#define get_D_star_form(R) (get_D_closure(R,0)) - -/**** - * Get D+ or D* from the relation that is in D form - * To get D+ calculate: - * D+= {[i1, i2 .. i_m] -> {j1, j2, ..., j_m]: - * exists s s.t. s>=1 and - * (forall p, 1<= p <= m) L_p * s<= j_p - i_p <= U_p*s && - * j_p - i_p == M_p alpha_p}; - * To get D* calculate almost the same relation but s>=0. - * Parameter n is 1 for getting D+ and 0 for D* - ****/ - - -Relation get_D_closure(Relation & D, int n) { - assert (is_in_D_form(D)); - assert(n==0 || n==1); - - Conjunct *c=D.single_conjunct(); - - Relation R(D.n_inp(), D.n_out()); - - F_Exists * ex = R.add_exists(); - Variable_ID s = ex->declare("s"); - F_And * N = ex->add_and(); - - /* add s>=1 or s>=0 */ - - GEQ_Handle geq= N->add_GEQ(); - geq.update_coef(s,1); - geq.update_const(-n); - geq.finalize(); - - - /* copy and modify all the EQs */ - - for (EQ_Iterator j= c->EQs(); j.live(); j.next()) { - EQ_Handle eq=N->add_EQ(); - copy_constraint(eq, *j); - - // if it's stride constraint do not change it - - if (!is_stride(*j)) { - /* eq is j_k -i_k = c, replace c buy s*c */ - - eq.update_coef(s, (*j).get_const()); - eq.update_const(-(*j).get_const()); - } - eq.finalize(); - } - - /* copy and modify all the GEQs */ - - for (GEQ_Iterator gi= c->GEQs(); gi.live(); gi.next()) { - geq=N->add_GEQ(); - copy_constraint(geq, *gi); - - /* geq is j_k -i_k >=c or i_k-j_k >=c, replace c buy s*c */ - - geq.update_coef(s,(*gi).get_const()); - geq.update_const(-(*gi).get_const()); - geq.finalize(); - } - - R.finalize(); - - if (detailedClosureDebug) { - fprintf(DebugFile, "Simplified D%c is:\n", n==1?'+':'*'); - R.print_with_subs(DebugFile); - } - - return R; -} - - -/*** - * Check if we can easily calculate the D* (D* will be convex). - * We can calculate D* if all differences have both lower and upper - * bounds to be non -/+ infinity - ***/ - - -bool can_get_D_star_form(Relation &D) { - assert(is_in_D_form(D)); - Conjunct *c=D.single_conjunct(); - - int n=D.n_inp(); - Tuple<int> bl(n), bu(n); - int i; - - for (i=1; i<=n; i++) - bl[i]=bu[i]=0; - - for (EQ_Iterator eq = c->EQs(); eq.live(); eq.next()) { - // do not check stride constraints - if (!is_stride(*eq)) { - for (i=1; i<=n; i++) { - if ((*eq).get_coef(D.input_var(i)) !=0 ) - bl[i]=bu[i]=1; - } - } - } - - - for (GEQ_Iterator geq = c->GEQs(); geq.live(); geq.next()) { - for (i=1; i<=n; i++) { - coef_t k; - if ((k=(*geq).get_coef(D.input_var(i))) != 0) { - if (k>0) - bu[i]=1; - else - bl[i]=1; - } - } - } - - for (i=1; i<=n; i++) - if (!bl[i] || !bu[i]) - return false; - - return true; -} - - - -/***** - * Check whether the relation intersect with identity or not - ****/ - -bool does_intersect_with_identity(Relation &R) { - assert (R.n_inp() == R.n_out()); - - Relation I=Identity(R.n_inp()); - Relation C=Intersection(I, copy(R)); - return C.is_upper_bound_satisfiable(); -} - -bool does_include_identity(Relation &R) { - Relation I=Identity(R.n_inp()); - return Must_Be_Subset(I, copy(R)); -} - -/***** - * Bill's closure: check if it is possible to calculate transitive closure - * of the relation using the Bill's algorithm. - * Return the transitive closure relation if it is possible and null relation - * otherwise - ****/ - -bool Bill_closure(Relation &R, Relation& IterationSpace, Relation & R_plus, Relation & R_star) { -#ifdef TC_STATS - fprintf(statsfile,"start bill closure\n"); -#endif - - if (does_include_identity(R)) - return false; - - if (detailedClosureDebug) { - fprintf(DebugFile, "\nApplying Bill's method to calculate transitive closure\n"); - } - - // get D and AxA - Relation D=get_D_form(R); - - - if (detailedClosureDebug) { - fprintf(DebugFile,"\n D form for the relation:\n"); - D.print_with_subs(DebugFile); - } - - Relation AxA=form_region1(R, IterationSpace); - - if (detailedClosureDebug) { - fprintf(DebugFile, "\n AxA for the relation:\n"); - AxA.print_with_subs(DebugFile); - } - - // compute R_+ - - R_plus=Intersection(get_D_plus_form(D), copy(AxA)); - - if (detailedClosureDebug) { - fprintf(DebugFile, "\nR_+= D+ intersection AxA is:\n"); - R_plus.print_with_subs(DebugFile); - } - - // compute R_* - R_star=Intersection(get_D_star_form(D), form_region(R,IterationSpace)); - - if (detailedClosureDebug) { - fprintf(DebugFile, "\nR_*= D* intersection AxA is:\n"); - R_star.print_with_subs(DebugFile); - } - -/* Check that R_+ is acyclic. - Given the way we constructed R_+, R_+=(R_+)+. - As a result it's enough to verify that R_+ intersection I = 0, - to prove that R_+ is acyclic. -*/ - - if (does_intersect_with_identity(R_plus)) { - if (detailedClosureDebug) { - fprintf(DebugFile,"R_+ is not acyclic.\n"); - } - return false; - } - - //Check R_+ - R is Must_Be_Subset of R o R_+ - - if (!Must_Be_Subset(Difference(copy(R_plus), copy(R)), Composition(copy(R), copy(R_plus)))) { -#if defined(TC_STATS) - fprintf(statsfile, "R_+ -R is not a Must_Be_Subset of R o R_+\n"); - fprintf(statsfile, "Bill Method is not applicable\n"); -#endif - return false; - } - if (detailedClosureDebug) { - fprintf(DebugFile, "R_+ -R is a Must_Be_Subset of R o R_+ - good\n"); - } - -// if we are here than all tests worked, and R_+ is transitive closure -// of R. - -#if defined(TC_STATS) - fprintf(statsfile,"\nAll three tests succeeded -- exact closure found\n"); - fprintf(statsfile, "Transitive closure is R_+\n"); -#endif -// assert(isD_OK(R,D,AxA)); - return true; -} - - -/********************************************************************** - * print the relation given the bounds on the iteration space - * If the bounds are unknown (Bounds is Null), then just print relation - * itself - ****/ - -void print_given_bounds( const Relation& R1, NOT_CONST Relation& input_Bounds) { - Relation & Bounds = (Relation &)input_Bounds; - Relation r; - if (Bounds.is_null()) - r=R1; - else - r = Gist(copy(R1),copy(Bounds),1); - r.print_with_subs(DebugFile); -} - -/********************************************************************** - * Investigate closure: - * checks if the copmuted approximation on the Transitive closure - * is upper and lower bound. If it's both - it's exact. - * This function doesn't return any value. It's just prints a lot - * of debug output - * INPUT: - * r - relation - * r_closure - approximation on r+. - * F - iteration space - **********************************************************************/ - -void InvestigateClosure(Relation r, Relation r_closure, Relation F) { - Relation r3; - bool LB_res, UB_res; - - if (!F.is_null()) - F=Cross_Product(copy(F),copy(F)); - - fprintf(DebugFile, "\n\n--->investigating the closure of the relation:\n"); - print_given_bounds(r,F); - - fprintf(DebugFile, "\nComputed closure is:\n"); - print_given_bounds(r_closure,F); - - r3=Composition(copy(r),copy(r_closure)); - r3.simplify(1,1); - - r3=Union(r3,Composition(copy(r_closure),copy(r))); - r3.simplify(1,1); - - r3=Union(r3,copy(r)); - r3.simplify(1,1); - - Relation remainder = Difference(copy(r3),copy(r_closure)); - - if (!F.is_null()) { - r3=Gist(r3,F,1); - } - r3.simplify(1,1); - - if (!F.is_null()) { - r_closure=Gist(r_closure,F,1); - } - r_closure.simplify(1,1); - - LB_res= Must_Be_Subset(copy(r_closure),copy(r3)); - - UB_res=Must_Be_Subset(copy(r3),copy(r_closure)); - - fprintf(DebugFile,"\nThe results of checking closure (gist) are:\n"); - fprintf(DebugFile,"LB - %s, UB - %s\n", LB_res?"YES":"NO", UB_res?"YES":"NO"); - - if (!UB_res) { - remainder.simplify(2,2); - fprintf(DebugFile,"Dependences not included include:\n"); - print_given_bounds(remainder,F); - } -} - - - -/**** - * Transitive closure of the relation containing single conjunct - ****/ - -bool ConjunctTransitiveClosure (NOT_CONST Relation & input_R, Relation & IterationSpace, Relation & R_plus, Relation & R_star) { - Relation R = consume_and_regurgitate(input_R); - assert(R.has_single_conjunct()); - - if (printConjunctClosure) { - fprintf(DebugFile,"\nTaking closure of the single conjunct: [\n"); - R.print_with_subs(DebugFile); - } -#ifdef TC_STATS - fprintf(statsfile,"start conjuncttransitiveclosure\n"); - singles++; -#endif - - if (is_closure_itself(copy(R))) { -#ifdef TC_STATS - fprintf(statsfile, "Relation is closure itself\n"); -#endif - int ndim_all, ndim_domain; - R.dimensions(ndim_all,ndim_domain); - if (ndim_all == ndim_domain +1) { - Relation ispace = Cross_Product(Domain(copy(R)),Range(copy(R))); - Relation R_zero = Intersection(copy(ispace),Identity(R.n_inp())); - R_star = Hull(Union(copy(R),R_zero),true,1,ispace); - R_plus=R; - if (printConjunctClosure) { - fprintf(DebugFile, "\n] For this relation R+=R\n"); - fprintf(DebugFile,"R*:\n"); - R_star.print_with_subs(DebugFile); - } - return true; - } - else { - R_star=R; - R_plus=R; - if (printConjunctClosure) { - fprintf(DebugFile, "\n] For this relation R+=R, not appropriate for R*\n"); - } - return false; - } - } - else { - bool done=false; - if (!IterationSpace.is_null()) { -// Bill's closure requires the information about Iteration Space. -// So if IterationSpace is NULL, i.e. unknown( e.g. when calling from parser, -// we do not do Bill's closure - - done = Bill_closure(R, IterationSpace, R_plus, R_star); -#ifdef TC_STATS - fprintf(statsfile,"Bill closure is %sapplicable\n",done?"":"not "); -#endif - if (printConjunctClosure) { - if (!done) - fprintf(DebugFile, "Bill's closure is not applicable\n"); - else { - fprintf(DebugFile, "Bill's closure is applicable\n"); - fprintf (DebugFile, " For R:\n"); - R.print_with_subs(DebugFile); - fprintf(DebugFile, "R+ is:\n"); - R_plus.print_with_subs(DebugFile); - fprintf(DebugFile, "R* is:\n"); - R_star.print_with_subs(DebugFile); - fprintf(DebugFile, "\n"); - InvestigateClosure(R, R_plus, IterationSpace); - } - } - } - if (done) { - if (printConjunctClosure) { - fprintf(DebugFile, "]\n"); - } - return true; - } - else { - // do and check approximate closure (several compositions) - R_plus = approx_closure(copy(R), 2); -#ifdef TC_STATS - fprintf(statsfile,"Approximating closure with 2 compositions\n"); -#endif - if (printConjunctClosure) { - fprintf(DebugFile, "Doing approximate closure\n"); - InvestigateClosure(R, R_plus, IterationSpace); - } - } //end else (!done after Bill Closure or Iteration space is NULL) - - if (printConjunctClosure) { - fprintf(DebugFile, "]\n"); - } - } - return false; -} - - -/********************************************************************* - * try to get conjunct transitive closure. - * it we can get it easy get it, return true. - * if not - return false - ********************************************************************/ - - -bool TryConjunctTransitiveClosure (NOT_CONST Relation & input_R, Relation & IterationSpace, Relation & R_plus) { - Relation R = consume_and_regurgitate(input_R); - assert(R.has_single_conjunct()); -#ifdef TC_STATS - fprintf(statsfile,"start tryconjuncttransitiveclosure\n"); - singles++; -#endif - - if (printConjunctClosure) { - fprintf(DebugFile,"\nTrying to take closure of the single conjunct: [\n"); - R.print_with_subs(DebugFile); - } - - if (is_closure_itself(copy(R))) { -#ifdef TC_STATS - fprintf(statsfile, "Relation is closure itself, leave alone (try)\n"); -#endif - if (printConjunctClosure) - fprintf(DebugFile, "\n ]The relation is closure itself. Leave it alone\n"); - return false; - } - else { - bool done; - assert(!IterationSpace.is_null()); - Relation R_star; - done = Bill_closure(R, IterationSpace, R_plus, R_star); -#ifdef TC_STATS - fprintf(statsfile, "Bill closure is %sapplicable (try)\n", done?"":"NOT "); -#endif - if (printConjunctClosure) { - if (!done) - fprintf(DebugFile, "]Bill's closure is not applicable\n"); - else { - fprintf(DebugFile, "]Bill's closure is applicable\n"); - fprintf (DebugFile, " For R:\n"); - R.print_with_subs(DebugFile); - fprintf(DebugFile, "R+ is:\n"); - R_plus.print_with_subs(DebugFile); - fprintf(DebugFile, "R* is:\n"); - R_star.print_with_subs(DebugFile); - fprintf(DebugFile, "\n"); - InvestigateClosure(R, R_plus, IterationSpace); - } - } - return done; - } - //return false; -} - - -bool Equal (const Relation & r1, const Relation & r2) { - bool res=Must_Be_Subset (copy(r1), copy(r2)); - if (!res) - return false; - return Must_Be_Subset (copy(r2),copy(r1)); -} - - -void appendClausesToList(Simple_List<Relation> &L, Relation &R) { - R.make_level_carried_to(R.n_inp()); - R.simplify(2,2); - for(int depth = R.n_inp(); depth >= -1; depth--) - for (DNF_Iterator d(R.query_DNF()); d.live(); d.next()) - if (d.curr()->query_guaranteed_leading_0s() == depth) { - L.append(Relation(R, d.curr())); - } -} - -void printRelationList(Simple_List<Relation> &L) { - for (Simple_List_Iterator<Relation> li(L); li.live(); li.next()) { - li.curr().print_with_subs(DebugFile); - } -} - -/**** - * Transitive closure of the relation containing multiple conjuncts - * New (Bill's) version - ***/ - -Relation TransitiveClosure0(NOT_CONST Relation &input_r, int maxExpansion, NOT_CONST Relation & input_IterationSpace) { - Relation r = consume_and_regurgitate(input_r); - Relation IterationSpace = consume_and_regurgitate(input_IterationSpace); - - if (closure_presburger_debug) - fprintf(DebugFile, "\n\n[Transitive closure\n\n"); - - Relation result; - -#ifdef TC_STATS -#define TC_RUNS 1 - int in_conj = copy(r).query_DNF()->length(); - totals++; - fprintf(statsfile,"%d closure run\n", totals); - if(is_in_D_form(copy(r))) - fprintf(statsfile, "Relation initially in D form\n"); - else - fprintf(statsfile, "Relation initially NOT in D form\n"); - if(is_lex_forward(copy(r))) - fprintf(statsfile, "Relation is initially lex forw\n"); - else - fprintf(statsfile, "Relation is NOT initially lex forw\n"); - start_clock(); - for(int tc_loop = 1; tc_loop <= TC_RUNS; tc_loop++) { - singles = 0; -#endif - - assert(!r.is_null()); - assert(r.n_inp() == r.n_out()); - - if (r.max_ufs_arity() > 0) { - assert(r.max_ufs_arity() == 0 && "Can't take transitive closure with UFS yet."); - - fprintf(stderr, "Can't take transitive closure with UFS yet."); - exit(1); - } - - r.simplify(2,2); - if (!r.is_upper_bound_satisfiable()) { -#ifdef TC_STATS - int totalTime = clock_diff(); - fprintf(statsfile, "Relation is unsatisfiable\n"); - fprintf(statsfile, "input conj: %d output conj: %d #singe conj closures: %d time: %d\n", - in_conj, copy(result).query_DNF()->length(), - singles, - totalTime/TC_RUNS); -#endif - - - if (closure_presburger_debug) - fprintf(DebugFile, "]TC : relation is false\n"); - return r; - } - - IterationSpace = Hull(Union(Domain(copy(r)),Range(copy(r))), true, 1, IterationSpace); - - if (detailedClosureDebug) { - fprintf(DebugFile, "r is:\n"); - r.print_with_subs(DebugFile); - fprintf(DebugFile, "IS is:\n"); - IterationSpace.print_with_subs(DebugFile); - } - Relation dom = Domain(copy(r)); - dom.simplify(2,1); - Relation rng = Range(copy(r)); - rng.simplify(2,1); - Relation AC = ConicClosure(Restrict_Range(Restrict_Domain(copy(r),copy(rng)),copy(dom))); - Relation UB = Union(copy(r),Join(copy(r),Join(AC,copy(r)))); - UB.simplify(2,1); - - if (detailedClosureDebug) { - fprintf(DebugFile, "UB is:\n"); - UB.print_with_subs(DebugFile); - } - result = Relation::False(r); - Simple_List<Relation> firstChoice,secondChoice; - - r.simplify(2,2); - - Relation test = Difference(copy(r),Composition(copy(r),copy(r))); - test.simplify(2,2); - if (r.number_of_conjuncts() > test.number_of_conjuncts()) { - Relation test2 = Union(copy(test),Composition(copy(test),copy(test))); - test2.simplify(2,2); - if (Must_Be_Subset(copy(r),copy(test2))) r = test; - else if (detailedClosureDebug) { - fprintf(DebugFile, "Transitive reduction not possible:\n"); - fprintf(DebugFile, "R is:\n"); - r.print_with_subs(DebugFile); - fprintf(DebugFile, "test2 is:\n"); - test2.print_with_subs(DebugFile); - } - } - - r.make_level_carried_to(r.n_inp()); - if (detailedClosureDebug) { - fprintf(DebugFile, "r is:\n"); - r.print_with_subs(DebugFile); - } - for(int depth = r.n_inp(); depth >= -1; depth--) - for (DNF_Iterator d(r.query_DNF()); d.live(); d.next()) - if (d.curr()->query_guaranteed_leading_0s() == depth) { - Relation C(r, d.curr()); - firstChoice.append(C); - } - - bool first_conj=true; - for (Simple_List_Iterator<Relation> sli(firstChoice); sli; sli++) { - if (first_conj) - first_conj=false; - else { - Relation C_plus; - bool change=TryConjunctTransitiveClosure( - copy(sli.curr()), IterationSpace, C_plus); - if (change) - sli.curr()=C_plus; - } - } - - //compute closure - int maxClauses = 3+firstChoice.size()*(1+maxExpansion); - - int resultConjuncts = 0; - int numFails = 0; - bool resultInexact = false; - while (!firstChoice.empty() || !secondChoice.empty()) { - Relation R_plus, R_star; - - if (detailedClosureDebug) { - fprintf(DebugFile,"Main loop of TC:\n"); - if (!firstChoice.empty()) { - fprintf(DebugFile,"First choice:\n"); - printRelationList(firstChoice); - } - if (!secondChoice.empty()) { - fprintf(DebugFile,"Second choice:\n"); - printRelationList(secondChoice); - } - } - - Relation R; - if (!firstChoice.empty()) - R = firstChoice.remove_front(); - else R = secondChoice.remove_front(); - - if (detailedClosureDebug) { - fprintf(DebugFile, "Working with conjunct:\n"); - R.print_with_subs(DebugFile); - } - - bool known=ConjunctTransitiveClosure(copy(R),IterationSpace, R_plus, R_star); - - if (!known && numFails < firstChoice.size()) { - numFails++; - firstChoice.append(R); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nTry another conjunct, R is not suitable\n"); - R.print_with_subs(DebugFile); - } - continue; - } - - - if (detailedClosureDebug) { - fprintf(DebugFile,"\nR+ is:\n"); - R_plus.print_with_subs(DebugFile); - if (known) { - fprintf(DebugFile, "Known R? is :\n"); - R_star.print_with_subs(DebugFile); - } - else - fprintf(DebugFile, "The R* for this relation is not calculated\n"); - } - - Relation R_z; - if (known) { - R_z=Difference(copy(R_star),copy(R_plus)); - known = R_z.is_upper_bound_satisfiable(); - if (known) { - int d = R.single_conjunct()->query_guaranteed_leading_0s(); - R_z.make_level_carried_to(min(R.n_inp(),d+1)); - if (R_z.query_DNF()->length() > 1) known = false; - if (detailedClosureDebug) { - fprintf(DebugFile, "\nForced R_Z to be level carried at level %d\n",min(R.n_inp(),d+1)); - } - } - if (detailedClosureDebug) { - if (known) { - fprintf(DebugFile, "\nDifference between R? and R+ is:\n"); - R_z.print_with_subs(DebugFile); - } - else - fprintf(DebugFile, "\nR_z is unusable\n"); - } - } - else R_z = Relation::False(r); - - if (!known) - numFails++; - else numFails = 0; - if (!known && numFails <= firstChoice.size()) { - firstChoice.append(R); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nTry another conjunct, Rz is avaiable for R:\n"); - R.print_with_subs(DebugFile); - } - continue; - } - - //make N empty list - Relation N = Relation::False(r); - - //append R+ to T - result = Union(result, copy(R_plus)); - resultConjuncts++; - - int expansion = maxClauses - (resultConjuncts + 2*firstChoice.size() + secondChoice.size()); - if (expansion < 0) expansion = 0; - if (detailedClosureDebug) { - fprintf(DebugFile,"Max clauses = %d\n",maxClauses); - fprintf(DebugFile,"result conjuncts = %d\n",resultConjuncts); - fprintf(DebugFile,"firstChoice's = %d\n",firstChoice.size()); - fprintf(DebugFile,"secondChoice's = %d\n",secondChoice.size()); - fprintf(DebugFile,"Allowed expansion is %d\n",expansion); - } - - bool firstPart=true; - if (!known && expansion == 0) { - if (detailedClosureDebug) { - fprintf(DebugFile,"Expansion = 0, R? unknown, skipping composition\n"); - } - if (!resultInexact && detailedClosureDebug) fprintf(DebugFile,"RESULT BECOMES INEXACT 1\n"); - resultInexact = true; - } - else - for (Simple_List_Iterator<Relation> s(firstChoice); - firstPart? - (s.live()?true: - (s = Simple_List_Iterator<Relation>(secondChoice), - firstPart = false, - s.live())) - :s.live(); - s.next()) { - assert(s.live()); - Relation C=(s.curr()); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nComposing chosen conjunct with C:\n"); - C.print_with_subs(DebugFile); - } - - if (!known) { - if (detailedClosureDebug) { - fprintf(DebugFile, "\nR? is unknown! No debug info here yet\n"); - } - Relation C1=Composition(copy(C), copy(R_plus)); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nGenerating \n"); - C1.print_with_subs(DebugFile); - } - C1.simplify(); - Relation newStuff = - Difference( - Difference(copy(C1),copy(C)), - copy(R_plus)); - newStuff.simplify(); - if (detailedClosureDebug) { - fprintf(DebugFile, "New Stuff:\n"); - newStuff.print_with_subs(DebugFile); - } - bool C1_contains_new_stuff = newStuff.is_upper_bound_satisfiable(); - if (C1_contains_new_stuff) { - if (newStuff.has_single_conjunct()) - C1 = newStuff; - if (expansion) { - N = Union(N,copy(C1)); - expansion--; - } - else { - if (!resultInexact && detailedClosureDebug) fprintf(DebugFile,"RESULT BECOMES INEXACT 2\n"); - resultInexact = true; - break; - } - } - else C1 = Relation::False(C1); - - Relation C2(Composition(copy(R_plus),copy(C))); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nGenerating \n"); - C2.print_with_subs(DebugFile); - } - newStuff = - Difference( - Difference( - Difference(copy(C2),copy(C)), - copy(C1)), - copy(R_plus)); - newStuff.simplify(); - if (detailedClosureDebug) { - fprintf(DebugFile, "New Stuff:\n"); - newStuff.print_with_subs(DebugFile); - } - if (newStuff.is_upper_bound_satisfiable()) { - if (newStuff.has_single_conjunct()) - C2 = newStuff; - if (expansion) { - N = Union(N,copy(C2)); - expansion--; - } - else { - if (!resultInexact && detailedClosureDebug) fprintf(DebugFile,"RESULT BECOMES INEXACT 3\n"); - resultInexact = true; - break; - } - } - else C2 = Relation::False(C2); - - if (C1_contains_new_stuff) { - Relation C3(Composition(copy(R_plus),copy(C1))); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nGenerating \n"); - C3.print_with_subs(DebugFile); - } - newStuff = - Difference( - Difference( - Difference( - Difference(copy(C3),copy(C)), - copy(C1)), - copy(C2)), - copy(R_plus)); - newStuff.simplify(); - if (detailedClosureDebug) { - fprintf(DebugFile, "New Stuff:\n"); - newStuff.print_with_subs(DebugFile); - } - if (newStuff.is_upper_bound_satisfiable()) { - if (newStuff.has_single_conjunct()) - C3 = newStuff; - if (expansion) { - N = Union(N,C3); - expansion--; - } - else { - if (!resultInexact && detailedClosureDebug) fprintf(DebugFile,"RESULT BECOMES INEXACT 4\n"); - resultInexact = true; - break; - } - } - } - - } - else { - Relation C_Rz(Composition(copy(C),copy(R_z))); - if (detailedClosureDebug) { - fprintf(DebugFile, "C o Rz is:\n"); - C_Rz.print_with_subs(DebugFile); - } - - Relation Rz_C_Rz(Composition(copy(R_z),copy(C_Rz))); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nRz o C o Rz is:\n"); - Rz_C_Rz.print_with_subs(DebugFile); - } - - if (Equal(C,Rz_C_Rz)) { -#if defined(TC_STATS) - fprintf(statsfile,"weak test selects C?\n"); -#endif - Relation tmp = Composition(C,copy(R_star)); - tmp.simplify(); - Relation tmp2 = Composition(copy(R_star),copy(tmp)); - tmp2.simplify(); - if (Must_Be_Subset(copy(tmp2),copy(tmp))) - *s = tmp; - else - *s = tmp2; - if (detailedClosureDebug) { - fprintf(DebugFile,"\nC is equal to Rz o C o Rz so R? o C o R? replaces C\n"); - fprintf(DebugFile, "R? o C o R? is:\n"); - (*s).print_with_subs(DebugFile); - } - } - else { -#if defined(TC_STATS) - fprintf(statsfile,"weak test fails\n"); -#endif - if (Equal(C, C_Rz)) { - *s=Composition(copy(C),copy(R_star)); - Relation p(Composition(copy(R_plus), copy(*s))); - p.simplify(); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nC is equal to C o Rz, so C o Rz replaces C\n"); - fprintf (DebugFile, "C o R? is:\n"); - (*s).print_with_subs(DebugFile); - fprintf (DebugFile, "R+ o C o R? is added to list N. It's :\n"); - p.print_with_subs(DebugFile); - } - if (!Is_Obvious_Subset(copy(p),copy(R_plus)) - && !Is_Obvious_Subset(copy(p),copy(C))) { - if (expansion) { - p.simplify(2,2); - expansion--; - } - else { - if (!resultInexact && detailedClosureDebug) fprintf(DebugFile,"RESULT BECOMES INEXACT 5\n"); - resultInexact = true; - break; - } - } - } - else { - Relation Rz_C(Composition(copy(R_z),copy(C))); - - if (Equal(C,Rz_C)) { - *s=Composition(copy(R_star),copy(C)); - Relation Rstar_C_Rplus(Composition(copy(*s),copy(R_plus))); - Rstar_C_Rplus.simplify(); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nC is equal to Rz o C , so R? o C replaces C\n"); - fprintf (DebugFile, "R? o C is:\n"); - (*s).print_with_subs(DebugFile); - fprintf (DebugFile, "R+ o C is added to list N. It's :\n"); - Rstar_C_Rplus.print_with_subs(DebugFile); - } - if (!Is_Obvious_Subset(copy(Rstar_C_Rplus),copy(R_plus)) - && !Is_Obvious_Subset(copy(Rstar_C_Rplus),copy(C))) { - if (expansion) - N = Union(N,Rstar_C_Rplus); - else { - if (!resultInexact && detailedClosureDebug) fprintf(DebugFile,"RESULT BECOMES INEXACT 6\n"); - resultInexact = true; - break; - } - } - } - else { - if (detailedClosureDebug) { - fprintf(DebugFile, "\nHave to handle it the hard way\n"); - } - Relation C1=Composition(copy(C), copy(R_plus)); - C1.simplify(); - if (!Is_Obvious_Subset(copy(C1),copy(R_plus)) - && !Is_Obvious_Subset(copy(C1),copy(C))) { - if (expansion) { - N = Union(N,copy(C1)); - expansion--; - } - else { - if (!resultInexact && detailedClosureDebug) fprintf(DebugFile,"RESULT BECOMES INEXACT 7\n"); - resultInexact = true; - break; - } - } - - Relation C2(Composition(copy(R_plus),copy(C))); - C2.simplify(); - if (!Is_Obvious_Subset(copy(C2),copy(R_plus)) - && !Is_Obvious_Subset(copy(C2),copy(C))) { - if (expansion) { - N = Union(N,C2); - expansion--; - } - else { - if (!resultInexact && detailedClosureDebug) { - fprintf(DebugFile,"RESULT BECOMES INEXACT 8\n"); - fprintf(DebugFile,"Have to discard:\n"); - C2.print_with_subs(DebugFile); - } - resultInexact = true; - break; - } - } - Relation C3(Composition(copy(R_plus),C1)); - C3.simplify(); - if (!Is_Obvious_Subset(copy(C3),copy(R_plus)) && !Is_Obvious_Subset(copy(C3),copy(C))) { - if (expansion) { - N = Union(N,C3); - expansion--; - } - else { - if (!resultInexact && detailedClosureDebug) - fprintf(DebugFile,"RESULT BECOMES INEXACT 9\n"); - resultInexact = true; - break; - } - } - } - } - } - } - } - - //now we processed the first conjunct. - if (detailedClosureDebug) { - N.simplify(2,2); - fprintf(DebugFile, "\nNew conjuncts:\n"); - N.print_with_subs(DebugFile); - } - - N.simplify(2,2); - appendClausesToList(secondChoice,N); - } - - //Did we do all conjuncts? If not, make T be inexact - result.copy_names(r); - - result.simplify(2,2); - - if (!result.is_exact()) { - result = Lower_Bound(result); - resultInexact = true; - } - if (resultInexact) { - Relation test(Composition(copy(result),copy(result))); - test.simplify(2,2); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nResult is:\n"); - result.print_with_subs(DebugFile); - fprintf(DebugFile, "\nResult composed with itself is:\n"); - test.print_with_subs(DebugFile); - } - if (!Must_Be_Subset(test,copy(result))) { - result = Union(result,Intersection(UB, Relation::Unknown(result))); - } - } - -#ifdef TC_STATS - { - Relation rcopy = result; - Relation test2(Composition(copy(rcopy),copy(rcopy))); - test2.simplify(2,2); - test2.remove_disjunction_with_unknown(); - rcopy.remove_disjunction_with_unknown(); - if (detailedClosureDebug) { - fprintf(DebugFile, "\nResult is:\n"); - rcopy.print_with_subs(DebugFile); - fprintf(DebugFile, "\nResult composed with itself is:\n"); - test2.print_with_subs(DebugFile); - } - if (!Must_Be_Subset(test2,copy(rcopy))) { - fprintf(statsfile,"multi TC result is inexact\n"); - } - else - fprintf(statsfile,"TC result is exact%s\n", (resultInexact || !rcopy.is_exact())?" despite perceived inexactness":""); - } -#endif - -#ifdef TC_STATS - } - int totalTime = clock_diff(); - fprintf(statsfile, "input conj: %d output conj: %d #singe conj closures: %d time: %d\n", - in_conj, copy(result).query_DNF()->length(), - singles, - totalTime/TC_RUNS); -#endif - - if (closure_presburger_debug || detailedClosureDebug) { - if (detailedClosureDebug) { - fprintf(DebugFile, "\nThe transitive closure is :\n"); - result.print_with_subs(DebugFile); - } - fprintf(DebugFile, "\n\n] END Transitive closure\n\n"); - } - return result; -} - - -Relation TransitiveClosure(NOT_CONST Relation &input_r, - int maxExpansion, - NOT_CONST Relation & input_IterationSpace) { - Relation r = consume_and_regurgitate(input_r); - Relation IterationSpace = consume_and_regurgitate(input_IterationSpace); - if (r.is_null()) - return r; - if (r.n_out() == 0) - throw std::invalid_argument("transitive closure does not apply to set"); - if (r.n_inp() != r.n_out()) - throw std::invalid_argument("transitive closure must has the same input and output arity"); - - if (closure_presburger_debug) { - fprintf(DebugFile,"\nComputing Transitive closure of:\n"); - r.print_with_subs(DebugFile); - fprintf(DebugFile,"\nIteration space is:\n"); - IterationSpace.print_with_subs(DebugFile); - } - if (!r.is_upper_bound_satisfiable()) { - if (closure_presburger_debug) - fprintf(DebugFile, "]TC : relation is false\n"); - return r; - } - - Relation UB = DeltasToRelation(ConicHull(Project_Sym(Deltas(copy(r)))), - r.n_inp(),r.n_out()); - if (closure_presburger_debug) { - fprintf(DebugFile,"UB is:\n"); - UB.print_with_subs(DebugFile); - } - - Relation conditions = Restrict_Domain(copy(UB),Domain(copy(r))); - conditions.simplify(); - if (closure_presburger_debug) { - fprintf(DebugFile,"Forward reachable is:\n"); - conditions.print_with_subs(DebugFile); - } - conditions = Composition(Inverse(copy(UB)),conditions); - conditions.simplify(); - if (closure_presburger_debug) { - fprintf(DebugFile,"Backward/forward reachable is:\n"); - conditions.print_with_subs(DebugFile); - } - conditions = Range(conditions); - conditions.simplify(); - // conditions = Approximate(conditions); - // conditions.simplify(); - conditions = VennDiagramForm(conditions); - conditions.simplify(); - - if (closure_presburger_debug) { - fprintf(DebugFile,"Condition regions are:\n"); - conditions.print_with_subs(DebugFile); - } - - if (conditions.is_obvious_tautology()) { - return TransitiveClosure0(r, maxExpansion, IterationSpace); - } - else { - Relation answer = Relation::False(r); - answer.copy_names(r); - answer.setup_names(); - - for (DNF_Iterator c(conditions.query_DNF()); c.live(); c.next()) { - Relation tmp = Relation(conditions, c.curr()); - if (closure_presburger_debug) { - fprintf(DebugFile,"\nComputing Transitive closure:\n"); - fprintf(DebugFile,"\nRegion:\n"); - tmp.prefix_print(DebugFile); - } - - Relation tmp3 = Restrict_Domain(copy(r),tmp); - tmp3.simplify(2,2); - if (closure_presburger_debug) { - fprintf(DebugFile,"\nRelation:\n"); - tmp3.prefix_print(DebugFile); - } - - answer = Union(answer, TransitiveClosure0(tmp3, maxExpansion,copy(IterationSpace))); - } - return answer; - } -} - - -/* ********************************* */ -/* Function check if relation */ -/* belong to d-form or */ -/* uniform relaion class */ -/* ********************************* */ - -Relation is_DForm_or_Uniform(NOT_CONST Relation &r){ - - Relation s = consume_and_regurgitate(r); - Relation Rtmp, Rdelta, delta; - - delta = Deltas(copy(s)); - Rdelta = DeltasToRelation(copy(delta), s.n_inp(), s.n_out()); - Rtmp = DeltasToRelation(Project_Sym(delta), s.n_inp(), s.n_out()); - - Rtmp = Restrict_Domain(Rtmp, Domain(copy(Rdelta))); - Rtmp = Restrict_Range(Rtmp, Range(Rdelta)); - - Rdelta = copy(Rtmp); - - Rtmp = Restrict_Domain(Rtmp, Domain(copy(s))); - Rtmp = Restrict_Range(Rtmp, Range(copy(s))); - - if (Must_Be_Subset( copy(Rtmp), copy(s)) && \ - Must_Be_Subset(copy(s), copy(Rtmp))) { - Rtmp = Relation::Null(); - } - else { - Rtmp = Rdelta = Relation::Null(); - } - - return Rdelta; - } - - - - /* ********************************* */ - /* Get a conjunction for */ - /* a given number from set */ - /* of relations */ - /* ********************************* */ - -Relation getConjunctionNr(NOT_CONST Relation &r, int conjNr) { - - Relation s = consume_and_regurgitate(r); - int i = 1; - - for (DNF_Iterator c(s.query_DNF()); c; c++,i++) { - if ( i == conjNr ) { - return Relation(s, c.curr()); - } - } - - return Relation::False(s.n_inp(), s.n_out()); - - } - - -/* ********************************* */ -/* Get a common region for */ -/* a given set of relations */ -/* ********************************* */ - -Relation getCommonRegion( NOT_CONST Relation &r, const long* relTab, const long relCount) { - - Relation s = consume_and_regurgitate(r); - Relation commonRegion, Rcurr; - long i = 0; - - Rcurr = getConjunctionNr( copy(s), relTab[0]); - commonRegion = Union(Domain(copy(Rcurr)), Range(copy(Rcurr))); - - for( i=1; i < relCount; i++ ){ - Rcurr = getConjunctionNr( copy(s), relTab[i]); - commonRegion = Intersection( commonRegion, Union( Domain(copy(Rcurr)), Range(copy(Rcurr))) ); - } - - return commonRegion; - } - - -/* ********************************* */ -/* Get a set of relations */ -/* ********************************* */ - -Relation getRelationsSet( NOT_CONST Relation &r, const long* relTab, const long relCount) { - - Relation s = consume_and_regurgitate(r); - Relation R = Relation::False(s.n_inp(), s.n_out()); - long i = 0; - - for( i=0; i < relCount; i++ ){ - R = Union( R, getConjunctionNr( copy(s), relTab[i]) ); - } - - return R; - } - - -/* ********************************* */ -/* Get a set of relations */ -/* from a common region */ -/* ********************************* */ - -Relation relationsOnCommonRegion( NOT_CONST Relation &r, NOT_CONST Relation ®ion ) { - - Relation set = consume_and_regurgitate(r); - Relation reg = consume_and_regurgitate(region); - Relation R = Relation::True(set.n_inp(), set.n_out()); - - R = Restrict_Domain(R, copy(reg)); - R.simplify(2,1); - R = Restrict_Range(R, reg); - R.simplify(2,1); - - R = Intersection(R, set); - - return R; - - } - - -Relation compose_N(NOT_CONST Relation &input_r) { - Relation r = consume_and_regurgitate(input_r); - Relation powerR, powerR2; - - r = Union(r, Identity(r.n_inp())); - powerR = copy(r); - - for(;;){ - if (powerR.number_of_conjuncts() > 50) { - powerR = Relation::Null(); - return powerR; - } - - powerR2 = Composition(copy(powerR), copy(r)); - powerR2.simplify(2,1); - - if (Must_Be_Subset( copy(powerR2), copy(powerR))) { - powerR2 = Relation::Null(); - return powerR; - } - - powerR = Relation::Null(); - powerR = copy(powerR2); - powerR2 = Relation::Null(); - } -} - - -/****************************** */ -/* Check exactness of R+ */ -/* */ -/* Tomasz Klimek 05-06-2010 */ -/****************************** */ - -bool checkExactness(NOT_CONST Relation &r, NOT_CONST Relation &rplus){ - - -Relation s1 = consume_and_regurgitate(r); -Relation s2 = consume_and_regurgitate(rplus); -Relation R; - -R = Composition(copy(s1), copy(s2)); -R = Union(s1, R); - - if( Must_Be_Subset(copy(s2), copy(R)) && \ - Must_Be_Subset(copy(R), copy(s2))) { - R = Relation::Null(); - s1 = Relation::Null(); - return true; - } - - R = Relation::Null(); - s1 = Relation::Null(); - - return false; - -} - -/************************************** */ -/* Calculate approximation of R* */ -/* */ -/* Tomasz Klimek 05-06-2010 */ -/************************************** */ - - -Relation ApproxClosure(NOT_CONST Relation &r) { - - Relation s = consume_and_regurgitate(r); - Relation R = Relation::False(s.n_inp(), s.n_out()); - Relation tc = Identity(s.n_inp()); - Relation Rtmp; - - - for (DNF_Iterator c(s.query_DNF()); c; c++) { - Rtmp = Hull(Project_Sym(Deltas(Relation(s, c.curr()))), false, 1, Relation::Null()); - R = Union(R, TransitiveClosure(DeltasToRelation(Rtmp,s.n_inp(),s.n_out()), 1, Relation::Null())); - } - - for (DNF_Iterator c(R.query_DNF()); c; c++) { - Rtmp = Union(Identity(s.n_inp()), Relation(R, c.curr())); - tc = Composition(tc, Rtmp); - tc = Hull(tc, false, 1, Relation::Null()); - } - - tc = Restrict_Domain(tc,Domain(copy(s))); - tc.simplify(2,1); - tc = Restrict_Range(tc,Range(s)); - tc.simplify(2,1); - tc = Intersection(tc, Relation::Unknown(tc)); - - return tc; -} - - -/************************************** */ -/* Calculate R* on unbounded region */ -/* */ -/* Tomasz Klimek 05-06-2010 */ -/************************************** */ - -Relation ClosureOnUnboundedRegion(NOT_CONST Relation &r) { - - Relation s = consume_and_regurgitate(r); - Relation R = Relation::False(s.n_inp(), s.n_out()); - Relation tc = Identity(s.n_inp()); - Relation Rtmp,tcTmp; - - for (DNF_Iterator c(s.query_DNF()); c; c++) { - Rtmp = is_DForm_or_Uniform(Relation(s, c.curr())); - - if (!(Rtmp.is_null())) { - tcTmp = TransitiveClosure(Rtmp, 1, Relation::Null()); - - if (!(tcTmp.is_exact())){ - tcTmp = R = Relation::Null(); - /* fprintf(DebugFile,"\nTC is inexact!"); */ - return tcTmp; - } - } - else { - R = Relation::Null(); - /* fprintf(DebugFile,"\nR is not d-form relation!"); */ - return Relation::Null(); - } - - R = Union(R, tcTmp); - } - - for (DNF_Iterator c(R.query_DNF()); c; c++) { - Rtmp = Union(Identity(s.n_inp()), Relation(R, c.curr())); - tc = Composition(tc, Rtmp); - tc.simplify(2,1); - } - - tc = Difference(tc, Identity(s.n_inp())); - - return tc; - -} - - - - -/******************************* */ -/* Try to select sets of domain */ -/* and range */ -/* */ -/* Tomasz Klimek 05-06-2010 */ -/******************************* */ - -Relation SelectRegionForClosure(NOT_CONST Relation &r){ - - Relation s = consume_and_regurgitate(r); - Relation DR = Union(Domain(copy(s)),Range(copy(s))); - Relation region,tc,tcTmp; - - region = SimpleHull(copy(DR)); - region.simplify(2,1); - - tc = ClosureOnUnboundedRegion(copy(s)); - - if (tc.is_null()) { - return tc; - } - - tcTmp = Restrict_Domain(copy(tc),copy(region)); - tcTmp.simplify(2,1); - tcTmp = Restrict_Range(tcTmp,region); - tcTmp.simplify(2,1); - - if (checkExactness(copy(s), copy(tcTmp))) { - s = tc = Relation::Null(); - return tcTmp; - } - - tcTmp = Relation::Null(); - region = Hull(DR,false,1,Relation::Null()); - - tcTmp = Restrict_Domain(copy(tc),copy(region)); - tcTmp.simplify(2,1); - tcTmp = Restrict_Range(tcTmp,region); - tcTmp.simplify(2,1); - - if (checkExactness(copy(s), copy(tcTmp))) { - s = tc = Relation::Null(); - return tcTmp; - } - - tcTmp = Relation::Null(); - - tc = Restrict_Domain(tc,Domain(copy(s))); - tc.simplify(2,1); - tc = Restrict_Range(tc,Domain(copy(s))); - tc.simplify(2,1); - - if (checkExactness(copy(s), copy(tc))) { - s = Relation::Null(); - return tc; - } - - tc = Relation::Null(); - - return ApproxClosure(s); - -} - - - - -/************************************** */ -/* Calculate R* */ -/* */ -/* Tomasz Klimek 05-06-2010 */ -/************************************** */ - -Relation calculateTransitiveClosure(NOT_CONST Relation &r) { - - Relation s = consume_and_regurgitate(r); - Relation tc = Relation::False(s.n_inp(), s.n_out()); - long* relationsSet = NULL; - Relation commonRegion, regionTmp; - Relation inputRelations; - long i,j=-1; - long N,M; - Relation R; - - - commonRegion = SelectRegionForClosure(copy(s)); - - if (commonRegion.is_null()) { - return ApproxClosure(s); - } - - if (commonRegion.is_exact()) { - return commonRegion; - } - - commonRegion = Relation::Null(); - N = M = s.number_of_conjuncts(); - relationsSet = (long*)calloc(N,sizeof(long)); - - if (relationsSet == NULL) { - return Relation::False(s.n_inp(), s.n_out()); - } - - for (; N > 1;) { - for ( i=0; i<N; i++ ) { - if ( i < j ) { - continue; - } - else if ( j == -1 ) { - relationsSet[i] = 1; - } - else if ( i > j ) { - relationsSet[i] = relationsSet[i-1] + 1; - } - else if ( i == j ) { - relationsSet[i] += 1; - } - if ( relationsSet[i] <= M ) { - j = i; - } - else { - j = i - 1; - break; - } - } - - if ( j+1 == N) { - /* fprintf(DebugFile,"\n"); - for(i=0;i<N;i++){ - fprintf(DebugFile," %ld", relationsSet[i]); - } - fprintf(DebugFile,"\n"); */ - - commonRegion = getCommonRegion( copy(s), relationsSet, N); - commonRegion.simplify(2,1); - inputRelations = getRelationsSet( copy(s), relationsSet, N); - inputRelations.simplify(2,1); - - /* ******************* */ - /* Check on rectangle */ - /* ******************* */ - regionTmp = SimpleHull(copy(commonRegion)); - regionTmp.simplify(2,1); - R = relationsOnCommonRegion( copy(inputRelations), regionTmp); - R.simplify(2,1); - regionTmp = SelectRegionForClosure(R); - - if (regionTmp.is_exact()) { - /* fprintf(DebugFile,"\nDescribed on rectangle region\n"); */ - tc = Union( tc, regionTmp ); - } - else { - /* ******************* */ - /* Check on hull */ - /* ******************* */ - - R = Relation::Null(); - regionTmp = Relation::Null(); - regionTmp = Hull(copy(commonRegion),false,1,Relation::Null()); - regionTmp.simplify(2,1); - R = relationsOnCommonRegion( copy(inputRelations), regionTmp); - R.simplify(2,1); - regionTmp = SelectRegionForClosure(R); - - if (regionTmp.is_exact()) { - /* fprintf(DebugFile,"\nDescribed on Hull\n"); */ - tc = Union( tc, regionTmp); - } - else { - /* ********************************** */ - /* Check on sets of domain and range */ - /* ********************************** */ - - R = Relation::Null(); - regionTmp = Relation::Null(); - R = relationsOnCommonRegion( copy(inputRelations), copy(commonRegion) ); - R.simplify(2,1); - regionTmp = SelectRegionForClosure(R); - - if (regionTmp.is_exact()) { - /* fprintf(DebugFile,"\nDescribed on sets of doamin and range\n"); */ - tc = Union( tc, regionTmp ); - } - else { - commonRegion = Relation::Null(); - inputRelations = Relation::Null(); - regionTmp = Relation::Null(); - R = Relation::Null(); - - return ApproxClosure(s); - } - } - } - - commonRegion = Relation::Null(); - inputRelations = Relation::Null(); - - regionTmp = Relation::Null(); - R = Relation::Null(); - } - - if ( j == -1 ) N--; - - } - - R = Relation::Null(); - - for (DNF_Iterator c(s.query_DNF()); c; c++) { - if (!Must_Be_Subset(Relation(s, c.curr()), copy(tc))) { - /* fprintf(DebugFile,"\nIs not a subset\n"); */ - tc = Union( tc, SelectRegionForClosure(Relation(s, c.curr()))); - } - } - - if (!(tc.is_exact())){ - return ApproxClosure(s); - } - - tc = compose_N(tc); - - if (tc.is_null()) { - return ApproxClosure(s); - } - - return tc; - -} - - - - - -} // namespace diff --git a/omegalib/omega/src/evac.cc b/omegalib/omega/src/evac.cc deleted file mode 100644 index ff872c9..0000000 --- a/omegalib/omega/src/evac.cc +++ /dev/null @@ -1,339 +0,0 @@ -#if defined STUDY_EVACUATIONS - -#include <omega/Relations.h> -#include <omega/pres_conj.h> -#include <omega/evac.h> -#include <omega/omega_core/debugging.h> -#include <omega/omega_core/oc_i.h> - -namespace omega { - -int evac_debug = 0; - -char *evac_names[] = { "trivial", - "offset", - "subseq", - "off_sub", -// "perm.", - "affine", - "nasty" }; - -int single_evacs[evac_nasty+1]; -int double_evacs[evac_nasty+1][evac_nasty+1]; - -/* - * We're going to try to describe the equalities among a set of variables - * We want to perform some substitutions to ensure that we don't miss - * v_1 = v_2 due to its expression as v_1 = v_3 && v_2 = v_3 - * We therefore try to substitute out all variables that we don't care - * about (e.g., v_3 in the above example). - */ - -static bool try_to_sub(Problem *p, int col) { - int e, i; - - if (!p->variablesInitialized) { - p->initializeVariables(); - } - - assert(col <= p->nVars); - assert(!inApproximateMode); - - for(e=0;e<p->nEQs;e++) - if (p->EQs[e].coef[col] == 1 || p->EQs[e].coef[col] == -1) { - int var = p->var[col]; - p->doElimination(e, col); - if (col != p->nVars + 1) - p->forwardingAddress[p->var[p->nVars+1]] = col; - assert(p->SUBs[p->nSUBs-1].key = var); - p->forwardingAddress[var] = -p->nSUBs; - break; - } - - if (e == p->nEQs) - return false; - - for (int c=0;c<=p->nVars;c++) { - assert(p->EQs[e].coef[c] == 0); - } - - p->nEQs--; - if (e < p->nEQs) eqnncpy(&p->EQs[e], &p->EQs[p->nEQs], p->nVars); - - for (i = 0; i < p->nSUBs; i++) { - assert(p->forwardingAddress[p->SUBs[i].key] == -i - 1); - } - - return true; -} - - -// should be static, but must be a friend -bool check_subseq_n(Conjunct *c, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity, int n, bool allow_offset) { - // check each position v to see if from[v] == to[v+n] (+ offset) - - assert(max_arity + n <= n_to); - - for (int v = 1; v <= max_arity; v++){ - // first, get rid of possible interlopers: - int col; - Conjunct *d = c->copy_conj_same_relation(); - for (int tv = 1; tv <= n_to; tv++) - if (tv != v+n) - if ((col = d->find_column(evac_to[tv])) > 0) - try_to_sub(d->problem, col); - for (int fv = 1; fv <= n_from; fv++) - if (fv != v) - if ((col = d->find_column(evac_from[fv])) > 0) - try_to_sub(d->problem, col); - - int c_to = d->find_column(evac_to[v+n]); - int c_from = d->find_column(evac_from[v]); - assert(c_to > 0); - assert(c_from > 0); - assert(c_to != c_from); - - // now, just look for an equality c_to = c_from + offset - - bool found_needed_eq = false; - - for (int e = 0; e < d->problem->nEQs; e++) { - if (d->problem->EQs[e].coef[c_from] != 0) { - for (int k = allow_offset?1:0; k < d->problem->nVars; k++) - if (k!=c_to && k!=c_from && d->problem->EQs[e].coef[k]!=0) - break; // this EQ is not what we need - if (k == d->problem->nVars) { // this EQ is what we need - found_needed_eq = true; - break; - } - } - } - - delete d; - - if (!found_needed_eq) - return false; // no EQ did what we need - } - - return true; -} - -void assert_subbed_syms(Conjunct *c) { - int v, col; - - // where possible, symbolic constants must have been subbed out - for (v = 1; v <= c->relation()->global_decls()->length(); v++) - if ((col = c->find_column((*c->relation()->global_decls())[v]))>0) - assert(!try_to_sub(c->problem, col)); -} - - -static bool check_offset(Conjunct *c, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity) { - assert_subbed_syms(c); - - return check_subseq_n(c,evac_from,evac_to,n_from,n_to,max_arity,0,true); -} - -static bool check_subseq(Conjunct *c, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity) { - assert_subbed_syms(c); - - for (int i = 0; i <= n_to - max_arity; i++) - if (check_subseq_n(c,evac_from,evac_to,n_from,n_to,max_arity,i,false)) - return true; - - return false; -} - -static bool check_offset_subseq(Conjunct *c, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity) { - assert_subbed_syms(c); - - for (int i = 0; i <= n_to - max_arity; i++) - if (check_subseq_n(c,evac_from,evac_to,n_from,n_to,max_arity,i,true)) - return true; - - return false; -} - -bool check_affine(Conjunct *d, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity) { - int v, col; - Conjunct *c = d->copy_conj_same_relation(); - assert_subbed_syms(c); - - // try to find substitutions for all evac_to variables - for (v = 1; v <= max_arity; v++) - if ((col = c->find_column(evac_to[v])) > 0) - try_to_sub(c->problem, col); - - // any that didn't have substitutions, aren't affine - for (v = 1; v <= max_arity; v++) - if (c->find_column(evac_to[v]) >= 0) { - delete c; - return false; - } - - // FERD - disallow symbolic constants? - delete c; - return true; -} - - -evac study(Conjunct *C, Sequence<Variable_ID> &evac_from, Sequence<Variable_ID> &evac_to, int n_from, int n_to, int max_arity) { - assert(max_arity > 0); - assert(max_arity <= C->relation()->n_inp()); - assert(max_arity <= C->relation()->n_out()); - - assert((&evac_from == &input_vars && &evac_to == &output_vars) || - (&evac_from == &output_vars && &evac_to == &input_vars)); - - evac ret = evac_nasty; - - if (C->query_guaranteed_leading_0s() >= max_arity) - ret = evac_trivial; - else { - Conjunct *c = C->copy_conj_same_relation(); - assert(c->relation() == C->relation()); - - if (evac_debug >= 3) { - fprintf(DebugFile, "About to study %s evacuation for conjunct\n", - &evac_from == &input_vars ? "In-->Out" : "Out-->In"); - use_ugly_names++; - C->prefix_print(DebugFile); - use_ugly_names--; - } - - bool sat = simplify_conj(c, true, 4, black); - assert(sat); // else c is deleted - - int v, col; - - // Substitute out all possible symbolic constants - assert(c->problem->nSUBs == 0); - for (v = 1; v <= c->relation()->global_decls()->length(); v++) - if ((col = c->find_column((*c->relation()->global_decls())[v]))>0) - try_to_sub(c->problem, col); - - if (check_offset(c, evac_from, evac_to, n_from, n_to, max_arity)) - ret = evac_offset; - else if (check_subseq(c, evac_from, evac_to, n_from, n_to, max_arity)) - ret = evac_subseq; - else if (check_offset_subseq(c, evac_from, evac_to, n_from, n_to, max_arity)) - ret = evac_offset_subseq; - else if (check_affine(c, evac_from, evac_to, n_from, n_to, max_arity)) - ret = evac_affine; - - delete c; - } - - if (evac_debug >= 2) { - if ((evac_debug == 2 && ret != evac_trivial && ret != evac_nasty)) { - fprintf(DebugFile, "Studied %s evacuation for conjunct\n", - &evac_from == &input_vars ? "In-->Out" : "Out-->In"); - use_ugly_names++; - C->prefix_print(DebugFile); - use_ugly_names--; - } - - fprintf(DebugFile, "Saw evacuation type %s\n", evac_names[ret]); - } - - return ret; -} - - -void study_evacuation(Conjunct *C, which_way dir, int max_arity) { - if (evac_debug > 0) { - assert(max_arity >= 0); - - if (max_arity > 0) - if (dir == in_to_out) { - assert(max_arity <= C->relation()->n_inp()); - if (max_arity <= C->relation()->n_out()) - single_evacs[study(C, input_vars, output_vars, - C->relation()->n_inp(), - C->relation()->n_out(), - max_arity)]++; - } - else { - assert(max_arity <= C->relation()->n_out()); - if (max_arity <= C->relation()->n_inp()) - single_evacs[study(C, output_vars, input_vars, - C->relation()->n_out(), - C->relation()->n_inp(), - max_arity)]++; - } - } -} - -void study_evacuation(Conjunct *C1, Conjunct *C2, int max_arity) { - if (evac_debug > 0) { - assert(max_arity >= 0); - assert(max_arity <= C1->relation()->n_inp()); - assert(C2->relation()->n_out() == C1->relation()->n_inp()); - - if (max_arity > 0) - if (max_arity <= C1->relation()->n_out() && - max_arity <= C2->relation()->n_inp()) { - double_evacs[study(C1, input_vars, output_vars, - C1->relation()->n_inp(), - C1->relation()->n_out(), - max_arity)] - [study(C2, output_vars, input_vars, - C2->relation()->n_out(), - C2->relation()->n_inp(), - max_arity)]++; - } - else if (max_arity <= C1->relation()->n_out()) { - single_evacs[study(C1, input_vars, output_vars, - C1->relation()->n_inp(), - C1->relation()->n_out(), - max_arity)]++; - } - else if (max_arity <= C2->relation()->n_inp()) { - single_evacs[study(C2, output_vars, input_vars, - C2->relation()->n_out(), - C2->relation()->n_inp(), - max_arity)]++; - } - } -} - -class Evac_info_printer { -public: - ~Evac_info_printer(); -}; - -Evac_info_printer::~Evac_info_printer() { - if (evac_debug > 0) { - int i, j; - - fprintf(DebugFile, "\n"); - - fprintf(DebugFile, "SINGLE"); - for (i = 0; i <= evac_nasty; i++) - fprintf(DebugFile, "\t%s", evac_names[i]); - fprintf(DebugFile, "\n"); - - for (i = 0; i <= evac_nasty; i++) - fprintf(DebugFile, "\t%d", single_evacs[i]); - fprintf(DebugFile, "\n\n"); - - - fprintf(DebugFile, "DOUBLE"); - for (i = 0; i <= evac_nasty; i++) - fprintf(DebugFile, "\t%s", evac_names[i]); - fprintf(DebugFile, "\n"); - - for (i = 0; i <= evac_nasty; i++) { - fprintf(DebugFile, "%s\t", evac_names[i]); - for (j = 0; j <= evac_nasty; j++) - fprintf(DebugFile, "%d\t", double_evacs[i][j]); - fprintf(DebugFile, "\n"); - } - } -} - -static Evac_info_printer print_stats_at_exit; - -} // namespace - -#endif diff --git a/omegalib/omega/src/farkas.cc b/omegalib/omega/src/farkas.cc deleted file mode 100644 index 1b3ef87..0000000 --- a/omegalib/omega/src/farkas.cc +++ /dev/null @@ -1,480 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - convert to dual cone for manipulation. - - Notes: - - History: -*****************************************************************************/ - -#include <basic/Bag.h> -#include <basic/Map.h> -#include <omega.h> -#include <omega/farkas.h> - -namespace omega { - -static Global_Var_Decl constant_term("constantTerm"); - -// class Constant_Term { -// public: -// Global_Var_Decl *p; - -// Constant_Term(); -// ~Constant_Term(); -// }; - -// namespace { -// Constant_Term constant_term; -// } - -// Constant_Term::Constant_Term() { -// p = new Global_Var_Decl("constantTerm"); -// } - -// Constant_Term::~Constant_Term() { -// delete p; -// } - -// Global_Var_ID coefficient_of_constant_term = constant_term.p; - -Global_Var_ID coefficient_of_constant_term = &constant_term; - -extern int inApproximateMode; - -int farkas_debug = 0; - -coef_t farkasDifficulty; - -//***************************************************************************** -// -// forall x1,..,xn s.t. a10 + a11 x1 + ... + a1n xn >= 0 and -// ... -// am0 + am1 x1 + ... + amn xn >= 0 -// -// b0 + b1 x1 + ... + bn xn >= 0 -// -// iff -// -// exists lambda_0,...,lambda_m >= 0 s.t. -// forall x1,..,xn -// lambda_0 + -// lambda_1 ( a10 + a11 x1 + ... + a1n xn) + -// ... -// lambda_m ( am0 + am1 x1 + ... + amn xn) = -// -// b0 + b1 x1 + ... + bn xn -// -// iff -// -// exists lambda_0,...,lambda_m >= 0 s.t. -// lambda_0 + sum_i ( lambda_i a_i0 ) = b_0 -// for j in 1..n -// sum_i ( a_ij lambda_i ) = b_j -// -// iff -// -// exists lambda0,...,lambda_m s.t. -// lambda1,...,lambda_m >= 0 -// lambda0 >= 0 -// lambda_0 = b_0 - sum_i ( lambda_i a_i0 ) -// for j in 1..n -// sum_i ( a_ij lambda_i ) = b_j -// iff -// -// exists lambda1,...,lambda_m s.t. -// lambda1,...,lambda_m >= 0 -// b_0 - sum_i ( lambda_i a_i0 ) >= 0 -// for j in 1..n -// sum_i ( a_ij lambda_i ) = b_j -// -// a_ij come from relation rel -// -// x_1,...,x_n are input and output variables from rel. -// -// b_0,...,b_m are input and output arrays of coef_vars -// -//***************************************************************************** - - -// Given a Relation/Set R -// Compute A,B,C such that -// Ax+By + C >= 0 is true for all x,y in R -// iff [A,B] : constantTerm=C is in AffineClosure(R) -// Note: constantTerm is a special global variable -// If constantTerm appears in the incoming relation -// then set it's coefficient to be 1 in the result - - -// # For example, given -// R := {[i,j] : 1 <= i <= 10 && 1 <= j <= n}; -// # the farkas closure of R is: -// # ac := approximate {[i,j] : exists (lambda0, lambda1,lambda2,lambda3,lambda4 : -// # 0 <= lambda1,lambda2,lambda3,lambda4 -// # && constantTerm - (-lambda1+ 10 lambda2 - lambda3) >= 0 -// # && i = lambda1-lambda2 -// # && j = lambda3-lambda4 -// # && n = lambda4)}; -// # -// # ac; -// -// {[i,j]: 0 <= n && 0 <= n+constantTerm+i+j -// && 0 <= n+constantTerm+10i+j && 0 <= n+j} -// -// The ConvexCombination of ac is: -//# -//# approximate {[i,j] : exists (lambda1,lambda2,lambda3,lambda4 : -//# 0 <= lambda1,lambda2,lambda3,lambda4 -//# && 1 = lambda2+lambda3 -//# && i = lambda2+10lambda3 -//# && j = lambda2+lambda3+lambda4 -//# && n = lambda1+lambda2+lambda3+lambda4 -//# )}; -// -//{[i,j]: 1 <= i <= 10 && 1 <= j <= n} -// - -static void handleVariable(Relation &farkas, Conjunct * conj, - F_And* and_node, - Map<GEQ_Handle, Variable_ID> &gMap, - Map<EQ_Handle, Variable_ID> &eMap, - Variable_ID v) { - use_ugly_names++; - if (farkas_debug > 1) { - fprintf(DebugFile,"Building equality for %s\n", v->name().c_str()); - } - - EQ_Handle e = and_node->add_EQ(); - - for (GEQ_Iterator g = conj->GEQs(); g.live(); g.next()) - if (gMap(*g) != (Variable_ID) 0) { - coef_t c = (*g).get_coef(v); - if (c != 0) { - e.update_coef(gMap(*g), c); - } - } - - for (EQ_Iterator eq = conj->EQs(); eq.live(); eq.next()) - if (eMap(*eq) != (Variable_ID) 0) { - coef_t c = (*eq).get_coef(v); - if (c != 0) { - e.update_coef(eMap(*eq), c); - } - } - - if ((v)->kind() == Global_Var && - (v)->get_global_var() == coefficient_of_constant_term) - e.update_const(-1); - else - e.update_coef(farkas.get_local(v), -1); - - e.finalize(); - if (farkas_debug > 1) { - fprintf(DebugFile,"Constraint is %s\n", e.print_to_string().c_str()); - } - use_ugly_names--; -} - - -Relation Farkas(NOT_CONST Relation &input_R, Farkas_Type op, bool early_bailout) { - assert(!input_R.is_null()); - int saved_use_ugly_names = use_ugly_names; - - use_ugly_names++; - farkasDifficulty = 0; - - Relation R = consume_and_regurgitate(input_R); - - if (op == Basic_Farkas || op == Decoupled_Farkas) { - R.simplify(2, 4); - R = Approximate(R, false); - } - - Relation result = Relation::False(R); - - if (farkas_debug) { - fprintf(DebugFile,"Computing farka of: [\n"); - R.prefix_print(DebugFile); - } - - Variable_ID_Tuple vars; - for (Variable_ID_Iterator v(*R.global_decls()); v; v++) vars.append(*v); - if (R.is_set()) - for(int i=1; i <= R.n_set(); i++) vars.append(R.set_var(i)); - else { - int i; - for(i=1; i <= R.n_inp(); i++) vars.append(R.input_var(i)); - for(i=1; i <= R.n_out(); i++) vars.append(R.output_var(i)); - } - - Set<Variable_ID> empty; - Variable_ID_Tuple owners; - Map<Variable_ID, Set<Variable_ID> > connectedVariables(empty); - - if (op == Decoupled_Farkas) { - for (Variable_ID_Iterator v(*R.global_decls()); v; v++) - if ((*v)->kind() == Global_Var) { - Global_Var_ID g = (*v)->get_global_var(); - if (g->arity() > 0) { - if (R.is_set()) - for(int i=1; i <= g->arity(); i++) - (*v)->UF_union(R.set_var(i)); - else if ((*v)->function_of() == Input_Tuple) - for(int i=1; i <= g->arity(); i++) - (*v)->UF_union(R.input_var(i)); - else - for(int i=1; i <= g->arity(); i++) - (*v)->UF_union(R.output_var(i)); - } - } - - for (DNF_Iterator s(R.query_DNF()); s.live(); s.next()) { - for (Variable_ID_Iterator v1(*(*s)->variables()); v1; v1++) { - for (EQ_Iterator eq = (*s)->EQs(); eq.live(); eq.next()) - if ((*eq).get_coef(*v1)) - for (Variable_ID_Iterator v2(*(*s)->variables()); v2; v2++) - if ((*eq).get_coef(*v2)) - (*v1)->UF_union(*v2); - for (GEQ_Iterator g = (*s)->GEQs(); g.live(); g.next()) - if ((*g).get_coef(*v1)) - for (Variable_ID_Iterator v2(*(*s)->variables()); v2; v2++) - if ((*g).get_coef(*v2)) - (*v1)->UF_union(*v2); - } - } - for (Variable_ID_Iterator v3(vars); v3.live(); v3.next()) - connectedVariables[(*v3)->UF_owner()] |= *v3; - - foreach_map(v,Variable_ID,s,Set<Variable_ID>,connectedVariables, - owners.append(v); - if (farkas_debug) { - fprintf(DebugFile,"%s:",v->char_name()); - foreach(v2,Variable_ID,s, - fprintf(DebugFile," %s",v2->char_name()); - ); - fprintf(DebugFile,"\n"); - } - ); - } - - Variable_ID_Iterator varGroup(owners); - int lambda_cnt = 1; - - Relation partialResult; - bool firstGroup = true; - try { - while ((op == Decoupled_Farkas && varGroup.live()) - || (op != Decoupled_Farkas && firstGroup)) { - - if (farkas_debug && op == Decoupled_Farkas) { - fprintf(DebugFile,"[Computing decoupled farkas for:"); - foreach(v2,Variable_ID,connectedVariables(varGroup.curr()), - fprintf(DebugFile," %s",v2->char_name()); - ); - fprintf(DebugFile,"\n"); - } - firstGroup = false; - partialResult = Relation::True(R); - coef_t difficulty = 0; - for (DNF_Iterator s(R.query_DNF()); s.live(); s.next()) { - int nz; - coef_t m,sum; - (*s)->difficulty(nz,m,sum); - difficulty = max((coef_t) nz,2*nz+2*m+sum); - if (farkas_debug) { - fprintf(DebugFile,"Computing farka of conjunct: \n"); - (*s)->prefix_print(DebugFile); - fprintf(DebugFile,"Difficulty is " coef_fmt "(%d," coef_fmt "," coef_fmt ")\n", difficulty,nz,m,sum); - } - if (early_bailout && difficulty >= 500) { - farkasDifficulty = difficulty; - if (farkas_debug) { - fprintf(DebugFile,"Too ugly, returning dull result\n"); - } - use_ugly_names--; - if (op == Basic_Farkas || op == Decoupled_Farkas) - return Relation::False(partialResult); - else return Relation::True(partialResult); - } - Relation farkas = Relation::Empty(R); - farkas.copy_names(R); - F_Exists* exist = farkas.add_exists(); - F_And* and_node = exist->add_and(); - Map<GEQ_Handle, Variable_ID> gMap((Variable_ID)0); - Map<EQ_Handle, Variable_ID> eMap((Variable_ID)0); - for (EQ_Iterator eq = (*s)->EQs(); eq.live(); eq.next()) { - if (op == Decoupled_Farkas) { - bool ShouldConsider = true; - for (Variable_ID_Iterator v(*(*s)->variables()); v; v++) { - if ((*eq).get_coef(*v) != 0 - && (*v)->UF_owner() != varGroup.curr()) { - ShouldConsider = false; - break; - } - } - if (!ShouldConsider) continue; - } - char s[10]; - sprintf(s, "lambda%d", lambda_cnt++); - eMap[*eq] = exist->declare(s); - assert(op == Basic_Farkas || op == Decoupled_Farkas - || (*eq).get_const() == 0); - } - for (GEQ_Iterator g = (*s)->GEQs(); g.live(); g.next()) { - if (op == Decoupled_Farkas) { - bool ShouldConsider = true; - for (Variable_ID_Iterator v(*(*s)->variables()); v; v++) { - if ((*g).get_coef(*v) != 0 - && (*v)->UF_owner() != varGroup.curr()) { - ShouldConsider = false; - break; - } - } - if (!ShouldConsider) continue; - } - char s[10]; - sprintf(s, "lambda%d", lambda_cnt++); - Variable_ID lambda = exist->declare(s); - GEQ_Handle positive; - switch(op) { - case Positive_Combination_Farkas: - case Convex_Combination_Farkas: - case Basic_Farkas: - case Decoupled_Farkas: - positive = and_node->add_GEQ(); - positive.update_coef(lambda, 1); - positive.finalize(); - break; - case Linear_Combination_Farkas: - case Affine_Combination_Farkas: - break; - } - gMap[*g] = lambda; - assert(op == Basic_Farkas || op == Decoupled_Farkas || (*g).get_const() == 0); - } - - for (Variable_ID_Iterator v(vars); v; v++) { - assert((*v)->kind() != Wildcard_Var); - if ((*v)->kind() == Global_Var - && (*v)->get_global_var() == coefficient_of_constant_term) { - assert(op != Basic_Farkas && op != Decoupled_Farkas); - if (op == Linear_Combination_Farkas) continue; - if (op == Positive_Combination_Farkas) continue; - } - if (op == Decoupled_Farkas && (*v)->UF_owner() != varGroup.curr()) { - EQ_Handle e = and_node->add_EQ(); - e.update_coef(farkas.get_local(*v),-1); - continue; - } - handleVariable(farkas, *s, and_node, gMap,eMap, *v); - } - - if (op == Basic_Farkas || op == Decoupled_Farkas) { - GEQ_Handle e = and_node->add_GEQ(); - e.update_coef(farkas.get_local(coefficient_of_constant_term),1); - for (GEQ_Iterator g = s.curr()->GEQs(); g.live(); g.next()) - if (gMap(*g) != (Variable_ID) 0) - e.update_coef( gMap(*g),-(*g).get_const()); - for (EQ_Iterator eq = s.curr()->EQs(); eq.live(); eq.next()) - if (eMap(*eq) != (Variable_ID) 0) - e.update_coef(eMap(*eq),-(*eq).get_const()); - e.finalize(); - } - - // lambda variables are not integers, so disable integer problem solving, - // we just mark it as simplified. - farkas.simplify(-1, -1); - - farkas.single_conjunct()->difficulty(nz,m,sum); - difficulty = max((coef_t) nz,2*nz+2*m+sum); - if (farkas_debug) { - fprintf(DebugFile,"farka has difficulty " coef_fmt "(%d," coef_fmt "," coef_fmt "):\n", difficulty,nz,m,sum); - farkas.prefix_print(DebugFile); - } - if (early_bailout && difficulty >= 500) { - farkasDifficulty = difficulty; - if (farkas_debug) { - fprintf(DebugFile,"Too ugly, returning dull result\n"); - } - use_ugly_names--; - if (op == Basic_Farkas || op == Decoupled_Farkas) - return Relation::False(partialResult); - else return Relation::True(partialResult); - } - farkas = Approximate(farkas); - if (farkas_debug) { - fprintf(DebugFile,"simplified:\n"); - farkas.prefix_print(DebugFile); - } - partialResult = Approximate(Intersection(partialResult,farkas)); - if (farkas_debug) { - fprintf(DebugFile,"combined:\n"); - partialResult.prefix_print(DebugFile); - } - if (partialResult.has_single_conjunct()) { - partialResult.single_conjunct()->difficulty(nz,m,sum); - difficulty = max((coef_t) nz,2*nz+2*m+sum); - } - else - difficulty = 1000; - if (early_bailout && difficulty >= 500) { - farkasDifficulty = difficulty; - if (farkas_debug) { - fprintf(DebugFile,"Too ugly, returning dull result\n"); - } - use_ugly_names--; - if (op == Basic_Farkas || op == Decoupled_Farkas) - return Relation::False(partialResult); - else return Relation::True(partialResult); - } - } - farkasDifficulty += difficulty; - - if (farkas_debug) { - fprintf(DebugFile,"] done computing farkas\n"); - partialResult.prefix_print(DebugFile); - } - - if (op == Decoupled_Farkas) { - result = Union(result,partialResult); - varGroup.next(); - } - } - } - catch (const std::overflow_error &e) { - // clear global variables - inApproximateMode = 0; - use_ugly_names = saved_use_ugly_names; - - if (early_bailout) { - if (farkasDifficulty < 1000) - farkasDifficulty = 1000; - // return dull result - if (op == Basic_Farkas || op == Decoupled_Farkas) - return Relation::False(partialResult); - else - return Relation::True(partialResult); - } - else - throw std::overflow_error("farkas too ugly"); - } - - if (1 || op == Decoupled_Farkas) { - foreach(v,Variable_ID,vars, reset_remap_field(v)); - } - use_ugly_names--; - if (op == Decoupled_Farkas) { - if (farkas_debug) { - fprintf(DebugFile,"] decoupled result:\n"); - result.prefix_print(DebugFile); - } - return result; - } - return partialResult; -} - -} // namespace diff --git a/omegalib/omega/src/hull_legacy.cc b/omegalib/omega/src/hull_legacy.cc deleted file mode 100755 index a59d34f..0000000 --- a/omegalib/omega/src/hull_legacy.cc +++ /dev/null @@ -1,1484 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Legacy hull calculations' implementation. - - Notes: - - History: - 06/15/09 ConvexRepresentation, Chun Chen - 11/25/09 RectHull, Chun Chen -*****************************************************************************/ - -#include <omega.h> -#include <omega/farkas.h> -#include <omega/hull.h> -#include <basic/Bag.h> -#include <basic/omega_error.h> -#include <list> -#include <vector> -#include <set> - -namespace omega { - -int hull_debug = 0; - -Relation ConvexHull(NOT_CONST Relation &R) { - Relation S = Approximate(consume_and_regurgitate(R)); - if (!S.is_upper_bound_satisfiable()) - return S; - if (S.has_single_conjunct()) - return S; - return Farkas(Farkas(S,Basic_Farkas), Convex_Combination_Farkas); -} - -Relation DecoupledConvexHull(NOT_CONST Relation &R) { - Relation S = Approximate(consume_and_regurgitate(R)); - if (!S.is_upper_bound_satisfiable()) - return S; - if (S.has_single_conjunct()) - return S; - return Farkas(Farkas(S,Decoupled_Farkas), Convex_Combination_Farkas); -} - -Relation AffineHull(NOT_CONST Relation &R) { - Relation S = Approximate(consume_and_regurgitate(R)); - if (!S.is_upper_bound_satisfiable()) - return S; - return Farkas(Farkas(S,Basic_Farkas), Affine_Combination_Farkas); -} - -Relation LinearHull(NOT_CONST Relation &R) { - Relation S = Approximate(consume_and_regurgitate(R)); - if (!S.is_upper_bound_satisfiable()) - return S; - return Farkas(Farkas(S,Basic_Farkas), Linear_Combination_Farkas); -} - -Relation ConicHull(NOT_CONST Relation &R) { - Relation S = Approximate(consume_and_regurgitate(R)); - if (!S.is_upper_bound_satisfiable()) - return S; - return Farkas(Farkas(S,Basic_Farkas), Positive_Combination_Farkas); -} - - -Relation FastTightHull(NOT_CONST Relation &input_R, NOT_CONST Relation &input_H) { - Relation R = Approximate(consume_and_regurgitate(input_R)); - Relation H = Approximate(consume_and_regurgitate(input_H)); - - if (hull_debug) { - fprintf(DebugFile,"[ Computing FastTightHull of:\n"); - R.prefix_print(DebugFile); - fprintf(DebugFile,"given known hull of:\n"); - H.prefix_print(DebugFile); - } - - if (!H.has_single_conjunct()) { - if (hull_debug) - fprintf(DebugFile, "] bailing out of FastTightHull, known hull not convex\n"); - return H; - } - - if (!H.is_obvious_tautology()) { - R = Gist(R,copy(H)); - R.simplify(1,0); - } - - if (R.has_single_conjunct()) { - R = Intersection(R,H); - if (hull_debug) { - fprintf(DebugFile, "] quick easy answer to FastTightHull\n"); - R.prefix_print(DebugFile); - } - return R; - } - if (R.has_local(coefficient_of_constant_term)) { - if (hull_debug) { - fprintf(DebugFile, "] Can't handle recursive application of Farkas lemma\n"); - } - return H; - } - - if (hull_debug) { - fprintf(DebugFile,"Gist of R given H is:\n"); - R.prefix_print(DebugFile); - } - - if (1) { - Set<Variable_ID> vars; - int conjuncts = 0; - for (DNF_Iterator s(R.query_DNF()); s.live(); s.next()) { - conjuncts++; - for (Variable_ID_Iterator v(*((*s)->variables())); v.live(); v++) { - bool found = false; - for (EQ_Iterator eq = (*s)->EQs(); eq.live(); eq.next()) - if ((*eq).get_coef(*v) != 0) { - if (!found) vars.insert(*v); - found = true; - break; - } - if (!found) - for (GEQ_Iterator geq = (*s)->GEQs(); geq.live(); geq.next()) - if ((*geq).get_coef(*v) != 0) { - if (!found) vars.insert(*v); - found = true; - break; - } - } - } - - - // We now know which variables appear in R - if (hull_debug) { - fprintf(DebugFile,"Variables we need a better hull on are: "); - foreach(v,Variable_ID,vars, - fprintf(DebugFile," %s",v->char_name())); - fprintf(DebugFile,"\n"); - } - Conjunct *c = H.single_conjunct(); - int total=0; - int copied = 0; - for (EQ_Iterator eq = c->EQs(); eq.live(); eq.next()) { - total++; - foreach(v,Variable_ID,vars, - if ((*eq).get_coef(v) != 0) { - R.and_with_EQ(*eq); - copied++; - break; // out of variable loop - } - ); - } - for (GEQ_Iterator geq = c->GEQs(); geq.live(); geq.next()) { - total++; - foreach(v,Variable_ID,vars, - if ((*geq).get_coef(v) != 0) { - R.and_with_GEQ(*geq); - copied++; - break; // out of variable loop - } - ); - } - if (copied < total) { - R = Approximate(R); - - if (hull_debug) { - fprintf(DebugFile,"Decomposed relation, copied only %d of %d constraints\n",copied,total); - fprintf(DebugFile,"Original R:\n"); - R.prefix_print(DebugFile); - fprintf(DebugFile,"Known hull:\n"); - H.prefix_print(DebugFile); - fprintf(DebugFile,"New R:\n"); - R.prefix_print(DebugFile); - } - } - } - - Relation F = Farkas(copy(R), Basic_Farkas, true); - if (hull_debug) - fprintf(DebugFile,"Farkas Difficulty = " coef_fmt "\n", farkasDifficulty); - if (farkasDifficulty > 260) { - if (hull_debug) { - fprintf(DebugFile, "] bailing out, farkas is way too complex\n"); - fprintf(DebugFile,"Farkas:\n"); - F.prefix_print(DebugFile); - } - return H; - } - else if (farkasDifficulty > 130) { - // Bail out - if (hull_debug) { - fprintf(DebugFile, coef_fmt " non-zeros in original farkas\n", farkasDifficulty); - } - Relation tmp = Farkas(R, Decoupled_Farkas, true); - - if (hull_debug) { - fprintf(DebugFile, coef_fmt " non-zeros in decoupled farkas\n", farkasDifficulty); - } - if (farkasDifficulty > 260) { - if (hull_debug) { - fprintf(DebugFile, "] bailing out, farkas is way too complex\n"); - fprintf(DebugFile,"Farkas:\n"); - F.prefix_print(DebugFile); - } - return H; - } - else { - if (farkasDifficulty > 130) - R = Intersection(H, Farkas(tmp, Affine_Combination_Farkas, true)); - else R = Intersection(H, - Intersection(Farkas(tmp, Convex_Combination_Farkas, true), - Farkas(F, Affine_Combination_Farkas, true))); - if (hull_debug) { - fprintf(DebugFile, "] bailing out, farkas is too complex, using affine hull\n"); - fprintf(DebugFile,"Farkas:\n"); - F.prefix_print(DebugFile); - fprintf(DebugFile,"Affine hull:\n"); - R.prefix_print(DebugFile); - } - return R; - } - } - - R = Intersection(H, Farkas(F, Convex_Combination_Farkas, true)); - if (hull_debug) { - fprintf(DebugFile, "] Result of FastTightHull:\n"); - R.prefix_print(DebugFile); - } - return R; -} - - - -namespace { - bool parallel(const GEQ_Handle &g1, const GEQ_Handle &g2) { - for(Constr_Vars_Iter cvi(g1, false); cvi; cvi++) { - coef_t c1 = (*cvi).coef; - coef_t c2 = g2.get_coef((*cvi).var); - if (c1 != c2) return false; - } - { - for(Constr_Vars_Iter cvi(g2, false); cvi; cvi++) { - coef_t c1 = g1.get_coef((*cvi).var); - coef_t c2 = (*cvi).coef; - if (c1 != c2) return false; - } - } - return true; - } - - - bool hull(const EQ_Handle &e, const GEQ_Handle &g, coef_t &hull) { - int sign = 0; - for(Constr_Vars_Iter cvi(e, false); cvi; cvi++) { - coef_t c1 = (*cvi).coef; - coef_t c2 = g.get_coef((*cvi).var); - if (sign == 0) sign = (c1*c2>=0?1:-1); - if (sign*c1 != c2) return false; - } - assert(sign != 0); - { - for(Constr_Vars_Iter cvi(g, false); cvi; cvi++) { - coef_t c1 = e.get_coef((*cvi).var); - coef_t c2 = (*cvi).coef; - if (sign*c1 != c2) return false; - } - } - hull = max(sign * e.get_const(), g.get_const()); - if (hull_debug) { - fprintf(DebugFile,"Hull of:\n %s\n", e.print_to_string().c_str()); - fprintf(DebugFile," %s\n", g.print_to_string().c_str()); - fprintf(DebugFile,"is " coef_fmt "\n\n",hull); - } - return true; - } - - bool eq(const EQ_Handle &e1, const EQ_Handle &e2) { - int sign = 0; - for(Constr_Vars_Iter cvi(e1, false); cvi; cvi++) { - coef_t c1 = (*cvi).coef; - coef_t c2 = e2.get_coef((*cvi).var); - if (sign == 0) sign = (c1*c2>=0?1:-1); - if (sign*c1 != c2) return false; - } - assert(sign != 0); - { - for(Constr_Vars_Iter cvi(e2, false); cvi; cvi++) { - coef_t c1 = e1.get_coef((*cvi).var); - coef_t c2 = (*cvi).coef; - if (sign*c1 != c2) return false; - } - } - return sign * e1.get_const() == e2.get_const(); - } -} - - -// This function is deprecated!!! -Relation QuickHull(Relation &R) { - Tuple<Relation> Rs(1); - Rs[1] = R; - return QuickHull(Rs); -} - - -// This function is deprecated!!! -Relation QuickHull(Tuple<Relation> &Rs) { - assert(!Rs.empty()); - - // if (Rs.size() == 1) return Rs[1]; - - Tuple<Relation> l_Rs; - for (int i = 1; i <= Rs.size(); i++) - for (DNF_Iterator c(Rs[i].query_DNF()); c; c++) { - Relation r = Relation(Rs[i], c.curr()); - l_Rs.append(Approximate(r)); - } - - if (l_Rs.size() == 1) - return l_Rs[1]; - - Relation result = Relation::True(Rs[1]); - result.copy_names(Rs[1]); - - use_ugly_names++; - - if (hull_debug > 1) - for (int i = 1; i <= l_Rs.size(); i++) { - fprintf(DebugFile,"#%d \n",i); - l_Rs[i].prefix_print(DebugFile); - } - - -// Relation R = copy(Rs[1]); -// for (int i = 2; i <= Rs.size(); i++) -// R = Union(R,copy(Rs[i])); - -// #if 0 -// if (!R.is_set()) { -// if (R.n_inp() == R.n_out()) { -// Relation AC = DeltasToRelation(Hull(Deltas(copy(R), -// min(R.n_inp(),R.n_out()))), -// R.n_inp(),R.n_out()); -// Relation dH = Hull(Domain(copy(R)),false); -// Relation rH = Hull(Range(copy(R)),false); -// result = Intersection(AC,Cross_Product(dH,rH)); -// } -// else { -// Relation dH = Hull(Domain(copy(R)),false); -// Relation rH = Hull(Range(copy(R)),false); -// result = Cross_Product(dH,rH); -// assert(Must_Be_Subset(copy(R),copy(result))); -// } -// } - -// #endif - - Conjunct *first; - l_Rs[1] = EQs_to_GEQs(l_Rs[1]); - first = l_Rs[1].single_conjunct(); - for (GEQ_Iterator candidate(first->GEQs()); candidate.live(); candidate.next()) { - coef_t maxConstantTerm = (*candidate).get_const(); - bool found = true; - if (hull_debug > 1) { - fprintf(DebugFile,"searching for bound on:\n %s\n", (*candidate).print_to_string().c_str()); - } - for (int i = 2; i <= l_Rs.size(); i++) { - Conjunct *other = l_Rs[i].single_conjunct(); - bool found_for_i = false; - for (GEQ_Iterator target(other->GEQs()); target.live(); target.next()) { - if (hull_debug > 2) { - fprintf(DebugFile,"candidate:\n %s\n", (*candidate).print_to_string().c_str()); - fprintf(DebugFile,"target:\n %s\n", (*target).print_to_string().c_str()); - } - if (parallel(*candidate,*target)) { - if (hull_debug > 1) - fprintf(DebugFile,"Found bound:\n %s\n", (*target).print_to_string().c_str()); - maxConstantTerm = max(maxConstantTerm,(*target).get_const()); - found_for_i = true; - break; - } - } - if (!found_for_i) { - for (EQ_Iterator target_e(other->EQs()); target_e.live(); target_e.next()) { - coef_t h; - if (hull(*target_e,*candidate,h)) { - if (hull_debug > 1) - fprintf(DebugFile,"Found bound of " coef_fmt ":\n %s\n", h, (*target_e).print_to_string().c_str()); - maxConstantTerm = max(maxConstantTerm,h); - found_for_i = true; - break; - } - }; - if (!found_for_i) { - if (hull_debug > 1) { - fprintf(DebugFile,"No bound found in:\n"); - fprintf(DebugFile, "%s", l_Rs[i].print_with_subs_to_string().c_str()); - } - //if nothing found - found = false; - break; - } - } - } - - if (found) { - GEQ_Handle h = result.and_with_GEQ(); - copy_constraint(h,*candidate); - if (hull_debug > 1) - fprintf(DebugFile,"Setting constant term to " coef_fmt " in\n %s\n", maxConstantTerm, h.print_to_string().c_str()); - h.update_const(maxConstantTerm - (*candidate).get_const()); - if (hull_debug > 1) - fprintf(DebugFile,"Updated constraint is\n %s\n", h.print_to_string().c_str()); - } - } - - - for (EQ_Iterator candidate_eq(first->EQs()); candidate_eq.live(); candidate_eq.next()) { - bool found = true; - for (int i = 2; i <= l_Rs.size(); i++) { - Conjunct *C = l_Rs[i].single_conjunct(); - bool found_for_i = false; - - for (EQ_Iterator target(C->EQs()); target.live(); target.next()) { - if (eq(*candidate_eq,*target)) { - found_for_i = true; - break; - } - } - if (!found_for_i) { - //if nothing found - found = false; - break; - } - } - - if (found) { - EQ_Handle h = result.and_with_EQ(); - copy_constraint(h,*candidate_eq); - if (hull_debug > 1) - fprintf(DebugFile,"Adding eq constraint: %s\n", h.print_to_string().c_str()); - } - } - - use_ugly_names--; - if (hull_debug > 1) { - fprintf(DebugFile,"quick hull is of:"); - result.print_with_subs(DebugFile); - } - return result; -} - - -// Relation Hull2(Tuple<Relation> &Rs, Tuple<int> &active) { -// assert(Rs.size() == active.size() && Rs.size() > 0); - -// Tuple<Relation> l_Rs; -// for (int i = 1; i <= Rs.size(); i++) -// if (active[i]) -// l_Rs.append(copy(Rs[i])); - -// if (l_Rs.size() == 0) -// return Relation::False(Rs[1]); - -// try { -// Relation r = l_Rs[1]; -// for (int i = 2; i <= l_Rs.size(); i++) { -// r = Union(r, copy(l_Rs[i])); -// r.simplify(); -// } - -// // Relation F = Farkas(r, Basic_Farkas, true); -// // if (farkasDifficulty >= 500) -// // throw std::overflow_error("loop convex hull too complicated."); -// // F = Farkas(F, Convex_Combination_Farkas, true); -// return Farkas(Farkas(r, Basic_Farkas, true), Convex_Combination_Farkas, true); -// } -// catch (std::overflow_error) { -// return QuickHull(l_Rs); -// } -// } - - -namespace { - void printRs(Tuple<Relation> &Rs) { - fprintf(DebugFile,"Rs:\n"); - for (int i = 1; i <= Rs.size(); i++) - fprintf(DebugFile,"#%d : %s\n",i, - Rs[i].print_with_subs_to_string().c_str()); - } -} - -Relation BetterHull(Tuple<Relation> &Rs, bool stridesAllowed, bool checkSubsets, - NOT_CONST Relation &input_knownHull = Relation::Null()) { - Relation knownHull = consume_and_regurgitate(input_knownHull); - static int OMEGA_WHINGE = -1; - if (OMEGA_WHINGE < 0) { - OMEGA_WHINGE = getenv("OMEGA_WHINGE") ? atoi(getenv("OMEGA_WHINGE")) : 0; - } - assert(!Rs.empty()); - if (Rs.size() == 1) { - if (stridesAllowed) return Rs[1]; - else return Approximate(Rs[1]); - } - - if (checkSubsets) { - Tuple<bool> live(Rs.size()); - if (hull_debug) { - fprintf(DebugFile,"Checking subsets in hull computation:\n"); - printRs(Rs); - } - int i; - for(i=1;i <=Rs.size(); i++) live[i] = true; - for(i=1;i <=Rs.size(); i++) - for(int j=1;j <=Rs.size(); j++) if (i != j && live[j]) { - if (hull_debug) fprintf(DebugFile,"checking %d Is_Obvious_Subset %d\n",i,j); - if (Is_Obvious_Subset(copy(Rs[i]),copy(Rs[j]))) { - if (hull_debug) fprintf(DebugFile,"yes...\n"); - live[i] = false; - break; - } - } - for(i=1;i <=Rs.size(); i++) if (!live[i]) { - if (i < Rs.size()) { - Rs[i] = Rs[Rs.size()]; - live[i] = live[Rs.size()]; - } - Rs[Rs.size()] = Relation(); - Rs.delete_last(); - i--; - } - } - Relation hull; - if (hull_debug) { - fprintf(DebugFile,"Better Hull:\n"); - printRs(Rs); - fprintf(DebugFile,"known hull: %s\n", knownHull.print_with_subs_to_string().c_str()); - } - if (knownHull.is_null()) hull = QuickHull(Rs); - else hull = Intersection(QuickHull(Rs),knownHull); - // for (int i = 1; i <= Rs.size(); i++) - // hull = RectHull(Union(hull, copy(Rs[i]))); - // hull = Intersection(hull, knownHull); - hull.simplify(); - if (hull_debug) { - fprintf(DebugFile,"quick hull: %s\n", hull.print_with_subs_to_string().c_str()); - } - - Relation orig = Relation::False(Rs[1]); - int i; - for (i = 1; i <= Rs.size(); i++) - orig = Union(orig,copy(Rs[i])); - - orig.simplify(); - - for (i = 1; i <= Rs.size(); i++) { - if (!hull.is_obvious_tautology()) Rs[i] = Gist(Rs[i],copy(hull)); - Rs[i].simplify(); - if (Rs[i].is_obvious_tautology()) return hull; - if (Rs[i].has_single_conjunct()) { - Rs[i] = EQs_to_GEQs(Rs[i]); - if (hull_debug) { - fprintf(DebugFile,"Checking for hull constraints in:\n %s\n", Rs[i].print_with_subs_to_string().c_str()); - } - Conjunct *c = Rs[i].single_conjunct(); - for (GEQ_Iterator g(c->GEQs()); g.live(); g.next()) { - Relation tmp = Relation::True(Rs[i]); - tmp.and_with_GEQ(*g); - if (!Difference(copy(orig),tmp).is_upper_bound_satisfiable()) - hull.and_with_GEQ(*g); - } - for (EQ_Iterator e(c->EQs()); e.live(); e.next()) { - Relation tmp = Relation::True(Rs[i]); - tmp.and_with_EQ(*e); - if (!Difference(copy(orig),tmp).is_upper_bound_satisfiable()) - hull.and_with_EQ(*e); - } - } - } - - hull = FastTightHull(orig,hull); - assert(hull.has_single_conjunct()); - - if (stridesAllowed) return hull; - else return Approximate(hull); - -} - - - -Relation Hull(NOT_CONST Relation &S, - bool stridesAllowed, - int effort, - NOT_CONST Relation &knownHull) { - Relation R = consume_and_regurgitate(S); - R.simplify(1,0); - if (!R.is_upper_bound_satisfiable()) return R; - Tuple<Relation> Rs; - for (DNF_Iterator c(R.query_DNF()); c.live(); ) { - Rs.append(Relation(R,c.curr())); - c.next(); - } - if (effort == 1) - return BetterHull(Rs,stridesAllowed,false,knownHull); - else - return QuickHull(Rs); -} - - - -Relation Hull(Tuple<Relation> &Rs, - const std::vector<bool> &validMask, - int effort, - bool stridesAllowed, - NOT_CONST Relation &knownHull) { - // Use relation of index i only when validMask[i] != 0 - Tuple<Relation> Rs2; - for(int i = 1; i <= Rs.size(); i++) { - if (validMask[i-1]) { - Rs[i].simplify(); - for (DNF_Iterator c(Rs[i].query_DNF()); c.live(); ) { - Rs2.append(Relation(Rs[i],c.curr())); - c.next(); - } - } - } - assert(effort == 0 || effort == 1); - if (effort == 1) - return BetterHull(Rs2,stridesAllowed,true,knownHull); - else - return QuickHull(Rs2); -} - - -// This function is deprecated!!! -Relation CheckForConvexRepresentation(NOT_CONST Relation &R_In) { - Relation R = consume_and_regurgitate(R_In); - Relation h = Hull(copy(R)); - if (!Difference(copy(h),copy(R)).is_upper_bound_satisfiable()) - return h; - else - return R; -} - -// This function is deprecated!!! -Relation CheckForConvexPairs(NOT_CONST Relation &S) { - Relation R = consume_and_regurgitate(S); - Relation hull = FastTightHull(copy(R),Relation::True(R)); - R.simplify(1,0); - if (!R.is_upper_bound_satisfiable() || R.number_of_conjuncts() < 2) return R; - Tuple<Relation> Rs; - for (DNF_Iterator c(R.query_DNF()); c.live(); ) { - Rs.append(Relation(R,c.curr())); - c.next(); - } - - bool *dead = new bool[Rs.size()+1]; - int i; - for(i = 1; i<=Rs.size();i++) dead[i] = false; - - for(i = 1; i<=Rs.size();i++) - if (!dead[i]) - for(int j = i+1; j<=Rs.size();j++) if (!dead[j]) { - if (hull_debug) { - fprintf(DebugFile,"Comparing #%d and %d\n",i,j); - } - Relation U = Union(copy(Rs[i]),copy(Rs[j])); - Relation H_ij = FastTightHull(copy(U),copy(hull)); - if (!Difference(copy(H_ij),U).is_upper_bound_satisfiable()) { - Rs[i] = H_ij; - dead[j] = true; - if (hull_debug) { - fprintf(DebugFile,"Combined them\n"); - } - } - } - i = 1; - while(i<=Rs.size() && dead[i]) i++; - assert(i<=Rs.size()); - R = Rs[i]; - i++; - for(; i<=Rs.size();i++) - if (!dead[i]) - R = Union(R,Rs[i]); - delete []dead; - return R; -} - -// -// Supporting functions for ConvexRepresentation -// -namespace { -struct Interval { - std::list<std::pair<Relation, Relation> >::iterator pos; - coef_t lb; - coef_t ub; - bool change; - coef_t modulo; - Interval(std::list<std::pair<Relation, Relation> >::iterator pos_, coef_t lb_, coef_t ub_): - pos(pos_), lb(lb_), ub(ub_) {} - friend bool operator<(const Interval &a, const Interval &b); -}; - -bool operator<(const Interval &a, const Interval &b) { - return a.lb < b.lb; -} - -struct Modulo_Interval { - coef_t modulo; - coef_t start; - coef_t size; - Modulo_Interval(coef_t modulo_, coef_t start_, coef_t size_): - modulo(modulo_), start(start_), size(size_) {} - friend bool operator<(const Interval &a, const Interval &b); -}; - -bool operator<(const Modulo_Interval &a, const Modulo_Interval &b) { - if (a.modulo == b.modulo) { - if (a.start == b.start) - return a.size < b.size; - else - return a.start < b.start; - } - else - return a.modulo < b.modulo; -} - -void merge_intervals(std::list<Interval> &intervals, coef_t modulo, std::list<std::pair<Relation, Relation> > &Rs, std::list<std::pair<Relation, Relation> >::iterator orig) { - // normalize intervals - for (std::list<Interval>::iterator i = intervals.begin(); i != intervals.end(); i++) { - (*i).modulo = modulo; - (*i).change = false; - if ((*i).ub - (*i).lb + 1>= modulo) { - (*i).lb = 0; - (*i).ub = modulo - 1; - } - else if ((*i).ub < 0 || (*i).lb >= modulo) { - coef_t range = (*i).ub - (*i).lb; - (*i).lb = int_mod((*i).lb, modulo); - (*i).ub = (*i).lb + range; - } - } - - intervals.sort(); - - // merge neighboring intervals - std::list<Interval>::iterator p = intervals.begin(); - while (p != intervals.end()) { - std::list<Interval>::iterator q = p; - q++; - while (q != intervals.end()) { - if ((*p).ub + 1 >= (*q).lb) { - Relation hull = ConvexHull(Union(copy((*(*p).pos).first), copy((*(*q).pos).first))); - Relation remainder = Difference(Difference(copy(hull), copy((*(*p).pos).first)), copy((*(*q).pos).first)); - if (!remainder.is_upper_bound_satisfiable()) { - if ((*q).pos == orig) - std::swap((*p).pos, (*q).pos); - (*(*p).pos).first = hull; - (*p).ub = max((*p).ub, (*q).ub); - (*p).change = true; - Rs.erase((*q).pos); - q = intervals.erase(q); - } - else - break; - } - else - break; - } - - bool p_moved = false; - q = p; - q++; - while (q != intervals.end()) { - if ((*q).ub >= modulo && int_mod((*q).ub, modulo) + 1 >= (*p).lb) { - Relation hull = ConvexHull(Union(copy((*(*p).pos).first), copy((*(*q).pos).first))); - Relation remainder = Difference(Difference(copy(hull), copy((*(*p).pos).first)), copy((*(*q).pos).first)); - if (!remainder.is_upper_bound_satisfiable()) { - if ((*p).pos == orig) - std::swap((*p).pos, (*q).pos); - (*(*q).pos).first = hull; - coef_t t = (*p).ub - int_mod((*q).ub, modulo); - if (t > 0) - (*q).ub = (*q).ub + t; - (*q).change = true; - Rs.erase((*p).pos); - p = intervals.erase(p); - p_moved = true; - break; - } - else - q++; - } - else - q++; - } - - if (!p_moved) - p++; - } - - // merge by reducing the strengh of modulo - std::list<Modulo_Interval> modulo_intervals; - coef_t max_distance = modulo/2; - for (std::list<Interval>::iterator p = intervals.begin(); p != intervals.end(); p++) { - if ((*p).lb >= max_distance) - break; - - coef_t size = (*p).ub - (*p).lb; - - std::list<Interval>::iterator q = p; - q++; - while (q != intervals.end()) { - coef_t distance = (*q).lb - (*p).lb; - if (distance > max_distance) - break; - - if ((*q).ub - (*q).lb != size || int_mod(modulo, distance) != 0) { - q++; - continue; - } - - int num_reduced = 0; - coef_t looking_for = int_mod((*p).lb, distance); - for (std::list<Interval>::iterator k = intervals.begin(); k != intervals.end(); k++) { - if ((*k).lb == looking_for && (*k).ub - (*k).lb == size) { - num_reduced++; - looking_for += distance; - if (looking_for >= modulo) - break; - } - else if ((*k).lb <= looking_for && (*k).ub >= looking_for + size) { - looking_for += distance; - if (looking_for >= modulo) - break; - } - else if ((*k).lb > looking_for) - break; - } - - if (looking_for >= modulo && num_reduced > 1) - modulo_intervals.push_back(Modulo_Interval(distance, int_mod((*p).lb, distance), size)); - - q++; - } - } - - modulo_intervals.sort(); - - // remove redundant reduced-strength intervals - std::list<Modulo_Interval>::iterator p2 = modulo_intervals.begin(); - while (p2 != modulo_intervals.end()) { - std::list<Modulo_Interval>::iterator q2 = p2; - q2++; - while (q2 != modulo_intervals.end()) { - if ((*p2).modulo == (*q2).modulo && (*p2).start == (*q2).start) - q2 = modulo_intervals.erase(q2); - else if (int_mod((*q2).modulo, (*p2).modulo) == 0 && - (*p2).start == int_mod((*q2).start, (*p2).modulo) && - (*p2).size >= (*q2).size) - q2 = modulo_intervals.erase(q2); - else - q2++; - } - p2++; - } - - // replace original intervals with new reduced-strength ones - for (std::list<Modulo_Interval>::iterator i = modulo_intervals.begin(); i != modulo_intervals.end(); i++) { - std::vector<Relation *> candidates; - int num_replaced = 0; - for (std::list<Interval>::iterator j = intervals.begin(); j != intervals.end(); j++) - if (int_mod((*j).modulo, (*i).modulo) == 0 && - (*j).ub - (*j).lb >= (*i).size && - (int_mod((*j).lb, (*i).modulo) == (*i).start || - int_mod((*j).ub, (*i).modulo) == (*i).start + (*i).size)) { - candidates.push_back(&((*(*j).pos).first)); - if (int_mod((*j).lb, (*i).modulo) == (*i).start && - (*j).ub - (*j).lb == (*i).size) - num_replaced++; - } - if (num_replaced <= 1) - continue; - - Relation R = copy(*candidates[0]); - for (size_t k = 1; k < candidates.size(); k++) - R = Union(R, copy(*candidates[k])); - Relation hull = ConvexHull(copy(R)); - Relation remainder = Difference(copy(hull), copy(R)); - if (!remainder.is_upper_bound_satisfiable()) { - std::list<Interval>::iterator replaced_one = intervals.end(); - for (std::list<Interval>::iterator j = intervals.begin(); j != intervals.end();) - if (int_mod((*j).modulo, (*i).modulo) == 0 && - (*j).ub - (*j).lb >= (*i).size && - (int_mod((*j).lb, (*i).modulo) == (*i).start || - int_mod((*j).ub, (*i).modulo) == (*i).start + (*i).size)) { - if (int_mod((*j).lb, (*i).modulo) == (*i).start && - (*j).ub - (*j).lb == (*i).size) { - if (replaced_one == intervals.end()) { - (*(*j).pos).first = hull; - (*j).lb = int_mod((*j).lb, (*i).modulo); - (*j).ub = int_mod((*j).ub, (*i).modulo); - (*j).modulo = (*i).modulo; - (*j).change = true; - replaced_one = j; - j++; - } - else { - if ((*j).pos == orig) { - std::swap((*replaced_one).pos, (*j).pos); - (*(*replaced_one).pos).first = (*(*j).pos).first; - } - Rs.erase((*j).pos); - j = intervals.erase(j); - } - } - else { - if (int_mod((*j).lb, (*i).modulo) == (*i).start) - (*j).lb = (*j).lb + (*i).size + 1; - else - (*j).ub = (*j).ub - (*i).size - 1; - (*j).change = true; - j++; - } - } - else - j++; - } - } -} -} // namespace - - -// -// Simplify a union of sets/relations to a minimal (may not be -// optimal) number of convex regions. It intends to replace -// CheckForConvexRepresentation and CheckForConvexPairs functions. -// -Relation ConvexRepresentation(NOT_CONST Relation &R) { - Relation l_R = copy(R); - if (!l_R.is_upper_bound_satisfiable() || l_R.number_of_conjuncts() < 2) - return R; - - // separate each conjunct into smooth convex region and holes - std::list<std::pair<Relation, Relation> > Rs; // pair(smooth region, hole condition) - for (DNF_Iterator c(l_R.query_DNF()); c.live(); c++) { - Relation r1 = Relation(l_R, c.curr()); - Relation r2 = Approximate(copy(r1)); - r1 = Gist(r1, copy(r2)); - Rs.push_back(std::make_pair(r2, r1)); - } - - try { - bool change = true; - while (change) { - change = false; - - std::list<std::pair<Relation, Relation> >::iterator i = Rs.begin(); - while (i != Rs.end()) { - // find regions with identical hole conditions to merge - { - std::list<std::pair<Relation, Relation> >::iterator j = i; - j++; - while (j != Rs.end()) { - if (!Difference(copy((*i).second), copy((*j).second)).is_upper_bound_satisfiable() && - !Difference(copy((*j).second), copy((*i).second)).is_upper_bound_satisfiable()) { - if (Must_Be_Subset(copy((*j).first), copy((*i).first))) { - j = Rs.erase(j); - } - else if (Must_Be_Subset(copy((*i).first), copy((*j).first))) { - (*i).first = (*j).first; - j = Rs.erase(j); - change = true; - } - else { - Relation r; - bool already_use_recthull = false; - try { - r = ConvexHull(Union(copy((*i).first), copy((*j).first))); - } - catch (const std::overflow_error &e) { - r = SimpleHull(Union(copy((*i).first), copy((*j).first))); - already_use_recthull = true; - } - retry_recthull: - Relation r2 = Difference(Difference(copy(r), copy((*i).first)), copy((*j).first)); - if (!r2.is_upper_bound_satisfiable()) { // convex hull is tight - (*i).first = r; - j = Rs.erase(j); - change = true; - } - else { - if (!already_use_recthull) { - r = SimpleHull(Union(copy((*i).first), copy((*j).first))); - already_use_recthull = true; - goto retry_recthull; - } - else - j++; - } - } - } - else - j++; - } - } - - // find identical smooth regions as candidates for hole merge - std::list<std::list<std::pair<Relation, Relation> >::iterator> s; - for (std::list<std::pair<Relation, Relation> >::iterator j = Rs.begin(); j != Rs.end(); j++) - if (j != i) { - if (!Intersection(Difference(copy((*i).first), copy((*j).first)), copy((*j).second)).is_upper_bound_satisfiable() && - !Intersection(Difference(copy((*j).first), copy((*i).first)), copy((*i).second)).is_upper_bound_satisfiable()) - s.push_back(j); - } - - if (s.size() != 0) { - // convert hole condition c1*x1+c2*x2+... = c*alpha+d to a pair of inequalities - (*i).second = EQs_to_GEQs((*i).second, false); - - // find potential wildcards that can be used for hole conditions - std::set<Variable_ID> nonsingle_wild; - for (EQ_Iterator ei((*i).second.single_conjunct()); ei; ei++) - if ((*ei).has_wildcards()) - for (Constr_Vars_Iter cvi(*ei, true); cvi; cvi++) - nonsingle_wild.insert(cvi.curr_var()); - for (GEQ_Iterator gei((*i).second.single_conjunct()); gei; gei++) - if ((*gei).has_wildcards()) { - Constr_Vars_Iter cvi(*gei, true); - Constr_Vars_Iter cvi2 = cvi; - cvi2++; - if (cvi2) { - nonsingle_wild.insert(cvi.curr_var()); - for (; cvi2; cvi2++) - nonsingle_wild.insert(cvi2.curr_var()); - } - } - - // find hole condition in c*alpha+d1<=c1*x1+c2*x2+...<=c*alpha+d2 format - for (GEQ_Iterator gei((*i).second.single_conjunct()); gei; gei++) - if ((*gei).has_wildcards()) { - coef_t c; - Variable_ID v; - { - Constr_Vars_Iter cvi(*gei, true); - v = cvi.curr_var(); - c = cvi.curr_coef(); - if (c < 0 || nonsingle_wild.find(v) != nonsingle_wild.end()) - continue; - } - - coef_t lb = posInfinity; - for (GEQ_Iterator gei2((*i).second.single_conjunct()); gei2; gei2++) { - if (!(*gei2 == *gei) && (*gei2).get_coef(v) != 0) { - if (lb != posInfinity) { - nonsingle_wild.insert(v); - break; - } - - bool match = true; - for (Constr_Vars_Iter cvi2(*gei); cvi2; cvi2++) - if (cvi2.curr_coef() != -((*gei2).get_coef(cvi2.curr_var()))) { - match = false; - break; - } - if (match) - for (Constr_Vars_Iter cvi2(*gei2); cvi2; cvi2++) - if (cvi2.curr_coef() != -((*gei).get_coef(cvi2.curr_var()))) { - match = false; - break; - } - if (!match) { - nonsingle_wild.insert(v); - break; - } - - lb = -(*gei2).get_const(); - } - } - - if (nonsingle_wild.find(v) != nonsingle_wild.end()) - continue; - - Relation stride_cond = Relation::True((*i).second); - F_Exists *f_exists = stride_cond.and_with_and()->add_exists(); - Variable_ID e = f_exists->declare(); - F_And *f_root = f_exists->add_and(); - GEQ_Handle h1 = f_root->add_GEQ(); - GEQ_Handle h2 = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi2(*gei); cvi2; cvi2++) { - Variable_ID v = cvi2.curr_var(); - switch (v->kind()) { - case Wildcard_Var: - h1.update_coef(e, cvi2.curr_coef()); - h2.update_coef(e, -cvi2.curr_coef()); - break; - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = stride_cond.get_local(g); - else - v2 = stride_cond.get_local(g, v->function_of()); - h1.update_coef(v2, cvi2.curr_coef()); - h2.update_coef(v2, -cvi2.curr_coef()); - break; - } - default: - h1.update_coef(v, cvi2.curr_coef()); - h2.update_coef(v, -cvi2.curr_coef()); - } - } - h1.update_const((*gei).get_const()); - h2.update_const(-lb); - - stride_cond.simplify(); - Relation other_cond = Gist(copy((*i).second), copy(stride_cond)); - - // find regions with potential mergeable stride condition with this one - std::list<Interval> intervals; - intervals.push_back(Interval(i, lb, (*gei).get_const())); - - for (std::list<std::list<std::pair<Relation, Relation> >::iterator>::iterator j = s.begin(); j != s.end(); j++) - if (Must_Be_Subset(copy((**j).second), copy(other_cond))) { - Relation stride_cond2 = Gist(copy((**j).second), copy(other_cond)); - - // interval can be removed - if (stride_cond2.is_obvious_tautology()) { - intervals.push_back(Interval(*j, 0, c-1)); - continue; - } - - stride_cond2 = EQs_to_GEQs(stride_cond2, false); - coef_t lb, ub; - GEQ_Iterator gei2(stride_cond2.single_conjunct()); - coef_t sign = 0; - for (Constr_Vars_Iter cvi(*gei2, true); cvi; cvi++) - if (sign != 0) { - sign = 0; - break; - } - else if (cvi.curr_coef() == c) - sign = 1; - else if (cvi.curr_coef() == -c) - sign = -1; - else { - sign = 0; - break; - } - if (sign == 0) - continue; - - bool match = true; - for (Constr_Vars_Iter cvi(*gei2); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - if (v->kind() == Wildcard_Var) - continue; - else if (v->kind() == Global_Var) { - Global_Var_ID g = v->get_global_var(); - if (g->arity() == 0) - v = (*i).second.get_local(g); - else - v = (*i).second.get_local(g, v->function_of()); - } - - if (cvi.curr_coef() != sign * (*gei).get_coef(v)) { - match = false; - break; - } - } - if (!match) - continue; - - for (Constr_Vars_Iter cvi(*gei); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - if (v->kind() == Wildcard_Var) - continue; - else if (v->kind() == Global_Var) { - Global_Var_ID g = v->get_global_var(); - if (g->arity() == 0) - v = stride_cond2.get_local(g); - else - v = stride_cond2.get_local(g, v->function_of()); - } - - if (cvi.curr_coef() != sign * (*gei2).get_coef(v)) { - match = false; - break; - } - } - if (!match) - continue; - if (sign > 0) - ub = (*gei2).get_const(); - else - lb = -(*gei2).get_const(); - - gei2++; - if (!gei2) - continue; - - coef_t sign2 = 0; - for (Constr_Vars_Iter cvi(*gei2, true); cvi; cvi++) - if (sign2 != 0) { - sign2 = 0; - break; - } - else if (cvi.curr_coef() == c) - sign2 = 1; - else if (cvi.curr_coef() == -c) - sign2 = -1; - else { - sign2 = 0; - break; - } - if (sign2 != -sign) - continue; - - for (Constr_Vars_Iter cvi(*gei2); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - if (v->kind() == Wildcard_Var) - continue; - else if (v->kind() == Global_Var) { - Global_Var_ID g = v->get_global_var(); - if (g->arity() == 0) - v = (*i).second.get_local(g); - else - v = (*i).second.get_local(g, v->function_of()); - } - - if (cvi.curr_coef() != sign2 * (*gei).get_coef(v)) { - match = false; - break; - } - } - if (!match) - continue; - - for (Constr_Vars_Iter cvi(*gei); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - if (v->kind() == Wildcard_Var) - continue; - else if (v->kind() == Global_Var) { - Global_Var_ID g = v->get_global_var(); - if (g->arity() == 0) - v = stride_cond2.get_local(g); - else - v = stride_cond2.get_local(g, v->function_of()); - } - - if (cvi.curr_coef() != sign2 * (*gei2).get_coef(v)) { - match = false; - break; - } - } - if (!match) - continue; - if (sign2 > 0) - ub = (*gei2).get_const(); - else - lb = -(*gei2).get_const(); - - gei2++; - if (gei2) - continue; - - intervals.push_back(Interval(*j, lb, ub)); - } - - merge_intervals(intervals, c, Rs, i); - - // make current region the last one being updated - bool invalid = false; - for (std::list<Interval>::iterator ii = intervals.begin(); ii != intervals.end(); ii++) - if ((*ii).change && (*ii).pos == i) { - invalid = true; - intervals.push_back(*ii); - intervals.erase(ii); - break; - } - - // update hole condition for each region - for (std::list<Interval>::iterator ii = intervals.begin(); ii != intervals.end(); ii++) - if ((*ii).change) { - change = true; - - if ((*ii).ub - (*ii).lb + 1 >= (*ii).modulo) - (*(*ii).pos).second = copy(other_cond); - else { - Relation stride_cond = Relation::True((*i).second); - F_Exists *f_exists = stride_cond.and_with_and()->add_exists(); - Variable_ID e = f_exists->declare(); - F_And *f_root = f_exists->add_and(); - GEQ_Handle h1 = f_root->add_GEQ(); - GEQ_Handle h2 = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi2(*gei); cvi2; cvi2++) { - Variable_ID v = cvi2.curr_var(); - switch (v->kind()) { - case Wildcard_Var: - h1.update_coef(e, (*ii).modulo); - h2.update_coef(e, -(*ii).modulo); - break; - case Global_Var: { - Global_Var_ID g = v->get_global_var(); - Variable_ID v2; - if (g->arity() == 0) - v2 = stride_cond.get_local(g); - else - v2 = stride_cond.get_local(g, v->function_of()); - h1.update_coef(v2, cvi2.curr_coef()); - h2.update_coef(v2, -cvi2.curr_coef()); - break; - } - default: - h1.update_coef(v, cvi2.curr_coef()); - h2.update_coef(v, -cvi2.curr_coef()); - } - } - h1.update_const((*ii).ub); - h2.update_const(-(*ii).lb); - - (*(*ii).pos).second = Intersection(copy(other_cond), stride_cond); - (*(*ii).pos).second.simplify(); - } - } - - if (invalid) - break; - } - } - i++; - } - } - } - catch (const presburger_error &e) { - throw e; - } - - Relation R2 = Relation::False(l_R); - for (std::list<std::pair<Relation, Relation> >::iterator i = Rs.begin(); i != Rs.end(); i++) - R2 = Union(R2, Intersection((*i).first, (*i).second)); - R2.simplify(0, 1); - - return R2; -} - -// -// Use gist and value range to calculate a quick rectangular hull. It -// intends to replace all hull calculations (QuickHull, BetterHull, -// FastTightHull) beyond the method of ConvexHull (dual -// representations). In the future, it will support max(...)-like -// upper bound. So RectHull complements ConvexHull in two ways: first -// for relations that ConvexHull gets too complicated, second for -// relations where different conjuncts have different symbolic upper -// bounds. -// -Relation RectHull(NOT_CONST Relation &Rel) { - Relation R = Approximate(consume_and_regurgitate(Rel)); - if (!R.is_upper_bound_satisfiable()) - return R; - if (R.has_single_conjunct()) - return R; - - std::vector<std::string> input_names(R.n_inp()); - for (int i = 1; i <= R.n_inp(); i++) - input_names[i-1] = R.input_var(i)->name(); - std::vector<std::string> output_names(R.n_out()); - for (int i = 1; i <= R.n_out(); i++) - output_names[i-1] = R.output_var(i)->name(); - - DNF_Iterator c(R.query_DNF()); - Relation r = Relation(R, c.curr()); - c++; - std::vector<std::pair<coef_t, coef_t> > bounds1(R.n_inp()); - std::vector<std::pair<coef_t, coef_t> > bounds2(R.n_out()); - { - Relation t = Project_Sym(copy(r)); - t.simplify(); - for (int i = 1; i <= R.n_inp(); i++) { - Tuple<Variable_ID> v; - for (int j = 1; j <= R.n_inp(); j++) - if (j != i) - v.append(r.input_var(j)); - for (int j = 1; j <= R.n_out(); j++) - v.append(r.output_var(j)); - Relation t2 = Project(copy(t), v); - t2.query_variable_bounds(t2.input_var(i), bounds1[i-1].first, bounds1[i-1].second); - } - for (int i = 1; i <= R.n_out(); i++) { - Tuple<Variable_ID> v; - for (int j = 1; j <= R.n_out(); j++) - if (j != i) - v.append(r.output_var(j)); - for (int j = 1; j <= R.n_inp(); j++) - v.append(r.input_var(j)); - Relation t2 = Project(copy(t), v); - t2.query_variable_bounds(t2.output_var(i), bounds2[i-1].first, bounds2[i-1].second); - } - } - - while (c.live()) { - Relation r2 = Relation(R, c.curr()); - c++; - Relation x = Gist(copy(r), Gist(copy(r), copy(r2), 1), 1); - if (Difference(copy(r2), copy(x)).is_upper_bound_satisfiable()) - x = Relation::True(R); - Relation y = Gist(copy(r2), Gist(copy(r2), copy(r), 1), 1); - if (Difference(copy(r), copy(y)).is_upper_bound_satisfiable()) - y = Relation::True(R); - r = Intersection(x, y); - - { - Relation t = Project_Sym(copy(r2)); - t.simplify(); - for (int i = 1; i <= R.n_inp(); i++) { - Tuple<Variable_ID> v; - for (int j = 1; j <= R.n_inp(); j++) - if (j != i) - v.append(r2.input_var(j)); - for (int j = 1; j <= R.n_out(); j++) - v.append(r2.output_var(j)); - Relation t2 = Project(copy(t), v); - coef_t lbound, ubound; - t2.query_variable_bounds(t2.input_var(i), lbound, ubound); - bounds1[i-1].first = min(bounds1[i-1].first, lbound); - bounds1[i-1].second = max(bounds1[i-1].second, ubound); - } - for (int i = 1; i <= R.n_out(); i++) { - Tuple<Variable_ID> v; - for (int j = 1; j <= R.n_out(); j++) - if (j != i) - v.append(r2.output_var(j)); - for (int j = 1; j <= R.n_inp(); j++) - v.append(r2.input_var(j)); - Relation t2 = Project(copy(t), v); - coef_t lbound, ubound; - t2.query_variable_bounds(t2.output_var(i), lbound, ubound); - bounds2[i-1].first = min(bounds2[i-1].first, lbound); - bounds2[i-1].second = max(bounds2[i-1].second, ubound); - } - } - - Relation r3(R.n_inp(), R.n_out()); - F_And *f_root = r3.add_and(); - for (int i = 1; i <= R.n_inp(); i++) { - if (bounds1[i-1].first != -posInfinity) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(r3.input_var(i), 1); - h.update_const(-bounds1[i-1].first); - } - if (bounds1[i-1].second != posInfinity) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(r3.input_var(i), -1); - h.update_const(bounds1[i-1].second); - } - } - for (int i = 1; i <= R.n_out(); i++) { - if (bounds2[i-1].first != -posInfinity) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(r3.output_var(i), 1); - h.update_const(-bounds2[i-1].first); - } - if (bounds2[i-1].second != posInfinity) { - GEQ_Handle h = f_root->add_GEQ(); - h.update_coef(r3.output_var(i), -1); - h.update_const(bounds2[i-1].second); - } - } - r = Intersection(r, r3); - r.simplify(); - } - - for (int i = 1; i <= r.n_inp(); i++) - r.name_input_var(i, input_names[i-1]); - for (int i = 1; i <= r.n_out(); i++) - r.name_output_var(i, output_names[i-1]); - r.setup_names(); - return r; -} - -} - diff --git a/omegalib/omega/src/hull_simple.cc b/omegalib/omega/src/hull_simple.cc deleted file mode 100755 index 62dcb26..0000000 --- a/omegalib/omega/src/hull_simple.cc +++ /dev/null @@ -1,1013 +0,0 @@ -/***************************************************************************** - Copyright (C) 2011 Chun Chen - All Rights Reserved. - - Purpose: - Hull approximation including lattice and irregular constraints that - involves wildcards. - - Notes: - - History: - 03/12/11 Created by Chun Chen - *****************************************************************************/ - -#include <assert.h> -#include <omega.h> -#include <basic/BoolSet.h> -#include <vector> -#include <list> -#include <set> -#include <string> -#include <algorithm> - -namespace omega { - -Relation SimpleHull(const Relation &R, bool allow_stride_constraint, - bool allow_irregular_constraint) { - std::vector<Relation> Rs; - Rs.push_back(R); - return SimpleHull(Rs, allow_stride_constraint, allow_irregular_constraint); -} - -Relation SimpleHull(const std::vector<Relation> &Rs, - bool allow_stride_constraint, bool allow_irregular_constraint) { - // check for sanity of parameters - if (Rs.size() == 0) - return Relation::False(0); - int num_dim = -1; - int first_non_null; - for (int i = 0; i < Rs.size(); i++) { - if (Rs[i].is_null()) - continue; - - if (num_dim == -1) { - num_dim = Rs[i].n_inp(); - first_non_null = i; - } - - if (Rs[i].n_inp() != num_dim) - throw std::invalid_argument( - "relations for hull must have same dimension"); - if (Rs[i].n_out() != 0) - throw std::invalid_argument( - "hull calculation must be set relation"); - } - - // convert to a list of relations each with a single conjunct - std::vector<Relation> l_Rs; - for (int i = 0; i < Rs.size(); i++) { - if (Rs[i].is_null()) - continue; - - Relation r = copy(Rs[i]); - - //r.simplify(2, 4); - r.simplify(); - DNF_Iterator c(r.query_DNF()); - int top = l_Rs.size(); - while (c.live()) { - Relation r2 = Relation(r, c.curr()); - - // quick elimination of redundant conjuncts - bool already_included = false; - for (int j = 0; j < top; j++) - if (Must_Be_Subset(copy(r2), copy(l_Rs[j]))) { - already_included = true; - break; - } else if (Must_Be_Subset(copy(l_Rs[j]), copy(r2))) { - l_Rs.erase(l_Rs.begin() + j); - top--; - break; - } - - if (!already_included) - l_Rs.push_back(r2); - c++; - } - } - - // shortcut for simple case - if (l_Rs.size() == 0) { - if (num_dim == -1) - return Relation::False(0); - else { - Relation r = Relation::False(num_dim); - r.copy_names(Rs[first_non_null]); - r.setup_names(); - return r; - } - } else if (l_Rs.size() == 1) { - if (allow_stride_constraint && allow_irregular_constraint) { - l_Rs[0].copy_names(Rs[first_non_null]); - l_Rs[0].setup_names(); - return l_Rs[0]; - } else if (!allow_stride_constraint && !allow_irregular_constraint) { - l_Rs[0] = Approximate(l_Rs[0]); - l_Rs[0].copy_names(Rs[first_non_null]); - l_Rs[0].setup_names(); - return l_Rs[0]; - } - } - - Relation hull = Relation::True(num_dim); - - // lattice union approximation - if (allow_stride_constraint) { - std::vector<std::vector<std::pair<EQ_Handle, BoolSet<> > > > strides( - l_Rs.size()); - for (int i = 0; i < l_Rs.size(); i++) - for (EQ_Iterator e = l_Rs[i].single_conjunct()->EQs(); e; e++) - if ((*e).has_wildcards()) { - int num_wildcard = 0; - BoolSet<> affected(num_dim); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - if (cvi.curr_var()->kind() == Wildcard_Var) - num_wildcard++; - else if (cvi.curr_var()->kind() == Input_Var) - affected.set(cvi.curr_var()->get_position() - 1); - } - if (num_wildcard == 1) - strides[i].push_back(std::make_pair(*e, affected)); - } - - for (int i = 0; i < strides[0].size(); i++) { - coef_t c = - abs( - strides[0][i].first.get_coef( - Constr_Vars_Iter(strides[0][i].first, true).curr_var())); - coef_t old_c = c; - bool is_stride = true; - for (int j = 1; j < l_Rs.size(); j++) { - std::list<coef_t> candidates; - for (int k = 0; k < strides[j].size(); k++) - if (!(strides[0][i].second & strides[j][k].second).empty()) { - coef_t t = gcd(c, - abs( - strides[j][k].first.get_coef( - Constr_Vars_Iter( - strides[j][k].first, - true).curr_var()))); - if (t != 1) { - std::list<coef_t>::iterator p = candidates.begin(); - while (p != candidates.end() && *p > t) - ++p; - if (p == candidates.end() || *p != t) - candidates.insert(p, t); - - t = gcd(t, abs(strides[0][i].first.get_const())); - t = gcd(t, abs(strides[j][k].first.get_const())); - if (t != 1) { - std::list<coef_t>::iterator p = - candidates.begin(); - while (p != candidates.end() && *p > t) - ++p; - if (p == candidates.end() || *p != t) - candidates.insert(p, t); - } - } - } - - bool found_matched_stride = false; - for (std::list<coef_t>::iterator k = candidates.begin(); - k != candidates.end(); k++) { - Relation r = Relation::True(num_dim); - EQ_Handle h = r.and_with_EQ(strides[0][i].first); - h.update_coef(Constr_Vars_Iter(h, true).curr_var(), - -old_c + *k); - r.simplify(); - if (Must_Be_Subset(copy(l_Rs[j]), copy(r))) { - c = *k; - found_matched_stride = true; - break; - } - } - - if (!found_matched_stride) { - is_stride = false; - break; - } - } - - if (is_stride) { - Relation r = Relation::True(num_dim); - EQ_Handle h = r.and_with_EQ(strides[0][i].first); - h.update_coef(Constr_Vars_Iter(h, true).curr_var(), -old_c + c); - r.simplify(); - hull = Intersection(hull, r); - } - } - } - - // consider some special wildcard constraints - if (allow_irregular_constraint) { - std::vector< - std::vector< - std::pair<Variable_ID, std::map<Variable_ID, coef_t> > > > ranges( - l_Rs.size()); - for (int i = 0; i < l_Rs.size(); i++) { - std::vector<std::pair<GEQ_Handle, std::map<Variable_ID, coef_t> > > geqs_ub; - std::vector<std::pair<GEQ_Handle, std::map<Variable_ID, coef_t> > > geqs_lb; - for (GEQ_Iterator e = l_Rs[i].single_conjunct()->GEQs(); e; e++) - if ((*e).has_wildcards()) { - int num_wildcard = 0; - std::map<Variable_ID, coef_t> formula; - int direction; - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) { - Variable_ID v = cvi.curr_var(); - switch (v->kind()) { - case Wildcard_Var: - num_wildcard++; - if (cvi.curr_coef() > 0) - direction = true; - else - direction = false; - break; - case Input_Var: - case Global_Var: - formula[cvi.curr_var()] = cvi.curr_coef(); - break; - default: - assert(false); - } - } - if (num_wildcard == 1) { - if (direction) { - for (std::map<Variable_ID, coef_t>::iterator j = - formula.begin(); j != formula.end(); j++) - j->second = -j->second; - geqs_ub.push_back(std::make_pair(*e, formula)); - } else - geqs_lb.push_back(std::make_pair(*e, formula)); - } - } - for (int j = 0; j < geqs_lb.size(); j++) { - Variable_ID v = - Constr_Vars_Iter(geqs_lb[j].first, true).curr_var(); - for (int k = 0; k < geqs_ub.size(); k++) - if (v == Constr_Vars_Iter(geqs_ub[k].first, true).curr_var() - && geqs_lb[j].second == geqs_ub[k].second) - ranges[i].push_back( - std::make_pair(v, geqs_lb[j].second)); - } - } - - // find compatible wildcard match - // TODO: evaluate to find the best match, also avoid mapping two wildcards - // in a single conjunct to one variable (incorrect) - std::vector<std::vector<int> > all_match; - for (int i = 0; i < ranges[0].size(); i++) { - std::vector<int> match(l_Rs.size(), -1); - match[0] = i; - for (int j = 1; j < l_Rs.size(); j++) { - for (int k = 0; k < ranges[j].size(); k++) - if (ranges[0][i].second == ranges[j][k].second) { - match[j] = k; - break; - } - if (match[j] == -1) - break; - } - if (match[l_Rs.size() - 1] != -1) - all_match.push_back(match); - } - - // map compatible wildcards to input variables - std::vector<Relation> ll_Rs(l_Rs.size()); - for (int i = 0; i < l_Rs.size(); i++) { - Relation r(num_dim + all_match.size()); - F_Exists *f_exists = r.add_and()->add_exists(); - F_And *f_root = f_exists->add_and(); - std::map<Variable_ID, Variable_ID> wc_map; - for (int j = 0; j < all_match.size(); j++) - wc_map[ranges[i][all_match[j][i]].first] = r.set_var(j + 1); - - for (EQ_Iterator e(l_Rs[i].single_conjunct()->EQs()); e; e++) - if (!(*e).has_wildcards()) { - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - h.update_coef( - r.set_var( - cvi.curr_var()->get_position() - + all_match.size()), - cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = cvi.curr_var()->get_global_var(); - Variable_ID v; - if (g->arity() == 0) - v = r.get_local(g); - else - v = r.get_local(g, - cvi.curr_var()->function_of()); - h.update_coef(v, cvi.curr_coef()); - break; - } - default: - assert(false); - } - h.update_const((*e).get_const()); - } - - for (GEQ_Iterator e(l_Rs[i].single_conjunct()->GEQs()); e; e++) { - GEQ_Handle h = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - h.update_coef( - r.set_var( - cvi.curr_var()->get_position() - + all_match.size()), - cvi.curr_coef()); - break; - } - case Global_Var: { - Global_Var_ID g = cvi.curr_var()->get_global_var(); - Variable_ID v; - if (g->arity() == 0) - v = r.get_local(g); - else - v = r.get_local(g, cvi.curr_var()->function_of()); - h.update_coef(v, cvi.curr_coef()); - break; - } - case Wildcard_Var: { - std::map<Variable_ID, Variable_ID>::iterator p = - wc_map.find(cvi.curr_var()); - Variable_ID v; - if (p == wc_map.end()) { - v = f_exists->declare(); - wc_map[cvi.curr_var()] = v; - } else - v = p->second; - h.update_coef(v, cvi.curr_coef()); - break; - } - default: - assert(false); - } - h.update_const((*e).get_const()); - } - - r.simplify(); - ll_Rs[i] = r; - } - - // now use SimpleHull on regular bounds only - Relation result = SimpleHull(ll_Rs, false, false); - - // convert imaginary input variables back to wildcards - Relation mapping(num_dim + all_match.size(), num_dim); - F_And *f_root = mapping.add_and(); - for (int i = 0; i < num_dim; i++) { - EQ_Handle h = f_root->add_EQ(); - h.update_coef(mapping.input_var(all_match.size() + i + 1), 1); - h.update_coef(mapping.output_var(i + 1), -1); - } - result = Range(Restrict_Domain(mapping, result)); - - hull = Intersection(hull, result); - hull.simplify(); - hull.copy_names(Rs[first_non_null]); - hull.setup_names(); - return hull; - } - - // check regular bounds - if (l_Rs.size() == 1) { - hull = Intersection(hull, Approximate(copy(l_Rs[0]))); - } else { - for (int i = 0; i < l_Rs.size(); i++) { - l_Rs[i] = Approximate(l_Rs[i]); - l_Rs[i].simplify(2, 4); - } - - // check global variables - // TODO: global variable function_of() is not considered for now - std::map<Global_Var_ID, int> globals; - for (int i = 0; i < l_Rs.size(); i++) - for (Constraint_Iterator e( - l_Rs[i].single_conjunct()->constraints()); e; e++) - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if (cvi.curr_var()->kind() == Global_Var) - globals[cvi.curr_var()->get_global_var()] = -1; - - if (globals.size() > 0) { - int count = 1; - for (std::map<Global_Var_ID, int>::iterator i = globals.begin(); - i != globals.end(); i++) - i->second = count++; - - std::vector<Relation> ll_Rs(l_Rs.size()); - for (int i = 0; i < l_Rs.size(); i++) { - Relation r(num_dim + globals.size()); - F_And *f_root = r.add_and(); - for (EQ_Iterator e(l_Rs[i].single_conjunct()->EQs()); e; e++) { - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - h.update_coef( - r.set_var( - cvi.curr_var()->get_position() - + globals.size()), - cvi.curr_coef()); - break; - } - case Global_Var: { - h.update_coef( - r.set_var( - globals[cvi.curr_var()->get_global_var()]), - cvi.curr_coef()); - break; - } - default: - assert(false); - } - h.update_const((*e).get_const()); - } - for (GEQ_Iterator e(l_Rs[i].single_conjunct()->GEQs()); e; - e++) { - GEQ_Handle h = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - h.update_coef( - r.set_var( - cvi.curr_var()->get_position() - + globals.size()), - cvi.curr_coef()); - break; - } - case Global_Var: { - h.update_coef( - r.set_var( - globals[cvi.curr_var()->get_global_var()]), - cvi.curr_coef()); - break; - } - default: - assert(false); - } - h.update_const((*e).get_const()); - } - - ll_Rs[i] = r; - } - - Relation result = SimpleHull(ll_Rs, false, false); - - std::map<int, Global_Var_ID> globals_reverse; - for (std::map<Global_Var_ID, int>::iterator i = globals.begin(); - i != globals.end(); i++) - globals_reverse[i->second] = i->first; - - Relation r(num_dim); - F_And *f_root = r.add_and(); - for (EQ_Iterator e(result.single_conjunct()->EQs()); e; e++) { - EQ_Handle h = f_root->add_EQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - int pos = cvi.curr_var()->get_position(); - if (pos > globals_reverse.size()) - h.update_coef( - r.set_var(pos - globals_reverse.size()), - cvi.curr_coef()); - else { - Global_Var_ID g = globals_reverse[pos]; - h.update_coef(r.get_local(g), cvi.curr_coef()); - } - break; - } - default: - assert(false); - } - h.update_const((*e).get_const()); - } - for (GEQ_Iterator e(result.single_conjunct()->GEQs()); e; e++) { - GEQ_Handle h = f_root->add_GEQ(); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - switch (cvi.curr_var()->kind()) { - case Input_Var: { - int pos = cvi.curr_var()->get_position(); - if (pos > globals_reverse.size()) - h.update_coef( - r.set_var(pos - globals_reverse.size()), - cvi.curr_coef()); - else { - Global_Var_ID g = globals_reverse[pos]; - h.update_coef(r.get_local(g), cvi.curr_coef()); - } - break; - } - default: - assert(false); - } - h.update_const((*e).get_const()); - } - - hull = Intersection(hull, r); - hull.simplify(); - hull.copy_names(Rs[first_non_null]); - hull.setup_names(); - return hull; - } else { - std::vector<std::vector<Relation> > projected(num_dim + 1, - std::vector<Relation>(l_Rs.size())); - for (int i = 0; i < l_Rs.size(); i++) { - projected[num_dim][i] = copy(l_Rs[i]); - for (int j = num_dim - 1; j >= 0; j--) { - projected[j][i] = Project(copy(projected[j + 1][i]), - projected[j + 1][i].input_var(j + 1)); - projected[j][i].simplify(2, 4); - } - } - - std::vector<bool> has_lb(num_dim, false); - std::vector<bool> has_ub(num_dim, false); - for (int i = 0; i < num_dim; i++) { - bool skip_lb = false; - bool skip_ub = false; - std::vector<Relation> bound(l_Rs.size()); - for (int j = 0; j < l_Rs.size(); j++) { - bound[j] = Gist(copy(projected[i + 1][j]), - copy(projected[i][j]), 1); - bound[j] = Approximate(bound[j]); - bound[j] = EQs_to_GEQs(bound[j]); - - bool has_lb_not_in_hull = false; - bool has_ub_not_in_hull = false; - for (GEQ_Iterator e = bound[j].single_conjunct()->GEQs(); e; - e++) { - coef_t coef = (*e).get_coef(bound[j].input_var(i + 1)); - if (!skip_lb && coef > 0) { - Relation r = Relation::True(bound[j].n_inp()); - r.and_with_GEQ(*e); - r.simplify(); - - if (j != 0 && l_Rs.size() > 2 - && Must_Be_Subset(copy(hull), copy(r))) - continue; - - bool belong_to_hull = true; - for (int k = 0; k < l_Rs.size(); k++) - if (k != j - && !Must_Be_Subset(copy(l_Rs[k]), - copy(r))) { - belong_to_hull = false; - break; - } - if (belong_to_hull) { - hull.and_with_GEQ(*e); - has_lb[i] = true; - } else - has_lb_not_in_hull = true; - } else if (!skip_ub && coef < 0) { - Relation r = Relation::True(bound[j].n_inp()); - r.and_with_GEQ(*e); - r.simplify(); - - if (j != 0 && l_Rs.size() > 2 - && Must_Be_Subset(copy(hull), copy(r))) - continue; - - bool belong_to_hull = true; - for (int k = 0; k < l_Rs.size(); k++) - if (k != j - && !Must_Be_Subset(copy(l_Rs[k]), - copy(r))) { - belong_to_hull = false; - break; - } - if (belong_to_hull) { - hull.and_with_GEQ(*e); - has_ub[i] = true; - } else - has_ub_not_in_hull = true; - } - } - - if (!has_lb_not_in_hull) - skip_lb = true; - if (!has_ub_not_in_hull) - skip_ub = true; - if (skip_lb && skip_ub) - break; - } - - // no ready lower bound, approximate it - bool got_rect_lb = false; - if (!skip_lb) { - for (int j = 0; j < l_Rs.size(); j++) { - std::set<BoolSet<> > S; - for (GEQ_Iterator e = - bound[j].single_conjunct()->GEQs(); e; e++) { - coef_t coef = (*e).get_coef( - bound[j].input_var(i + 1)); - if (coef > 0) { - BoolSet<> s(i); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if ((*cvi).var->kind() == Input_Var - && (*cvi).var->get_position() - 1 - != i) { - if (((*cvi).coef > 0 - && has_ub[(*cvi).var->get_position() - - 1]) - || ((*cvi).coef < 0 - && has_lb[(*cvi).var->get_position() - - 1])) - s.set( - (*cvi).var->get_position() - - 1); - else { - for (GEQ_Iterator e2 = - bound[j].single_conjunct()->GEQs(); - e2; e2++) - if (e2 != e - && (((*cvi).coef > 0 - && (*e2).get_coef( - (*cvi).var) - < 0) - || ((*cvi).coef - < 0 - && (*e2).get_coef( - (*cvi).var) - > 0))) { - s.set( - (*cvi).var->get_position() - - 1); - break; - } - } - } - - if (s.num_elem() > 0) - S.insert(s); - } - } - - if (S.size() > 0) { - BoolSet<> s(i); - for (std::set<BoolSet<> >::iterator k = S.begin(); - k != S.end(); k++) - s |= *k; - for (int k = 0; k < i; k++) - if (s.get(k)) { - BoolSet<> t(i); - t.set(k); - S.insert(t); - } - - for (std::set<BoolSet<> >::iterator k = S.begin(); - k != S.end(); k++) { - - bool do_again = false; - std::set<int> vars; - int round_trip = 0; - do { - Relation r = copy(projected[i + 1][j]); - - if (!do_again) { - for (int kk = 0; kk < i; kk++) - if ((*k).get(kk)) { - r = Project(r, - r.input_var(kk + 1)); - vars.insert(kk + 1); - } - } else { - for (std::set<int>::iterator vars_it = - vars.begin(); - vars_it != vars.end(); - vars_it++) - if (*vars_it < i + 1) - r = Project(r, - r.input_var(*vars_it)); - } - - r.simplify(2, 4); - Relation r2 = Project(copy(r), - r.input_var(i + 1)); - Relation b = Gist(copy(r), copy(r2), 1); - // Relation c = Project(copy(r),r.input_var(4) ); - - // c.simplify(2,4); - // Relation d = Project(copy(c), r.input_var(i+1)); - // Relation e = Gist(copy(c), copy(d), 1); - - b = Approximate(b); - b = EQs_to_GEQs(b); - - for (GEQ_Iterator e = - b.single_conjunct()->GEQs(); e; - e++) { - coef_t coef = (*e).get_coef( - b.input_var(i + 1)); - if (coef > 0) { - Relation r = Relation::True( - b.n_inp()); - r.and_with_GEQ(*e); - r.simplify(); - - if (Must_Be_Subset(copy(hull), - copy(r))) - continue; - - bool belong_to_hull = true; - for (int k = 0; k < l_Rs.size(); - k++) - if (k != j - && !Must_Be_Subset( - copy(l_Rs[k]), - copy(r))) { - belong_to_hull = false; - break; - } - if (belong_to_hull) { - hull.and_with_GEQ(*e); - got_rect_lb = true; - } - } - } - do_again = false; - if (!got_rect_lb) { - bool found = false; - for (GEQ_Iterator e = - b.single_conjunct()->GEQs(); e; - e++) { - coef_t coef = (*e).get_coef( - b.input_var(i + 1)); - - if (coef > 0) { - for (Constr_Vars_Iter cvi(*e); - cvi; cvi++) - if ((*cvi).var->kind() - == Input_Var - && (*cvi).var->get_position() - - 1 != i) { - - if (((*cvi).coef > 0 - && has_ub[(*cvi).var->get_position() - - 1]) - || ((*cvi).coef - < 0 - && has_lb[(*cvi).var->get_position() - - 1])) { - vars.insert( - (*cvi).var->get_position()); - found = true; - } else { - for (GEQ_Iterator e2 = - b.single_conjunct()->GEQs(); - e2; e2++) - if (e2 != e - && (((*cvi).coef - > 0 - && (*e2).get_coef( - (*cvi).var) - < 0) - || ((*cvi).coef - < 0 - && (*e2).get_coef( - (*cvi).var) - > 0))) { - vars.insert( - (*cvi).var->get_position()); - found = - true; - break; - } - } - - } - - } - if (found) - break; - - } - if (found && (round_trip < i)) - do_again = true; - - } - round_trip++; - } while (do_again); - } - - if (got_rect_lb) - break; - } - } - } - - // no ready upper bound, approximate it - bool got_rect_ub = false; - if (!skip_ub) { - for (int j = 0; j < l_Rs.size(); j++) { - std::set<BoolSet<> > S; - for (GEQ_Iterator e = - bound[j].single_conjunct()->GEQs(); e; e++) { - coef_t coef = (*e).get_coef( - bound[j].input_var(i + 1)); - if (coef < 0) { - BoolSet<> s(i); - for (Constr_Vars_Iter cvi(*e); cvi; cvi++) - if ((*cvi).var->kind() == Input_Var - && (*cvi).var->get_position() - 1 - != i) { - if (((*cvi).coef > 0 - && has_ub[(*cvi).var->get_position() - - 1]) - || ((*cvi).coef < 0 - && has_lb[(*cvi).var->get_position() - - 1])) - s.set( - (*cvi).var->get_position() - - 1); - else { - for (GEQ_Iterator e2 = - bound[j].single_conjunct()->GEQs(); - e2; e2++) - if (e2 != e - && (((*cvi).coef > 0 - && (*e2).get_coef( - (*cvi).var) - < 0) - || ((*cvi).coef - < 0 - && (*e2).get_coef( - (*cvi).var) - > 0))) { - s.set( - (*cvi).var->get_position() - - 1); - break; - } - } - } - - if (s.num_elem() > 0) - S.insert(s); - } - } - - if (S.size() > 0) { - BoolSet<> s(i); - for (std::set<BoolSet<> >::iterator k = S.begin(); - k != S.end(); k++) - s |= *k; - for (int k = 0; k < i; k++) - if (s.get(k)) { - BoolSet<> t(i); - t.set(k); - S.insert(t); - } - - for (std::set<BoolSet<> >::iterator k = S.begin(); - k != S.end(); k++) { - - bool do_again = false; - std::set<int> vars; - int round_trip = 0; - do { - - Relation r = copy(projected[i + 1][j]); - - if (!do_again) { - for (int kk = 0; kk < i; kk++) - if ((*k).get(kk)) { - r = Project(r, - r.input_var(kk + 1)); - vars.insert(kk + 1); - } - } else { - for (std::set<int>::iterator vars_it = - vars.begin(); - vars_it != vars.end(); - vars_it++) - if (*vars_it < i + 1) - r = Project(r, - r.input_var(*vars_it)); - } - - r.simplify(2, 4); - Relation r2 = Project(copy(r), - r.input_var(i + 1)); - // r2.simplify(2,4); - Relation b = Gist(r, r2, 1); - b = Approximate(b); - b = EQs_to_GEQs(b); - - for (GEQ_Iterator e = - b.single_conjunct()->GEQs(); e; - e++) { - coef_t coef = (*e).get_coef( - b.input_var(i + 1)); - if (coef < 0) { - Relation r = Relation::True( - b.n_inp()); - r.and_with_GEQ(*e); - r.simplify(); - - if (Must_Be_Subset(copy(hull), - copy(r))) - continue; - - bool belong_to_hull = true; - for (int k = 0; k < l_Rs.size(); - k++) - if (k != j - && !Must_Be_Subset( - copy(l_Rs[k]), - copy(r))) { - belong_to_hull = false; - break; - } - if (belong_to_hull) { - hull.and_with_GEQ(*e); - got_rect_ub = true; - } - } - } - do_again = false; - if (!got_rect_ub) { - bool found = false; - for (GEQ_Iterator e = - b.single_conjunct()->GEQs(); e; - e++) { - coef_t coef = (*e).get_coef( - b.input_var(i + 1)); - if (coef < 0) { - for (Constr_Vars_Iter cvi(*e); - cvi; cvi++) - if ((*cvi).var->kind() - == Input_Var - && (*cvi).var->get_position() - - 1 != i) { - - if (((*cvi).coef > 0 - && has_ub[(*cvi).var->get_position() - - 1]) - || ((*cvi).coef - < 0 - && has_lb[(*cvi).var->get_position() - - 1])) { - vars.insert( - (*cvi).var->get_position()); - found = true; - } else { - for (GEQ_Iterator e2 = - b.single_conjunct()->GEQs(); - e2; e2++) - if (e2 != e - && (((*cvi).coef - > 0 - && (*e2).get_coef( - (*cvi).var) - < 0) - || ((*cvi).coef - < 0 - && (*e2).get_coef( - (*cvi).var) - > 0))) { - vars.insert( - (*cvi).var->get_position()); - found = - true; - break; - } - } - - } - } - if (found) - break; - } - if (found && (round_trip < i)) - do_again = true; - - } - round_trip++; - } while (do_again); - } - - if (got_rect_ub) - break; - } - } - } - } - } - } - - hull.simplify(); - hull.copy_names(Rs[first_non_null]); - hull.setup_names(); - return hull; -} - -} - diff --git a/omegalib/omega/src/omega_core/oc.cc b/omegalib/omega/src/omega_core/oc.cc deleted file mode 100644 index 0dc9b49..0000000 --- a/omegalib/omega/src/omega_core/oc.cc +++ /dev/null @@ -1,754 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Simplify a problem. - - Notes: - - History: - 12/10/06 Improved gist function, by Chun Chen. -*****************************************************************************/ - -#include <omega/omega_core/oc_i.h> - -namespace omega { - -eqn SUBs[maxVars+1]; -Memory redMemory[maxVars+1]; - -int Problem::reduceProblem() { - int result; - checkVars(nVars+1); - assert(omegaInitialized); - if (nVars > nEQs + 3 * safeVars) - freeEliminations(safeVars); - - check(); - if (!mayBeRed && nSUBs == 0 && safeVars == 0) { - result = solve(OC_SOLVE_UNKNOWN); - nGEQs = 0; - nEQs = 0; - nSUBs = 0; - nMemories = 0; - if (!result) { - int e = newEQ(); - assert(e == 0); - eqnnzero(&EQs[0], nVars); - EQs[0].color = EQ_BLACK; - EQs[0].coef[0] = 1; - } - check(); - return result; - } - return solve(OC_SOLVE_SIMPLIFY); -} - - -int Problem::simplifyProblem(int verify, int subs, int redundantElimination) { - checkVars(nVars+1); - assert(omegaInitialized); - setInternals(); - check(); - if (!reduceProblem()) goto returnFalse; - if (verify) { - addingOuterEqualities++; - int r = verifyProblem(); - addingOuterEqualities--; - if (!r) goto returnFalse; - if (nEQs) { // found some equality constraints during verification - int numRed = 0; - if (mayBeRed) - for (int e = nGEQs - 1; e >= 0; e--) if (GEQs[e].color == EQ_RED) numRed++; - if (mayBeRed && nVars == safeVars && numRed == 1) - nEQs = 0; // discard them - else if (!reduceProblem()) { - assert(0 && "Added equality constraint to verified problem generates false"); - } - } - } - if (redundantElimination) { - if (redundantElimination > 1) { - if (!expensiveEqualityCheck()) goto returnFalse; - } - if (!quickKill(0)) goto returnFalse; - if (redundantElimination > 1) { - if (!expensiveKill()) goto returnFalse; - } - } - resurrectSubs(); - if (redundantElimination) - simplifyStrideConstraints(); - if (redundantElimination > 2 && safeVars < nVars) { - if (!quickKill(0)) goto returnFalse; - return simplifyProblem(verify, subs, redundantElimination-2); - } - setExternals(); - assert(nMemories == 0); - return (1); - -returnFalse: - nGEQs = 0; - nEQs = 0; - resurrectSubs(); - nGEQs = 0; - nEQs = 0; - int neweq = newEQ(); - assert(neweq == 0); - eqnnzero(&EQs[neweq], nVars); - EQs[neweq].color = EQ_BLACK; - EQs[neweq].coef[0] = 1; - nMemories = 0; - return 0; -} - -int Problem::simplifyApproximate(bool strides_allowed) { - int result; - checkVars(nVars+1); - assert(inApproximateMode == 0); - - inApproximateMode = 1; - inStridesAllowedMode = strides_allowed; - if (TRACE) - fprintf(outputFile, "Entering Approximate Mode [\n"); - - assert(omegaInitialized); - result = simplifyProblem(0,0,0); - - while (result && !strides_allowed && nVars > safeVars) { - int e; - for (e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[nVars]) deleteGEQ(e); - for (e = nEQs - 1; e >= 0; e--) - if (EQs[e].coef[nVars]) deleteEQ(e); - nVars--; - result = simplifyProblem(0,0,0); - } - - if (TRACE) - fprintf(outputFile, "] Leaving Approximate Mode\n"); - - assert(inApproximateMode == 1); - inApproximateMode=0; - inStridesAllowedMode = 0; - - assert(nMemories == 0); - return (result); -} - - - - -/* - * Return 1 if red equations constrain the set of possible - * solutions. We assume that there are solutions to the black - * equations by themselves, so if there is no solution to the combined - * problem, we return 1. - */ - -#ifdef GIST_CHECK -Problem full_answer, context; -Problem redProblem; -#endif - -redCheck Problem::redSimplifyProblem(int effort, int computeGist) { - int result; - int e; - - checkVars(nVars+1); - assert(mayBeRed >= 0); - mayBeRed++; - - assert(omegaInitialized); - if (TRACE) { - fprintf(outputFile, "Checking for red equations:\n"); - printProblem(); - } - setInternals(); - -#ifdef GIST_CHECK - int r1,r2; - if (TRACE) - fprintf(outputFile,"Set-up for gist invariant checking[\n"); - redProblem = *this; - redProblem.check(); - full_answer = *this; - full_answer.check(); - full_answer.turnRedBlack(); - full_answer.check(); - r1 = full_answer.simplifyProblem(1,0,1); - full_answer.check(); - if (DBUG) fprintf(outputFile,"Simplifying context [\n"); - context = *this; - context.check(); - context.deleteRed(); - context.check(); - r2 = context.simplifyProblem(1,0,1); - context.check(); - if (DBUG) fprintf(outputFile,"] Simplifying context\n"); - - if (!r2 && TRACE) fprintf(outputFile, "WARNING: Gist context is false!\n"); - if (TRACE) - fprintf(outputFile,"] Set-up for gist invariant checking done\n"); -#endif - - // Save known integer modular equations, -- by chun 12/10/2006 - eqn ModularEQs[nEQs]; - int nModularEQs = 0; - int old_nVars = nVars; - for (int e = 0; e < nEQs; e++) - if (EQs[e].color != EQ_RED) - for (int i = safeVars+1; i <= nVars; i++) - if (EQs[e].coef[i] != 0) { - eqnncpy(&(ModularEQs[nModularEQs++]), &(EQs[e]), nVars); - break; - } - - - if (solveEQ() == false) { - if (TRACE) - fprintf(outputFile, "Gist is FALSE\n"); - if (computeGist) { - nMemories = 0; - nGEQs = 0; - nEQs = 0; - resurrectSubs(); - nGEQs = 0; - nEQs = 0; - int neweq = newEQ(); - assert(neweq == 0); - eqnnzero(&EQs[neweq], nVars); - EQs[neweq].color = EQ_RED; - EQs[neweq].coef[0] = 1; - } - mayBeRed--; - return redFalse; - } - - if (!computeGist && nMemories) - return redConstraints; - if (normalize() == normalize_false) { - if (TRACE) - fprintf(outputFile, "Gist is FALSE\n"); - if (computeGist) { - nGEQs = 0; - nEQs = 0; - resurrectSubs(); - nMemories = 0; - nGEQs = 0; - nEQs = 0; - int neweq = newEQ(); - assert(neweq == 0); - eqnnzero(&EQs[neweq], nVars); - EQs[neweq].color = EQ_RED; - EQs[neweq].coef[0] = 1; - } - mayBeRed--; - return redFalse; - } - - result = 0; - for (e = nGEQs - 1; e >= 0; e--) if (GEQs[e].color == EQ_RED) result = 1; - for (e = nEQs - 1; e >= 0; e--) if (EQs[e].color == EQ_RED) result = 1; - if (nMemories) result = 1; - if (!result) { - if (computeGist) { - nGEQs = 0; - nEQs = 0; - resurrectSubs(); - nGEQs = 0; - nMemories = 0; - nEQs = 0; - } - mayBeRed--; - return noRed; - } - - result = simplifyProblem(effort?1:0,1,0); -#ifdef GIST_CHECK - if (!r1 && TRACE && result) - fprintf(outputFile, "Gist is False but not detected\n"); -#endif - if (!result) { - if (TRACE) - fprintf(outputFile, "Gist is FALSE\n"); - if (computeGist) { - nGEQs = 0; - nEQs = 0; - resurrectSubs(); - nGEQs = 0; - nEQs = 0; - int neweq = newEQ(); - assert(neweq == 0); - nMemories = 0; - eqnnzero(&EQs[neweq], nVars); - EQs[neweq].color = EQ_RED; - EQs[neweq].coef[0] = 1; - } - mayBeRed--; - return redFalse; - } - - freeRedEliminations(); - - result = 0; - for (e = nGEQs - 1; e >= 0; e--) if (GEQs[e].color == EQ_RED) result = 1; - for (e = nEQs - 1; e >= 0; e--) if (EQs[e].color == EQ_RED) result = 1; - if (nMemories) result = 1; - if (!result) { - if (computeGist) { - nGEQs = 0; - nEQs = 0; - resurrectSubs(); - nGEQs = 0; - nMemories = 0; - nEQs = 0; - } - mayBeRed--; - return noRed; - } - - if (effort && (computeGist || !nMemories)) { - if (TRACE) - fprintf(outputFile, "*** Doing potentially expensive elimination tests for red equations [\n"); - quickRedKill(computeGist); - checkGistInvariant(); - result = nMemories; - for (e = nGEQs - 1; e >= 0; e--) if (GEQs[e].color == EQ_RED) result++; - for (e = nEQs - 1; e >= 0; e--) if (EQs[e].color == EQ_RED) result++; - if (result && effort > 1 && (computeGist || !nMemories)) { - expensiveRedKill(); - result = nMemories; - for (e = nGEQs-1; e >= 0; e--) if (GEQs[e].color == EQ_RED) result++; - for (e = nEQs-1; e >= 0; e--) if (EQs[e].color == EQ_RED) result++; - } - - if (!result) { - if (TRACE) - fprintf(outputFile, "]******************** Redudant Red Equations eliminated!!\n"); - if (computeGist) { - nGEQs = 0; - nEQs = 0; - resurrectSubs(); - nGEQs = 0; - nMemories = 0; - nEQs = 0; - } - mayBeRed--; - return noRed; - } - - if (TRACE) fprintf(outputFile, "]******************** Red Equations remain\n"); - if (DEBUG) printProblem(); - } - - if (computeGist) { - resurrectSubs(); - cleanoutWildcards(); - - - // Restore saved modular equations into EQs without affecting the problem - if (nEQs+nModularEQs > allocEQs) { - allocEQs = padEQs(allocEQs, nEQs+nModularEQs); - eqn *new_eqs = new eqn[allocEQs]; - for (int e = 0; e < nEQs; e++) - eqnncpy(&(new_eqs[e]), &(EQs[e]), nVars); - delete[] EQs; - EQs= new_eqs; - } - - for (int e = 0; e < nModularEQs; e++) { - eqnncpy(&(EQs[nEQs+e]), &(ModularEQs[e]), old_nVars); - EQs[nEQs+e].color = EQ_RED; - Tuple<coef_t> t(safeVars); - for (int i = 1; i <= safeVars; i++) - t[i] = ModularEQs[e].coef[var[i]]; - for (int i = 1; i <= safeVars; i++) - EQs[nEQs+e].coef[i] = t[i]; - } - - - // Now simplify modular equations using Chinese remainder theorem -- by chun 12/10/2006 - for (int e = 0; e < nEQs; e++) - if (EQs[e].color == EQ_RED) { - int wild_pos = -1; - for (int i = safeVars+1; i <= nVars; i++) - if (EQs[e].coef[i] != 0) { - wild_pos = i; - break; - } - - if (wild_pos == -1) - continue; - - for (int e2 = e+1; e2 < nEQs+nModularEQs; e2++) - if (EQs[e2].color == EQ_RED) { - int wild_pos2 = -1; - for (int i = safeVars+1; i <= ((e2<nEQs)?nVars:old_nVars); i++) - if (EQs[e2].coef[i] != 0) { - wild_pos2 = i; - break; - } - - if (wild_pos2 == -1) - continue; - - coef_t g = gcd(abs(EQs[e].coef[wild_pos]), abs(EQs[e2].coef[wild_pos2])); - coef_t g2 = 1; - coef_t g3; - EQs[e].color = EQs[e2].color = EQ_BLACK; - while ((g3 = factor(g)) != 1) { - coef_t gg = g2 * g3; - g = g/g3; - - bool match = true; - coef_t c = EQs[e].coef[0]; - coef_t c2 = EQs[e2].coef[0]; - bool change_sign = false; - for (int i = 1; i <= safeVars; i++) { - coef_t coef = int_mod_hat(EQs[e].coef[i], gg); - coef_t coef2 = int_mod_hat(EQs[e2].coef[i], gg); - - if (coef == 0 && coef2 == 0) - continue; - - if (change_sign && coef == -coef2) - continue; - - if (!change_sign) { - if (coef == coef2) - continue; - else if (coef == -coef2) { - change_sign = true; - continue; - } - } - - if (coef != 0) { - coef_t t = query_variable_mod(i, gg/gcd(abs(coef), gg), EQ_RED, nModularEQs, old_nVars); - if (t == posInfinity) { - match = false; - break; - } - - c += coef * t; - } - if (coef2 != 0) { - coef_t t = query_variable_mod(i, gg/gcd(abs(coef2), gg), EQ_RED, nModularEQs, old_nVars); - if (t == posInfinity) { - match = false; - break; - } - - c2 += coef2 * t; - } - } - if ((change_sign && int_mod_hat(c, gg) != -int_mod_hat(c2, gg)) || - (!change_sign && int_mod_hat(c, gg) != int_mod_hat(c2, gg))) - match = false; - - if (match) - g2 = gg; - } - EQs[e].color = EQs[e2].color = EQ_RED; - - if (g2 == 1) - continue; - - if (g2 == abs(EQs[e].coef[wild_pos])) { - EQs[e].color = EQ_BLACK; - break; - } - else if (e2 < nEQs && g2 == abs(EQs[e2].coef[wild_pos2])) - EQs[e2].color = EQ_BLACK; - else { - coef_t g4 = abs(EQs[e].coef[wild_pos])/g2; - while (lcm(g2, g4) != abs(EQs[e].coef[wild_pos])) { - assert(lcm(g2, g4) < abs(EQs[e].coef[wild_pos])); - g4 *= abs(EQs[e].coef[wild_pos])/lcm(g2, g4); - } - - for (int i = 0; i <= safeVars; i++) - EQs[e].coef[i] = int_mod_hat(EQs[e].coef[i], g4); - EQs[e].coef[wild_pos] = (EQs[e].coef[wild_pos]>0?1:-1)*g4; - } - } - } - - deleteBlack(); - } - - setExternals(); - mayBeRed--; - assert(nMemories == 0); - return redConstraints; -} - - -void Problem::convertEQstoGEQs(bool excludeStrides) { - int i; - int e; - if (DBUG) - fprintf(outputFile, "Converting all EQs to GEQs\n"); - simplifyProblem(0,0,0); - for(e=0;e<nEQs;e++) { - bool isStride = 0; - int e2 = newGEQ(); - if (excludeStrides) - for(i = safeVars+1; i <= nVars; i++) - isStride = isStride || (EQs[e].coef[i] != 0); - if (isStride) continue; - eqnncpy(&GEQs[e2], &EQs[e], nVars); - GEQs[e2].touched = 1; - e2 = newGEQ(); - eqnncpy(&GEQs[e2], &EQs[e], nVars); - GEQs[e2].touched = 1; - for (i = 0; i <= nVars; i++) - GEQs[e2].coef[i] = -GEQs[e2].coef[i]; - } - // If we have eliminated all EQs, can set nEQs to 0 - // If some strides are left, we don't know the position of them in the EQs - // array, so decreasing nEQs might remove wrong EQs -- we just leave them - // all in. (could sort the EQs to move strides to the front, but too hard.) - if (!excludeStrides) nEQs=0; - if (DBUG) - printProblem(); -} - - -void Problem::convertEQtoGEQs(int eq) { - int i; - if (DBUG) - fprintf(outputFile, "Converting EQ %d to GEQs\n",eq); - int e2 = newGEQ(); - eqnncpy(&GEQs[e2], &EQs[eq], nVars); - GEQs[e2].touched = 1; - e2 = newGEQ(); - eqnncpy(&GEQs[e2], &EQs[eq], nVars); - GEQs[e2].touched = 1; - for (i = 0; i <= nVars; i++) - GEQs[e2].coef[i] = -GEQs[e2].coef[i]; - if (DBUG) - printProblem(); -} - - -/* - * Calculate value of variable modulo integer from problem's equation - * set plus additional saved modular equations embedded in the same - * EQs array (hinted by nModularEQs) if available. If there is no - * solution, return posInfinity. - */ -coef_t Problem::query_variable_mod(int v, coef_t factor, int color, int nModularEQs, int nModularVars) const { - if (safeVars < v) - return posInfinity; - - Tuple<bool> working_on(safeVars); - for (int i = 1; i <= safeVars; i++) - working_on[i] = false; - - return query_variable_mod(v, factor, color, nModularEQs, nModularVars, working_on); -} - -coef_t Problem::query_variable_mod(int v, coef_t factor, int color, int nModularEQs, int nModularVars, Tuple<bool> &working_on) const { - working_on[v] = true; - - for (int e = 0; e < nEQs+nModularEQs; e++) - if (EQs[e].color == color) { - coef_t coef = int_mod_hat(EQs[e].coef[v], factor); - if (abs(coef) != 1) - continue; - - bool wild_factored = true; - for (int i = safeVars+1; i <= ((e<nEQs)?nVars:nModularVars); i++) - if (int_mod_hat(EQs[e].coef[i], factor) != 0) { - wild_factored = false; - break; - } - if (!wild_factored) - continue; - - coef_t result = 0; - for (int i = 1; i <= safeVars; i++) - if (i != v) { - coef_t p = int_mod_hat(EQs[e].coef[i], factor); - - if (p == 0) - continue; - - if (working_on[i] == true) { - result = posInfinity; - break; - } - - coef_t q = query_variable_mod(i, factor, color, nModularEQs, nModularVars, working_on); - if (q == posInfinity) { - result = posInfinity; - break; - } - result += p*q; - } - - if (result != posInfinity) { - result += EQs[e].coef[0]; - if (coef == 1) - result = -result; - working_on[v] = false; - - return int_mod_hat(result, factor); - } - } - - working_on[v] = false; - return posInfinity; -} - - - -#ifdef GIST_CHECK -enum compareAnswer {apparentlyEqual, mightNotBeEqual, NotEqual}; - -static compareAnswer checkEquiv(Problem *p1, Problem *p2) { - int r1,r2; - - p1->check(); - p2->check(); - p1->resurrectSubs(); - p2->resurrectSubs(); - p1->check(); - p2->check(); - p1->putVariablesInStandardOrder(); - p2->putVariablesInStandardOrder(); - p1->check(); - p2->check(); - p1->ordered_elimination(0); - p2->ordered_elimination(0); - p1->check(); - p2->check(); - r1 = p1->simplifyProblem(1,1,0); - r2 = p2->simplifyProblem(1,1,0); - p1->check(); - p2->check(); - - if (!r1 || !r2) { - if (r1 == r2) return apparentlyEqual; - return NotEqual; - } - if (p1->nVars != p2->nVars - || p1->nGEQs != p2->nGEQs - || p1->nSUBs != p2->nSUBs - || p1->checkSum() != p2->checkSum()) { - r1 = p1->simplifyProblem(0,1,1); - r2 = p2->simplifyProblem(0,1,1); - assert(r1 && r2); - p1->check(); - p2->check(); - if (p1->nVars != p2->nVars - || p1->nGEQs != p2->nGEQs - || p1->nSUBs != p2->nSUBs - || p1->checkSum() != p2->checkSum()) { - r1 = p1->simplifyProblem(0,1,2); - r2 = p2->simplifyProblem(0,1,2); - p1->check(); - p2->check(); - assert(r1 && r2); - if (p1->nVars != p2->nVars - || p1->nGEQs != p2->nGEQs - || p1->nSUBs != p2->nSUBs - || p1->checkSum() != p2->checkSum()) { - p1->check(); - p2->check(); - p1->resurrectSubs(); - p2->resurrectSubs(); - p1->check(); - p2->check(); - p1->putVariablesInStandardOrder(); - p2->putVariablesInStandardOrder(); - p1->check(); - p2->check(); - p1->ordered_elimination(0); - p2->ordered_elimination(0); - p1->check(); - p2->check(); - r1 = p1->simplifyProblem(1,1,0); - r2 = p2->simplifyProblem(1,1,0); - p1->check(); - p2->check(); - } - } - } - - if (p1->nVars != p2->nVars - || p1->nSUBs != p2->nSUBs - || p1->nGEQs != p2->nGEQs - || p1->nSUBs != p2->nSUBs) return NotEqual; - if (p1->checkSum() != p2->checkSum()) return mightNotBeEqual; - return apparentlyEqual; -} -#endif - -void Problem::checkGistInvariant() const { -#ifdef GIST_CHECK - Problem new_answer; - int r; - - check(); - fullAnswer.check(); - context.check(); - - if (safeVars < nVars) { - if (DBUG) { - fprintf(outputFile,"Can't check gist invariant due to wildcards\n"); - printProblem(); - } - return; - } - if (DBUG) { - fprintf(outputFile,"Checking gist invariant on: [\n"); - printProblem(); - } - - new_answer = *this; - new_answer->resurrectSubs(); - new_answer->cleanoutWildcards(); - if (DEBUG) { - fprintf(outputFile,"which is: \n"); - printProblem(); - } - deleteBlack(&new_answer); - turnRedBlack(&new_answer); - if (DEBUG) { - fprintf(outputFile,"Black version of answer: \n"); - printProblem(&new_answer); - } - problem_merge(&new_answer,&context); - - r = checkEquiv(&full_answer,&new_answer); - if (r != apparentlyEqual) { - fprintf(outputFile,"GIST INVARIANT REQUIRES MANUAL CHECK:[\n"); - fprintf(outputFile,"Original problem:\n"); - printProblem(&redProblem); - - fprintf(outputFile,"Context:\n"); - printProblem(&context); - - fprintf(outputFile,"Computed gist:\n"); - printProblem(); - - fprintf(outputFile,"Combined answer:\n"); - printProblem(&full_answer); - - fprintf(outputFile,"Context && red constraints:\n"); - printProblem(&new_answer); - fprintf(outputFile,"]\n"); - } - - if (DBUG) { - fprintf(outputFile,"] Done checking gist invariant on\n"); - } -#endif -} - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_eq.cc b/omegalib/omega/src/omega_core/oc_eq.cc deleted file mode 100644 index dc595ea..0000000 --- a/omegalib/omega/src/omega_core/oc_eq.cc +++ /dev/null @@ -1,653 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Solve equalities. - - Notes: - - History: - *****************************************************************************/ - -#include <omega/omega_core/oc_i.h> - -namespace omega { - -void Problem::simplifyStrideConstraints() { - int e, e2, i; - if (DBUG) - fprintf(outputFile, "Checking for stride constraints\n"); - for (i = safeVars + 1; i <= nVars; i++) { - if (DBUG) - fprintf(outputFile, "checking %s\n", variable(i)); - for (e = 0; e < nGEQs; e++) - if (GEQs[e].coef[i]) - break; - if (e >= nGEQs) { - if (DBUG) - fprintf(outputFile, "%s passed GEQ test\n", variable(i)); - e2 = -1; - for (e = 0; e < nEQs; e++) - if (EQs[e].coef[i]) { - if (e2 == -1) - e2 = e; - else { - e2 = -1; - break; - } - } - if (e2 >= 0) { - if (DBUG) { - fprintf(outputFile, "Found stride constraint: "); - printEQ(&EQs[e2]); - fprintf(outputFile, "\n"); - } - /* Is a stride constraint */ - coef_t g = abs(EQs[e2].coef[i]); - assert(g>0); - int j; - for (j = 0; j <= nVars; j++) - if (i != j) - EQs[e2].coef[j] = int_mod_hat(EQs[e2].coef[j], g); - } - } - } -} - -void Problem::doMod(coef_t factor, int e, int j) { - /* Solve e = factor alpha for x_j and substitute */ - int k; - eqn eq; - coef_t nFactor; - - int alpha; - - // if (j > safeVars) alpha = j; - // else - if (EQs[e].color) { - rememberRedConstraint(&EQs[e], redEQ, 0); - EQs[e].color = EQ_BLACK; - } - alpha = addNewUnprotectedWildcard(); - eqnncpy(&eq, &EQs[e], nVars); - newVar = alpha; - - if (DEBUG) { - fprintf(outputFile, "doing moding: "); - fprintf(outputFile, "Solve "); - printTerm(&eq, 1); - fprintf(outputFile, " = " coef_fmt " %s for %s and substitute\n", - factor, variable(alpha), variable(j)); - } - for (k = nVars; k >= 0; k--) - eq.coef[k] = int_mod_hat(eq.coef[k], factor); - nFactor = eq.coef[j]; - assert(nFactor == 1 || nFactor == -1); - eq.coef[alpha] = factor / nFactor; - if (DEBUG) { - fprintf(outputFile, "adjusted: "); - fprintf(outputFile, "Solve "); - printTerm(&eq, 1); - fprintf(outputFile, " = 0 for %s and substitute\n", variable(j)); - } - - eq.coef[j] = 0; - substitute(&eq, j, nFactor); - newVar = -1; - deleteVariable(j); - for (k = nVars; k >= 0; k--) { - assert(EQs[e].coef[k] % factor == 0); - EQs[e].coef[k] = EQs[e].coef[k] / factor; - } - if (DEBUG) { - fprintf(outputFile, "Mod-ing and normalizing produces:\n"); - printProblem(); - } -} - -void Problem::substitute(eqn *sub, int i, coef_t c) { - int e, j; - coef_t k; - int recordSubstitution = (i <= safeVars && var[i] >= 0); - - redType clr; - if (sub->color) - clr = redEQ; - else - clr = notRed; - - assert(c == 1 || c == -1); - - if (DBUG || doTrace) { - if (sub->color) - fprintf(outputFile, "RED SUBSTITUTION\n"); - fprintf(outputFile, "substituting using %s := ", variable(i)); - printTerm(sub, -c); - fprintf(outputFile, "\n"); - printVars(); - } -#ifndef NDEBUG - if (i > safeVars && clr) { - bool unsafeSub = false; - for (e = nEQs - 1; e >= 0; e--) - if (!(EQs[e].color || !EQs[e].coef[i])) - unsafeSub = true; - for (e = nGEQs - 1; e >= 0; e--) - if (!(GEQs[e].color || !GEQs[e].coef[i])) - unsafeSub = true; - for (e = nSUBs - 1; e >= 0; e--) - if (SUBs[e].coef[i]) - unsafeSub = true; - if (unsafeSub) { - fprintf(outputFile, "UNSAFE RED SUBSTITUTION\n"); - fprintf(outputFile, "substituting using %s := ", variable(i)); - printTerm(sub, -c); - fprintf(outputFile, "\n"); - printProblem(); - assert(0 && "UNSAFE RED SUBSTITUTION"); - } - } -#endif - - for (e = nEQs - 1; e >= 0; e--) { - eqn *eq; - eq = &(EQs[e]); - k = eq->coef[i]; - if (k != 0) { - k = check_mul(k, c); // Should be k = k/c, but same effect since abs(c) == 1 - eq->coef[i] = 0; - for (j = nVars; j >= 0; j--) { - eq->coef[j] -= check_mul(sub->coef[j], k); - } - } - if (DEBUG) { - printEQ(eq); - fprintf(outputFile, "\n"); - } - } - for (e = nGEQs - 1; e >= 0; e--) { - int zero; - eqn *eq; - eq = &(GEQs[e]); - k = eq->coef[i]; - if (k != 0) { - k = check_mul(k, c); // Should be k = k/c, but same effect since abs(c) == 1 - eq->touched = true; - eq->coef[i] = 0; - zero = 1; - for (j = nVars; j >= 0; j--) { - eq->coef[j] -= check_mul(sub->coef[j], k); - if (j > 0 && eq->coef[j]) - zero = 0; - } - if (zero && clr != notRed && !eq->color) { - coef_t z = int_div(eq->coef[0], abs(k)); - if (DBUG || doTrace) { - fprintf(outputFile, - "Black inequality matches red substitution\n"); - if (z < 0) - fprintf(outputFile, "System is infeasible\n"); - else if (z > 0) - fprintf(outputFile, "Black inequality is redundant\n"); - else { - fprintf(outputFile, - "Black constraint partially implies red equality\n"); - if (k < 0) { - fprintf(outputFile, "Black constraints tell us "); - assert(sub->coef[i] == 0); - sub->coef[i] = c; - printTerm(sub, 1); - sub->coef[i] = 0; - fprintf(outputFile, "<= 0\n"); - } else { - fprintf(outputFile, "Black constraints tell us "); - assert(sub->coef[i] == 0); - sub->coef[i] = c; - printTerm(sub, 1); - sub->coef[i] = 0; - fprintf(outputFile, " >= 0\n"); - } - } - } - if (z == 0) { - if (k < 0) { - if (clr == redEQ) - clr = redGEQ; - else if (clr == redLEQ) - clr = notRed; - } else { - if (clr == redEQ) - clr = redLEQ; - else if (clr == redGEQ) - clr = notRed; - } - } - - } - } - if (DEBUG) { - printGEQ(eq); - fprintf(outputFile, "\n"); - } - } - if (i <= safeVars && clr) { - assert(sub->coef[i] == 0); - sub->coef[i] = c; - rememberRedConstraint(sub, clr, 0); - sub->coef[i] = 0; - } - - if (recordSubstitution) { - int s = nSUBs++; - int kk; - eqn *eq = &(SUBs[s]); - for (kk = nVars; kk >= 0; kk--) - eq->coef[kk] = check_mul(-c, (sub->coef[kk])); - eq->key = var[i]; - if (DEBUG) { - fprintf(outputFile, "Recording substition as: "); - printSubstitution(s); - fprintf(outputFile, "\n"); - } - } - if (DEBUG) { - fprintf(outputFile, "Ready to update subs\n"); - if (sub->color) - fprintf(outputFile, "RED SUBSTITUTION\n"); - fprintf(outputFile, "substituting using %s := ", variable(i)); - printTerm(sub, -c); - fprintf(outputFile, "\n"); - printVars(); - } - - for (e = nSUBs - 1; e >= 0; e--) { - eqn *eq = &(SUBs[e]); - k = eq->coef[i]; - if (k != 0) { - k = check_mul(k, c); // Should be k = k/c, but same effect since abs(c) == 1 - eq->coef[i] = 0; - for (j = nVars; j >= 0; j--) { - eq->coef[j] -= check_mul(sub->coef[j], k); - } - } - if (DEBUG) { - fprintf(outputFile, "updated sub (" coef_fmt "): ", c); - printSubstitution(e); - fprintf(outputFile, "\n"); - } - } - - if (DEBUG) { - fprintf(outputFile, "---\n\n"); - printProblem(); - fprintf(outputFile, "===\n\n"); - } -} - - -void Problem::doElimination(int e, int i) { - if (DBUG || doTrace) - fprintf(outputFile, "eliminating variable %s\n", variable(i)); - - eqn sub; - eqnncpy(&sub, &EQs[e], nVars); - coef_t c = sub.coef[i]; - sub.coef[i] = 0; - - if (c == 1 || c == -1) { - substitute(&sub, i, c); - } else { - coef_t a = abs(c); - if (TRACE) - fprintf(outputFile, - "performing non-exact elimination, c = " coef_fmt "\n", c); - if (DBUG) - printProblem(); - assert(inApproximateMode); - - for (int e2 = nEQs - 1; e2 >= 0; e2--) { - eqn *eq = &(EQs[e2]); - coef_t k = eq->coef[i]; - if (k != 0) { - coef_t l = lcm(abs(k), a); - coef_t scale1 = l / abs(k); - for (int j = nVars; j >= 0; j--) - eq->coef[j] = check_mul(eq->coef[j], scale1); - eq->coef[i] = 0; - coef_t scale2 = l / c; - if (k < 0) - scale2 = -scale2; - for (int j = nVars; j >= 0; j--) - eq->coef[j] -= check_mul(sub.coef[j], scale2); - eq->color |= sub.color; - } - } - for (int e2 = nGEQs - 1; e2 >= 0; e2--) { - eqn *eq = &(GEQs[e2]); - coef_t k = eq->coef[i]; - if (k != 0) { - coef_t l = lcm(abs(k), a); - coef_t scale1 = l / abs(k); - for (int j = nVars; j >= 0; j--) - eq->coef[j] = check_mul(eq->coef[j], scale1); - eq->coef[i] = 0; - coef_t scale2 = l / c; - if (k < 0) - scale2 = -scale2; - for (int j = nVars; j >= 0; j--) - eq->coef[j] -= check_mul(sub.coef[j], scale2); - eq->color |= sub.color; - eq->touched = 1; - } - } - for (int e2 = nSUBs - 1; e2 >= 0; e2--) - if (SUBs[e2].coef[i]) { - eqn *eq = &(EQs[e2]); - assert(0); - // We can't handle this since we can't multiply - // the coefficient of the left-hand side - assert(!sub.color); - for (int j = nVars; j >= 0; j--) - eq->coef[j] = check_mul(eq->coef[j], a); - coef_t k = eq->coef[i]; - eq->coef[i] = 0; - for (int j = nVars; j >= 0; j--) - eq->coef[j] -= check_mul(sub.coef[j], k / c); - } - } - deleteVariable(i); -} - -int Problem::solveEQ() { - check(); - - // Reorder equations according to complexity. - { - int delay[nEQs]; - - for (int e = 0; e < nEQs; e++) { - delay[e] = 0; - if (EQs[e].color) - delay[e] += 8; - int nonunitWildCards = 0; - int unitWildCards = 0; - for (int i = nVars; i > safeVars; i--) - if (EQs[e].coef[i]) { - if (EQs[e].coef[i] == 1 || EQs[e].coef[i] == -1) - unitWildCards++; - else - nonunitWildCards++; - } - int unit = 0; - int nonUnit = 0; - for (int i = safeVars; i > 0; i--) - if (EQs[e].coef[i]) { - if (EQs[e].coef[i] == 1 || EQs[e].coef[i] == -1) - unit++; - else - nonUnit++; - } - if (unitWildCards == 1 && nonunitWildCards == 0) - delay[e] += 0; - else if (unitWildCards >= 1 && nonunitWildCards == 0) - delay[e] += 1; - else if (inApproximateMode && nonunitWildCards > 0) - delay[e] += 2; - else if (unit == 1 && nonUnit == 0 && nonunitWildCards == 0) - delay[e] += 3; - else if (unit > 1 && nonUnit == 0 && nonunitWildCards == 0) - delay[e] += 4; - else if (unit >= 1 && nonunitWildCards <= 1) - delay[e] += 5; - else - delay[e] += 6; - } - - for (int e = 0; e < nEQs; e++) { - int e2, slowest; - slowest = e; - for (e2 = e + 1; e2 < nEQs; e2++) - if (delay[e2] > delay[slowest]) - slowest = e2; - if (slowest != e) { - int tmp = delay[slowest]; - delay[slowest] = delay[e]; - delay[e] = tmp; - eqn eq; - eqnncpy(&eq, &EQs[slowest], nVars); - eqnncpy(&EQs[slowest], &EQs[e], nVars); - eqnncpy(&EQs[e], &eq, nVars); - } - } - } - - // Eliminate all equations. - while (nEQs != 0) { - int e = nEQs - 1; - eqn *eq = &(EQs[e]); - coef_t g, g2; - - assert(mayBeRed || !eq->color); - - check(); - - // get gcd of coefficients of all unprotected variables - g2 = 0; - for (int i = nVars; i > safeVars; i--) - if (eq->coef[i] != 0) { - g2 = gcd(abs(eq->coef[i]), g2); - if (g2 == 1) - break; - } - - // get gcd of coefficients of all variables - g = g2; - if (g != 1) - for (int i = safeVars; i >= 1; i--) - if (eq->coef[i] != 0) { - g = gcd(abs(eq->coef[i]), g); - if (g == 1) - break; - } - - // approximate mode bypass integer modular test; in Farkas(), - // existential variable lambda's are rational numbers. - if (inApproximateMode && g2 != 0) - g = gcd(abs(eq->coef[0]), g); - - // simple test to see if the equation is satisfiable - if (g == 0) { - if (eq->coef[0] != 0) { - return (false); - } else { - nEQs--; - continue; - } - } else if (abs(eq->coef[0]) % g != 0) { - return (false); - } - - // set gcd of all coefficients to 1 - if (g != 1) { - for (int i = nVars; i >= 0; i--) - eq->coef[i] /= g; - g2 = g2 / g; - } - - // exact elimination of unit coefficient variable - if (g2 != 0) { // for constraint with unprotected variable - int i; - for (i = nVars; i > safeVars; i--) - if (abs(eq->coef[i]) == 1) - break; - if (i > safeVars) { - nEQs--; - doElimination(e, i); - continue; - } - } else { // for constraint without unprotected variable - - // pick the unit coefficient variable with complex inequalites - // to eliminate, this will make inequalities tighter. e.g. - // {[t4,t6,t10]:exists (alpha: 0<=t6<=3 && t10=4alpha+t6 && - // 64t4<=t10<=64t4+15)} - int unit_var; - int cost = -1; - - for (int i = safeVars; i > 0; i--) - - if (abs(eq->coef[i]) == 1) { - int cur_cost = 0; - for (int j = 0; j < nGEQs; j++) - if (GEQs[j].coef[i] != 0) { - for (int k = safeVars; k > 0; k--) - if (GEQs[j].coef[k] != 0) { - if (abs(GEQs[j].coef[k]) != 1){ - - cur_cost += 3; - - } - else - cur_cost += 1; - } - } - - if (cur_cost > cost) { - cost = cur_cost; - unit_var = i; - } - - } - - if (cost != -1) { - nEQs--; - doElimination(e, unit_var); - continue; - } - - - } - - // check if there is an unprotected variable as wildcard - if (g2 > 0) { - int pos = 0; - coef_t g3; - for (int k = nVars; k > safeVars; k--) - if (eq->coef[k] != 0) { - int e2; - for (e2 = e - 1; e2 >= 0; e2--) - if (EQs[e2].coef[k]) - break; - if (e2 >= 0) - continue; - for (e2 = nGEQs - 1; e2 >= 0; e2--) - if (GEQs[e2].coef[k]) - break; - if (e2 >= 0) - continue; - for (e2 = nSUBs - 1; e2 >= 0; e2--) - if (SUBs[e2].coef[k]) - break; - if (e2 >= 0) - continue; - - if (pos == 0) { - g3 = abs(eq->coef[k]); - pos = k; - } else { - if (abs(eq->coef[k]) < g3) { - g3 = abs(eq->coef[k]); - pos = k; - } - } - } - - if (pos != 0) { - bool change = false; - for (int k2 = nVars; k2 >= 0; k2--) - if (k2 != pos && eq->coef[k2] != 0) { - coef_t t = int_mod_hat(eq->coef[k2], g3); - if (t != eq->coef[k2]) { - eq->coef[k2] = t; - change = true; - } - } - - // strength reduced, try this equation again - if (change) { - // nameWildcard(pos); - continue; - } - } - } - - // insert new stride constraint - if (g2 > 1 && !(inApproximateMode && !inStridesAllowedMode)) { - int newvar = addNewProtectedWildcard(); - int neweq = newEQ(); - assert(neweq == e+1); - // we were working on highest-numbered EQ - eqnnzero(&EQs[neweq], nVars); - eqnncpy(&EQs[neweq], eq, safeVars); - - for (int k = nVars; k >= 0; k--) { - EQs[neweq].coef[k] = int_mod_hat(EQs[neweq].coef[k], g2); - } - if (EQs[e].color) - rememberRedConstraint(&EQs[neweq], redStride, g2); - EQs[neweq].coef[newvar] = g2; - EQs[neweq].color = EQ_BLACK; - continue; - } - - // inexact elimination of unprotected variable - if (g2 > 0 && inApproximateMode) { - int pos = 0; - for (int k = nVars; k > safeVars; k--) - if (eq->coef[k] != 0) { - pos = k; - break; - } - assert(pos > safeVars); - - // special handling for wildcard used in breaking down - // diophantine equation - if (abs(eq->coef[pos]) > 1) { - int e2; - for (e2 = nSUBs - 1; e2 >= 0; e2--) - if (SUBs[e2].coef[pos]) - break; - if (e2 >= 0) { - protectWildcard(pos); - continue; - } - } - - nEQs--; - doElimination(e, pos); - continue; - } - - // now solve linear diophantine equation using least remainder - // algorithm - { - coef_t factor = (posInfinity); // was MAXINT - int pos = 0; - for (int k = nVars; k > (g2 > 0 ? safeVars : 0); k--) - if (eq->coef[k] != 0 && factor > abs(eq->coef[k]) + 1) { - factor = abs(eq->coef[k]) + 1; - pos = k; - } - assert(pos > (g2>0?safeVars:0)); - doMod(factor, e, pos); - continue; - } - } - - assert(nEQs == 0); - return (OC_SOLVE_UNKNOWN); -} - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_exp_kill.cc b/omegalib/omega/src/omega_core/oc_exp_kill.cc deleted file mode 100644 index fdb2718..0000000 --- a/omegalib/omega/src/omega_core/oc_exp_kill.cc +++ /dev/null @@ -1,297 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Expensive inequality elimination. - - Notes: - - History: - 03/31/09 Use BoolSet, Chun Chen -*****************************************************************************/ - -#include <omega/omega_core/oc_i.h> -#include <basic/BoolSet.h> -#include <vector> - -namespace omega { - -int Problem::expensiveKill() { - int e; - if (TRACE) fprintf(outputFile,"Performing expensive kill tests: [\n"); - if (DBUG) printProblem(); - Problem tmpProblem; - int oldTrace = trace; - int constraintsRemoved = 0; - - trace = 0; - conservative++; - - for (e = nGEQs - 1; e >= 0; e--) - if (!GEQs[e].essential) { - if (DBUG) { - fprintf(outputFile, "checking equation %d to see if it is redundant: ", e); - printGEQ(&(GEQs[e])); - fprintf(outputFile, "\n"); - } - tmpProblem = *this; - tmpProblem.negateGEQ(e); - tmpProblem.varsOfInterest = 0; - tmpProblem.nSUBs = 0; - tmpProblem.nMemories = 0; - tmpProblem.safeVars = 0; - tmpProblem.variablesFreed = 0; - tmpProblem.isTemporary = true; - - if (!tmpProblem.solve(false)) { - if (DBUG) - fprintf(outputFile, "redundant!\n"); - constraintsRemoved++; - deleteGEQ(e); - } - } - - if (constraintsRemoved) { - if (TRACE) fprintf(outputFile,"%d Constraints removed!!\n",constraintsRemoved); - } - - trace = oldTrace; - conservative--; - if (TRACE) fprintf(outputFile,"] expensive kill tests done\n"); - return 1; -} - -int Problem::expensiveRedKill() { - int e; - if (TRACE) fprintf(outputFile,"Performing expensive red kill tests: [\n"); - Problem tmpProblem; - int oldTrace = trace; - int constraintsRemoved = 0; - - trace = 0; - conservative++; - - for (e = nGEQs - 1; e >= 0; e--) - if (!GEQs[e].essential && GEQs[e].color) { - if (DEBUG) { - fprintf(outputFile, "checking equation %d to see if it is redundant: ", e); - printGEQ(&(GEQs[e])); - fprintf(outputFile, "\n"); - } - tmpProblem = *this; - tmpProblem.negateGEQ(e); - tmpProblem.varsOfInterest = 0; - tmpProblem.nSUBs = 0; - tmpProblem.nMemories = 0; - tmpProblem.safeVars = 0; - tmpProblem.variablesFreed = 0; - tmpProblem.isTemporary = true; - tmpProblem.turnRedBlack(); - if (!tmpProblem.solve(false)) { - constraintsRemoved++; - deleteGEQ(e); - } - } - - if (constraintsRemoved) { - if (TRACE) fprintf(outputFile,"%d Constraints removed!!\n",constraintsRemoved); - } - - trace = oldTrace; - conservative--; - if (TRACE) fprintf(outputFile,"] expensive red kill tests done\n"); - return 1; -} - - -int Problem::expensiveEqualityCheck() { - int e; - return 1; - if (TRACE) fprintf(outputFile,"Performing expensive equality tests: [\n"); - Problem tmpProblem; - int oldTrace = trace; - int equalitiesFound = 0; - - trace = 0; - conservative++; - - for (e = nGEQs - 1; e >= 0; e--) { - if (DEBUG) { - fprintf(outputFile, "checking equation %d to see if it is an equality: ", e); - printGEQ(&(GEQs[e])); - fprintf(outputFile, "\n"); - } - tmpProblem = *this; - tmpProblem.GEQs[e].coef[0]--; - tmpProblem.varsOfInterest = 0; - tmpProblem.nSUBs = 0; - tmpProblem.nMemories = 0; - tmpProblem.safeVars = 0; - tmpProblem.variablesFreed = 0; - tmpProblem.isTemporary = true; - if (!tmpProblem.solve(false)) { - int neweq = newEQ(); - eqnncpy(&EQs[neweq], &GEQs[e], nVars); - equalitiesFound++; - addingEqualityConstraint(neweq); - } - } - if (equalitiesFound) { - if (TRACE) fprintf(outputFile,"%d Equalities found!!\n",equalitiesFound); - } - - trace = oldTrace; - conservative--; - if (equalitiesFound) { - if (!solveEQ()) return 0; - if (!normalize()) return 0; - } - if (TRACE) fprintf(outputFile,"] expensive equality tests done\n"); - return 1; -} - - -void Problem::quickRedKill(int computeGist) { - if (DBUG) { - fprintf(outputFile, "in quickRedKill: [\n"); - printProblem(); - } - - noteEssential(0); - int moreToDo = chainKill(1,0); - -#ifdef NDEBUG - if (!moreToDo) { - if (DBUG) fprintf(outputFile, "] quickRedKill\n"); - return; - } -#endif - - int isDead[nGEQs]; - int deadCount = 0; - std::vector<BoolSet<> > P(nGEQs, BoolSet<>(nVars)), Z(nGEQs, BoolSet<>(nVars)), N(nGEQs, BoolSet<>(nVars)); - BoolSet<> PP, PZ, PN; /* possible Positives, possible zeros & possible negatives */ - BoolSet<> MZ; /* must zeros */ - - int equationsToKill = 0; - for (int e = nGEQs - 1; e >= 0; e--) { - isDead[e] = 0; - if (GEQs[e].color && !GEQs[e].essential) equationsToKill++; - if (GEQs[e].color && GEQs[e].essential && !computeGist) - if (!moreToDo) { - if (DBUG) fprintf(outputFile, "] quickRedKill\n"); - return; - } - for (int i = nVars; i >= 1; i--) { - if (GEQs[e].coef[i] > 0) - P[e].set(i-1); - else if (GEQs[e].coef[i] < 0) - N[e].set(i-1); - else - Z[e].set(i-1); - } - } - - if (!equationsToKill) - if (!moreToDo) { - if (DBUG) fprintf(outputFile, "] quickRedKill\n"); - return; - } - - for (int e = nGEQs - 1; e > 0; e--) - if (!isDead[e]) - for (int e2 = e - 1; e2 >= 0; e2--) - if (!isDead[e2]) { - coef_t a = 0; - int i, j; - for (i = nVars; i > 1; i--) { - for (j = i - 1; j > 0; j--) { - a = (GEQs[e].coef[i] * GEQs[e2].coef[j] - GEQs[e2].coef[i] * GEQs[e].coef[j]); - if (a != 0) - goto foundPair; - } - } - continue; - - foundPair: - if (DEBUG) { - fprintf(outputFile, "found two equations to combine, i = %s, ", variable(i)); - fprintf(outputFile, "j = %s, alpha = " coef_fmt "\n", variable(j), a); - printGEQ(&(GEQs[e])); - fprintf(outputFile, "\n"); - printGEQ(&(GEQs[e2])); - fprintf(outputFile, "\n"); - } - - MZ = (Z[e] & Z[e2]); - PZ = MZ | (P[e] & N[e2]) | (N[e] & P[e2]); - PP = P[e] | P[e2]; - PN = N[e] | N[e2]; - - for (int e3 = nGEQs - 1; e3 >= 0; e3--) - if (e3 != e && e3 != e2 && GEQs[e3].color && !GEQs[e3].essential) { - coef_t alpha1, alpha2, alpha3; - - if (!PZ.imply(Z[e3]) || MZ.imply(~Z[e3])) continue; - if (!PP.imply(P[e3]) || !PN.imply(N[e3])) continue; - - if (a > 0) { - alpha1 = GEQs[e2].coef[j] * GEQs[e3].coef[i] - GEQs[e2].coef[i] * GEQs[e3].coef[j]; - alpha2 = -(GEQs[e].coef[j] * GEQs[e3].coef[i] - GEQs[e].coef[i] * GEQs[e3].coef[j]); - alpha3 = a; - } - else { - alpha1 = -(GEQs[e2].coef[j] * GEQs[e3].coef[i] - GEQs[e2].coef[i] * GEQs[e3].coef[j]); - alpha2 = -(-(GEQs[e].coef[j] * GEQs[e3].coef[i] - GEQs[e].coef[i] * GEQs[e3].coef[j])); - alpha3 = -a; - } - - if (alpha1 > 0 && alpha2 > 0) { - if (DEBUG) { - fprintf(outputFile, "alpha1 = " coef_fmt ", alpha2 = " coef_fmt "; comparing against: ", alpha1, alpha2); - printGEQ(&(GEQs[e3])); - fprintf(outputFile, "\n"); - } - coef_t c; - int k; - for (k = nVars; k >= 0; k--) { - c = alpha1 * GEQs[e].coef[k] + alpha2 * GEQs[e2].coef[k]; - if (DEBUG) { - if (k>0) - fprintf(outputFile, " %s: " coef_fmt ", " coef_fmt "\n", variable(k), c, alpha3 * GEQs[e3].coef[k]); - else fprintf(outputFile, " constant: " coef_fmt ", " coef_fmt "\n", c, alpha3 * GEQs[e3].coef[k]); - } - if (c != alpha3 * GEQs[e3].coef[k]) - break; - } - if (k < 0 || (k == 0 && c < alpha3 * (GEQs[e3].coef[k]+1))) { - if (DEBUG) { - deadCount++; - fprintf(outputFile, "red equation#%d is dead (%d dead so far, %d remain)\n", e3, deadCount, nGEQs - deadCount); - printGEQ(&(GEQs[e])); - fprintf(outputFile, "\n"); - printGEQ(&(GEQs[e2])); - fprintf(outputFile, "\n"); - printGEQ(&(GEQs[e3])); - fprintf(outputFile, "\n"); - assert(moreToDo); - } - isDead[e3] = 1; - } - } - } - } - - for (int e = nGEQs - 1; e >= 0; e--) - if (isDead[e]) - deleteGEQ(e); - - if (DBUG) { - fprintf(outputFile,"] quickRedKill\n"); - printProblem(); - } -} - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_global.cc b/omegalib/omega/src/omega_core/oc_global.cc deleted file mode 100644 index 17d8a0c..0000000 --- a/omegalib/omega/src/omega_core/oc_global.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include <omega/omega_core/oc_i.h> - -namespace omega { - -const int Problem::min_alloc = 10; -const int Problem::first_alloc_pad = 5; - -int omega_core_debug = 0; // 3: full debugging info - -int maxEQs = 100; // original 35, increased by chun -int maxGEQs = 200; // original 70, increased by chun - -int newVar = -1; -int findingImplicitEqualities = 0; -int firstCheckForRedundantEquations = 0; -int doItAgain; -int conservative = 0; -FILE *outputFile = stderr; /* printProblem writes its output to this file */ -char wildName[200][20]; -int nextWildcard = 0; -int trace = 1; -int depth = 0; -int headerLevel; -int inApproximateMode = 0; -int inStridesAllowedMode = 0; -int addingOuterEqualities = 0; -int outerColor = 0; -int reduceWithSubs = 1; -int pleaseNoEqualitiesInSimplifiedProblems = 0; -Problem *originalProblem = noProblem; -int omegaInitialized = 0; -int mayBeRed = 0; - - -// Hash table is used to hash all inequalties for all problems. It -// persists across problems for quick problem merging in case. When -// the table is filled to 1/3 full, it is flushed and the filling -// process starts all over again. -int packing[maxVars]; -int hashVersion = 0; -eqn hashMaster[hashTableSize]; -int fastLookup[maxKeys*2]; -int nextKey; - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_print.cc b/omegalib/omega/src/omega_core/oc_print.cc deleted file mode 100644 index 7934713..0000000 --- a/omegalib/omega/src/omega_core/oc_print.cc +++ /dev/null @@ -1,686 +0,0 @@ -#include <omega/omega_core/oc_i.h> - -namespace omega { - -int print_in_code_gen_style = 0; - -void Problem::initializeVariables() const { - Problem *p = (Problem *)this; - int i; - assert(!p->variablesInitialized); - for (i = p->nVars; i >= 0; i--) - p->forwardingAddress[i] = p->var[i] = i; - p->variablesInitialized = 1; -} - - -std::string Problem::print_term_to_string(const eqn *e, int c) const { - std::string s=""; - int i; - int first; - int n = nVars; - int wentFirst = -1; - first = 1; - for (i = 1; i <= n; i++) - if (c * e->coef[i] > 0) { - first = 0; - wentFirst = i; - - if (c * e->coef[i] == 1) - s+= variable(i); - else { - s += to_string(c * e->coef[i]); - if (print_in_code_gen_style) s += "*"; - s += variable(i); - } - break; - } - for (i = 1; i <= n; i++) - if (i != wentFirst && c * e->coef[i] != 0) { - if (!first && c * e->coef[i] > 0) - s += "+"; - - first = 0; - - if (c * e->coef[i] == 1) - s += variable(i); - else if (c * e->coef[i] == -1) { - s += "-"; s += variable(i); - } - else { - s += to_string(c * e->coef[i]); - if (print_in_code_gen_style) s += "*"; - s += variable(i); - } - } - if (!first && c * e->coef[0] > 0) - s += "+"; - if (first || c * e->coef[0] != 0) - s += to_string(c * e->coef[0]); - return s; -} - - -void Problem::printTerm(const eqn * e, int c) const { - std::string s = print_term_to_string(e, c); - fprintf(outputFile, "%s", s.c_str()); -} - - -void Problem::printSub(int v) const { - std::string s = print_sub_to_string(v); - fprintf(outputFile, "%s", s.c_str()); -} - - -std::string Problem::print_sub_to_string(int v) const { - std::string s; - - if (v > 0) - s = variable(v); - else - s = print_term_to_string(&SUBs[-v-1], 1); - return s; -} - - -void Problem::clearSubs() { - nSUBs = 0; - nMemories = 0; -} - - -void Problem::printEqn(const eqn *e, int test, int extra) const { - char buf[maxVars * 12 + 180]; // original buf[maxVars * 12 + 80] - - sprintEqn(buf, e, test, extra); - fprintf(outputFile, "%s", buf); -} - - -std::string Problem::printEqnToString(const eqn *e, int test, int extra) const { - char buf[maxVars * 12 + 180]; // original buf[maxVars * 12 + 80] - sprintEqn(buf, e, test, extra); - return std::string(buf); -} - - -void Problem::sprintEqn(char *str, const eqn *e, int test, int extra) const { - int i; - int first; - int n = nVars + extra; - int isLT; - - isLT = test && e->coef[0] == -1; - if (isLT) - isLT = 1; -#if 0 - if (test) { - if (DEBUG && e->touched) { - sprintf(str, "!"); - while (*str) - str++; - } - else if (DBUG && !e->touched && e->key != 0) { - sprintf(str, "%d: ", e->key); - while (*str) - str++; - } - } -#endif - if (e->color) { - sprintf(str, "["); - while (*str) - str++; - } - first = 1; - for (i = isLT; i <= n; i++) - if (e->coef[i] < 0) { - if (!first) { - sprintf(str, "+"); - while (*str) - str++; - } - else - first = 0; - if (i == 0) { - sprintf(str, coef_fmt, -e->coef[i]); - while (*str) - str++; - } - else if (e->coef[i] == -1) { - sprintf(str, "%s", variable(i)); - while (*str) - str++; - } - else { - if (print_in_code_gen_style) - sprintf(str, coef_fmt "*%s", -e->coef[i], variable(i)); - else sprintf(str, coef_fmt "%s", -e->coef[i], variable(i)); - while (*str) - str++; - } - } - if (first) { - if (isLT) { - sprintf(str, "1"); - isLT = 0; - } - else - sprintf(str, "0"); - while (*str) - str++; - } - if (test == 0) { - if (print_in_code_gen_style) sprintf(str, " == "); - else sprintf(str, " = "); - while (*str) - str++; - } - else { - if (isLT) - sprintf(str, " < "); - else - sprintf(str, " <= "); - while (*str) - str++; - } - - first = 1; - for (i = 0; i <= n; i++) - if (e->coef[i] > 0) { - if (!first) { - sprintf(str, "+"); - while (*str) - str++; - } - else - first = 0; - if (i == 0) { - sprintf(str, coef_fmt , e->coef[i]); - while (*str) - str++; - } - else if (e->coef[i] == 1) { - sprintf(str, "%s", variable(i)); - while (*str) - str++; - } - else { - if (print_in_code_gen_style) - sprintf(str, coef_fmt "*%s", e->coef[i], variable(i)); - else - sprintf(str, coef_fmt "%s", e->coef[i], variable(i)); - while (*str) - str++; - } - } - if (first) { - sprintf(str, "0"); - while (*str) - str++; - } - if (e->color) { - sprintf(str, "]"); - while (*str) - str++; - } -} - - -void Problem::printSubstitution(int s) const { - const eqn * eq = &(SUBs[s]); - assert(eq->key > 0); - fprintf(outputFile, "%s := ", orgVariable(eq->key)); - printTerm(eq, 1); -} - - -void Problem::printVars(int /*debug*/) const { - int i; - fprintf(outputFile, "variables = "); - if (safeVars > 0) - fprintf(outputFile, "("); - for (i = 1; i <= nVars; i++) { - fprintf(outputFile, "%s", variable(i)); - if (i == safeVars) - fprintf(outputFile, ")"); - if (i < nVars) - fprintf(outputFile, ", "); - } - fprintf(outputFile, "\n"); - /* - fprintf(outputFile, "forward addresses = "); - if (safeVars > 0) - fprintf(outputFile, "("); - for (i = 1; i <= nVars; i++) - { - int v = forwardingAddress[i]; - if (v > 0) fprintf(outputFile, "%s", variable(i)); - else fprintf(outputFile, "*"); - if (i == safeVars) - fprintf(outputFile, ")"); - if (i < nVars) - fprintf(outputFile, ", "); - }; - fprintf(outputFile, "\n"); - */ -} - - -void printHeader() { - int i; - for(i=0; i<headerLevel; i++) { - fprintf(outputFile, ". "); - } -} - - -void Problem::printProblem(int debug) const { - int e; - - if (!variablesInitialized) - initializeVariables(); - if (debug) { - printHeader(); - fprintf(outputFile, "#vars = %d, #EQ's = %d, #GEQ's = %d, # SUB's = %d, ofInterest = %d\n", - nVars,nEQs,nGEQs,nSUBs,varsOfInterest); - printHeader(); - printVars(debug); - } - for (e = 0; e < nEQs; e++) { - printHeader(); - printEQ(&EQs[e]); - fprintf(outputFile, "\n"); - } - for (e = 0; e < nGEQs; e++) { - printHeader(); - printGEQ(&GEQs[e]); - fprintf(outputFile, "\n"); - } - for (e = 0; e < nSUBs; e++) { - printHeader(); - printSubstitution(e); - fprintf(outputFile, "\n"); - } - - for (e = 0; e < nMemories; e++) { - int i; - printHeader(); - switch(redMemory[e].kind) { - case notRed: - fprintf(outputFile,"notRed: "); - break; - case redGEQ: - fprintf(outputFile,"Red: 0 <= "); - break; - case redLEQ: - fprintf(outputFile,"Red ??: 0 >= "); - break; - case redEQ: - fprintf(outputFile,"Red: 0 == "); - break; - case redStride: - fprintf(outputFile,"Red stride " coef_fmt ": ", redMemory[e].stride); - break; - } - fprintf(outputFile," " coef_fmt, redMemory[e].constantTerm); - for(i=0;i< redMemory[e].length; i++) - if(redMemory[e].coef[i] >= 0) - fprintf(outputFile,"+" coef_fmt "%s", redMemory[e].coef[i], orgVariable(redMemory[e].var[i])); - else - fprintf(outputFile,"-" coef_fmt "%s", -redMemory[e].coef[i], orgVariable(redMemory[e].var[i])); - fprintf(outputFile, "\n"); - } - fflush(outputFile); - - CHECK_FOR_DUPLICATE_VARIABLE_NAMES; -} - - -void Problem::printRedEquations() const { - int e; - - if (!variablesInitialized) - initializeVariables(); - printVars(1); - for (e = 0; e < nEQs; e++) { - if (EQs[e].color == EQ_RED) { - printEQ(&EQs[e]); - fprintf(outputFile, "\n"); - } - } - for (e = 0; e < nGEQs; e++) { - if (GEQs[e].color == EQ_RED) { - printGEQ(&GEQs[e]); - fprintf(outputFile, "\n"); - } - } - for (e = 0; e < nSUBs; e++) { - if (SUBs[e].color) { - printSubstitution(e); - fprintf(outputFile, "\n"); - } - } - fflush(outputFile); -} - - -int Problem::prettyPrintProblem() const { - std::string s = prettyPrintProblemToString(); - fprintf(outputFile, "%s", s.c_str()); - fflush(outputFile); - return 0; -} - - -std::string Problem::prettyPrintProblemToString() const { - std::string s=""; - int e; - int v; - int live[maxmaxGEQs]; - int v1, v2, v3; - int t, change; - int stuffPrinted = 0; - const char *connector = " && "; - - typedef enum { - none, le, lt - } partialOrderType; - - partialOrderType po[maxVars][maxVars]; - int poE[maxVars][maxVars]; - int lastLinks[maxVars]; - int firstLinks[maxVars]; - int chainLength[maxVars]; - int chain[maxVars]; - int varCount[maxVars]; - int i, m, multiprint; - - - if (!variablesInitialized) - initializeVariables(); - - if (nVars > 0) { - for (e = 0; e < nEQs; e++) { - if (stuffPrinted) - s += connector; - stuffPrinted = 1; - s += print_EQ_to_string(&EQs[e]); - } - - for (e = 0; e < nGEQs; e++) { - live[e] = true; - varCount[e] = 0; - for (v = 1; v <= nVars; v++) - if (GEQs[e].coef[v]) varCount[e]++; - } - - if (!print_in_code_gen_style) - while (1) { - for (v = 1; v <= nVars; v++) { - lastLinks[v] = firstLinks[v] = 0; - chainLength[v] = 0; - for (v2 = 1; v2 <= nVars; v2++) - po[v][v2] = none; - } - - for (e = 0; e < nGEQs; e++) - if (live[e] && varCount[e] <= 2) { - for (v = 1; v <= nVars; v++) { - if (GEQs[e].coef[v] == 1) - firstLinks[v]++; - else if (GEQs[e].coef[v] == -1) - lastLinks[v]++; - } - - v1 = nVars; - while (v1 > 0 && GEQs[e].coef[v1] == 0) - v1--; - v2 = v1 - 1; - while (v2 > 0 && GEQs[e].coef[v2] == 0) - v2--; - v3 = v2 - 1; - while (v3 > 0 && GEQs[e].coef[v3] == 0) - v3--; - - if (GEQs[e].coef[0] > 0 || GEQs[e].coef[0] < -1 - || v2 <= 0 || v3 > 0 - || GEQs[e].coef[v1] * GEQs[e].coef[v2] != -1) { - /* Not a partial order relation */ - - } - else { - if (GEQs[e].coef[v1] == 1) { - v3 = v2; - v2 = v1; - v1 = v3; - } - /* relation is v1 <= v2 or v1 < v2 */ - po[v1][v2] = ((GEQs[e].coef[0] == 0) ? le : lt); - poE[v1][v2] = e; - } - } - for (v = 1; v <= nVars; v++) - chainLength[v] = lastLinks[v]; - - /* - * printf("\n\nPartial order:\n"); printf(" "); for (v1 = 1; v1 <= nVars; v1++) - * printf("%7s",variable(v1)); printf("\n"); for (v1 = 1; v1 <= nVars; v1++) { printf("%6s: - * ",variable(v1)); for (v2 = 1; v2 <= nVars; v2++) switch (po[v1][v2]) { case none: printf(" "); - * break; case le: printf(" <= "); break; case lt: printf(" < "); break; } printf("\n"); } - */ - - - /* Just in case nVars <= 0 */ - change = false; - for (t = 0; t < nVars; t++) { - change = false; - for (v1 = 1; v1 <= nVars; v1++) - for (v2 = 1; v2 <= nVars; v2++) - if (po[v1][v2] != none && - chainLength[v1] <= chainLength[v2]) { - chainLength[v1] = chainLength[v2] + 1; - change = true; - } - } - - if (change) { - /* caught in cycle */ - -#if 0 - printf("\n\nPartial order:\n"); printf(" "); - for (v1 = 1; v1 <= nVars; v1++) printf("%7s",variable(v1)); printf("\n"); - for (v1 = 1; v1 <= nVars; v1++) { - printf("%6s: ",variable(v1)); - for (v2 = 1; v2 <= nVars; v2++) switch (po[v1][v2]) { - case none: printf(" "); break; - case le: printf(" <= "); break; - case lt: printf(" < "); break; - } - printf("\n"); - } - - printProblem(1); -#endif - break; - } - - for (v1 = 1; v1 <= nVars; v1++) - if (chainLength[v1] == 0) - firstLinks[v1] = 0; - - v = 1; - for (v1 = 2; v1 <= nVars; v1++) - if (chainLength[v1] + firstLinks[v1] > chainLength[v] + firstLinks[v]) - v = v1; - - if (chainLength[v] + firstLinks[v] == 0) - break; - - if (stuffPrinted) - s += connector; - stuffPrinted = 1; - /* chain starts at v */ - /* print firstLinks */ - { - coef_t tmp; - int first; - first = 1; - for (e = 0; e < nGEQs; e++) - if (live[e] && GEQs[e].coef[v] == 1 && varCount[e] <= 2) { - if (!first) - s += ", "; - tmp = GEQs[e].coef[v]; - ((Problem *)this)-> - GEQs[e].coef[v] = 0; - s += print_term_to_string(&GEQs[e], -1); - ((Problem *)this)-> - GEQs[e].coef[v] = tmp; - live[e] = false; - first = 0; - } - if (!first) - s += " <= "; - } - - - /* find chain */ - chain[0] = v; - m = 1; - while (1) { - /* print chain */ - for (v2 = 1; v2 <= nVars; v2++) - if (po[v][v2] && chainLength[v] == 1 + chainLength[v2]) - break; - if (v2 > nVars) - break; - chain[m++] = v2; - v = v2; - } - - s += variable(chain[0]); - - multiprint = 0; - for (i = 1; i < m; i++) { - v = chain[i - 1]; - v2 = chain[i]; - if (po[v][v2] == le) - s += " <= "; - else - s += " < "; - s += variable(v2); - live[poE[v][v2]] = false; - if (!multiprint && i < m - 1) - for (v3 = 1; v3 <= nVars; v3++) { - if (v == v3 || v2 == v3) - continue; - if (po[v][v2] != po[v][v3]) - continue; - if (po[v2][chain[i + 1]] != po[v3][chain[i + 1]]) - continue; - s += ","; s += variable(v3); - live[poE[v][v3]] = false; - live[poE[v3][chain[i + 1]]] = false; - multiprint = 1; - } - else - multiprint = 0; - } - - v = chain[m - 1]; - /* print lastLinks */ - { - coef_t tmp; - int first; - first = 1; - for (e = 0; e < nGEQs; e++) - if (live[e] && GEQs[e].coef[v] == -1 && varCount[e] <= 2) { - if (!first) - s += ", "; - else - s += " <= "; - tmp = GEQs[e].coef[v]; - ((Problem *)this)-> - GEQs[e].coef[v] = 0; - s += print_term_to_string(&GEQs[e], 1); - ((Problem *)this)-> - GEQs[e].coef[v] = tmp; - live[e] = false; - first = 0; - } - } - } - - - for (e = 0; e < nGEQs; e++) - if (live[e]) { - if (stuffPrinted) - s += connector; - stuffPrinted = 1; - s += print_GEQ_to_string(&GEQs[e]); - } - - for (e = 0; e < nSUBs; e++) { - const eqn * eq = &SUBs[e]; - if (stuffPrinted) - s += connector; - stuffPrinted = 1; - if (eq->key > 0) { - s += orgVariable(eq->key); s += " := "; - } - else { - s += "#"; s += to_string(eq->key); s += " := "; - } - s += print_term_to_string(eq, 1); - } - } - return s; -} - - -int Problem::prettyPrintRedEquations() const { - int e, stuffPrinted = 0; - const char *connector = " && "; - - if (!variablesInitialized) - initializeVariables(); - - for (e = 0; e < nEQs; e++) { - if (EQs[e].color == EQ_RED) { - if (stuffPrinted) - fprintf(outputFile, "%s", connector); - stuffPrinted = 1; - ((Problem *)this)-> - EQs[e].color = EQ_BLACK; - printEQ(&EQs[e]); - ((Problem *)this)-> - EQs[e].color = EQ_RED; - } - } - for (e = 0; e < nGEQs; e++) { - if (GEQs[e].color == EQ_RED) { - if (stuffPrinted) - fprintf(outputFile, "%s", connector); - stuffPrinted = 1; - ((Problem *)this)-> - GEQs[e].color = EQ_BLACK; - printGEQ(&GEQs[e]); - ((Problem *)this)-> - GEQs[e].color = EQ_RED; - } - } - for (e = 0; e < nSUBs; e++) { - if (SUBs[e].color) { - if (stuffPrinted) - fprintf(outputFile, "%s", connector); - stuffPrinted = 1; - printSubstitution(e); - } - } - fflush(outputFile); - - return 0; -} - -} diff --git a/omegalib/omega/src/omega_core/oc_problems.cc b/omegalib/omega/src/omega_core/oc_problems.cc deleted file mode 100644 index 8b6e04c..0000000 --- a/omegalib/omega/src/omega_core/oc_problems.cc +++ /dev/null @@ -1,198 +0,0 @@ -#include <omega/omega_core/oc_i.h> -#include <basic/omega_error.h> - -namespace omega { - -Problem::~Problem() { - delete[] EQs; - delete[] GEQs; -} - - -void check_number_EQs(int n) { - if (n < 0) { - fprintf(stderr,"ERROR: nEQs < 0??\n"); - exit(1); - } - - if (n > maxmaxEQs) { - // clear global variables - inApproximateMode = 0; - outerColor = 0; - - throw presburger_error("\nERROR:\n" - "An attempt was made to set the number of available equality constraints to " + to_string(n) + ".\n" - "The maximum number of equality constraints in a conjunction is " + to_string(maxmaxEQs) + ".\n" - "This limit can be changed by redefining maxmaxEQs in oc.h and recompiling.\n\n"); - - // fprintf(stderr, "\nERROR:\n"); - // fprintf(stderr, "An attempt was made to set the number of available equality constraints to %d.\n", n); - // fprintf(stderr, "The maximum number of equality constraints in a conjunction is %d.\n", maxmaxEQs); - // fprintf(stderr, "This limit can be changed by redefining maxmaxEQs in oc.h and recompiling.\n\n"); - // exit(2); - } -} - -void check_number_GEQs(int n) { - if (n < 0) { - fprintf(stderr,"ERROR: nGEQs < 0??\n"); - exit(1); - } - - if (n > maxmaxGEQs) { - // clear global variables - inApproximateMode = 0; - outerColor = 0; - - throw presburger_error("\nERROR:\n" - "An attempt was made to set the number of available inequality constraints to " + to_string(n) +".\n" - "The maximum number of inequality constraints in a conjunction is " + to_string(maxmaxGEQs) +".\n" - "This limit can be changed by redefining maxmaxGEQs in oc.h and recompiling.\n\n"); - - // fprintf(stderr, "\nERROR:\n"); - // fprintf(stderr, "An attempt was made to set the number of available inequality constraints to %d.\n", n); - // fprintf(stderr, "The maximum number of inequality constraints in a conjunction is %d.\n", maxmaxGEQs); - // fprintf(stderr, "This limit can be changed by redefining maxmaxGEQs in oc.h and recompiling.\n\n"); - // exit(2); - } -} - - -void check_number_EQs_GEQs(int e, int g) { - check_number_EQs(e); - check_number_GEQs(g); -} - - -Problem::Problem(int in_eqs, int in_geqs) { - check_number_EQs_GEQs(in_eqs, in_geqs); - allocEQs = padEQs(in_eqs); - allocGEQs = padGEQs(in_geqs); - assert(allocEQs > 0 && allocGEQs > 0); - EQs = new eqn[allocEQs]; - GEQs = new eqn[allocGEQs]; - nVars = 0; - hashVersion = omega::hashVersion; - variablesInitialized = 0; - variablesFreed = 0; - varsOfInterest = 0; - safeVars = 0; - nEQs = 0; - nGEQs = 0; - nSUBs = 0; - nMemories = 0; - isTemporary = false; -} - -Problem::Problem(const Problem & p2) { - allocEQs = padEQs(p2.nEQs); // Don't over-allocate; p2 might have too many! - allocGEQs = padGEQs(p2.nGEQs); - assert(allocEQs > 0 && allocGEQs > 0); - EQs = new eqn[allocEQs]; - GEQs = new eqn[allocGEQs]; - int e, i; - nVars = p2.nVars; - hashVersion = p2.hashVersion; - variablesInitialized = p2.variablesInitialized; - variablesFreed = p2.variablesFreed; - varsOfInterest = p2.varsOfInterest; - safeVars = p2.safeVars; - nEQs = p2.nEQs; - isTemporary = p2.isTemporary; - //nSUBs = 0; - for (e = p2.nEQs - 1; e >= 0; e--) - eqnncpy(&(EQs[e]), &(p2.EQs[e]), p2.nVars); - nGEQs = p2.nGEQs; - for (e = p2.nGEQs - 1; e >= 0; e--) - eqnncpy(&(GEQs[e]), &(p2.GEQs[e]), p2.nVars); - for (i = 0; i <= p2.nVars; i++) - var[i] = p2.var[i]; - for (i = 0; i <= maxVars; i++) - forwardingAddress[i] = p2.forwardingAddress[i]; - //nMemories = 0; - get_var_name = p2.get_var_name; - getVarNameArgs = p2.getVarNameArgs; -} - -Problem & Problem::operator=(const Problem & p2) { - if (this != &p2) { - if(allocEQs < p2.nEQs) { - delete[] EQs; - allocEQs = padEQs(p2.nEQs); - EQs = new eqn[allocEQs]; - } - if(allocGEQs < p2.nGEQs) { - delete[] GEQs; - allocGEQs = padGEQs(p2.nGEQs); - GEQs = new eqn[allocGEQs]; - } - int e, i; - nVars = p2.nVars; - hashVersion = p2.hashVersion; - variablesInitialized = p2.variablesInitialized; - variablesFreed = p2.variablesFreed; - varsOfInterest = p2.varsOfInterest; - safeVars = p2.safeVars; - nEQs = p2.nEQs; - isTemporary = p2.isTemporary; - //nSUBs = 0; - for (e = p2.nEQs - 1; e >= 0; e--) - eqnncpy(&(EQs[e]), &(p2.EQs[e]), p2.nVars); - nGEQs = p2.nGEQs; - for (e = p2.nGEQs - 1; e >= 0; e--) - eqnncpy(&(GEQs[e]), &(p2.GEQs[e]), p2.nVars); - for (i = 0; i <= p2.nVars; i++) - var[i] = p2.var[i]; - for (i = 0; i <= maxVars; i++) - forwardingAddress[i] = p2.forwardingAddress[i]; - //nMemories = 0; - get_var_name = p2.get_var_name; - getVarNameArgs = p2.getVarNameArgs; - } - return *this; -} - - -void Problem::zeroVariable(int i) { - int e; - for (e = nGEQs - 1; e >= 0; e--) GEQs[e].coef[i] = 0; - for (e = nEQs - 1; e >= 0; e--) EQs[e].coef[i] = 0; - for (e = nSUBs - 1; e >= 0; e--) SUBs[e].coef[i] = 0; -} - -/* Functions for allocating EQ's and GEQ's */ - -int Problem::newGEQ() { - if (++nGEQs > allocGEQs) { - check_number_GEQs(nGEQs); - allocGEQs = padGEQs(allocGEQs, nGEQs); - assert(allocGEQs >= nGEQs); - eqn *new_geqs = new eqn[allocGEQs]; - for (int e = nGEQs - 2; e >= 0; e--) - eqnncpy(&(new_geqs[e]), &(GEQs[e]), nVars); - delete[] GEQs; - GEQs = new_geqs; - } -// problem->GEQs[nGEQs-1].color = black; -// eqnnzero(&problem->GEQs[nGEQs-1],problem->nVars); - return nGEQs-1; -} - -int Problem::newEQ() { - if (++nEQs > allocEQs) { - check_number_EQs(nEQs); - allocEQs = padEQs(allocEQs, nEQs); - assert(allocEQs >= nEQs); - eqn *new_eqs = new eqn[allocEQs]; - for (int e = nEQs - 2; e >= 0; e--) - eqnncpy(&(new_eqs[e]), &(EQs[e]), nVars); - delete[] EQs; - EQs = new_eqs; - } -// Could do this here, but some calls to newEQ do a copy instead of a zero; -// problem->EQs[nEQs-1].color = black; -// eqnnzero(&problem->EQs[nEQs-1],problem->nVars); - return nEQs-1; -} - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_query.cc b/omegalib/omega/src/omega_core/oc_query.cc deleted file mode 100644 index 528b297..0000000 --- a/omegalib/omega/src/omega_core/oc_query.cc +++ /dev/null @@ -1,478 +0,0 @@ -#include <omega/omega_core/oc_i.h> - -namespace omega { - -void Problem::unprotectVariable( int v) { - int e, j, i; - coef_t t; - i = forwardingAddress[v]; - if (i < 0) { - i = -1 - i; - nSUBs--; - if (i < nSUBs) { - eqnncpy(&SUBs[i], &SUBs[nSUBs], nVars); - forwardingAddress[SUBs[i].key] = -i - 1; - } - } - else { - int bringToLife[maxVars]; - int comingBack = 0; - int e2; - for (e = nSUBs - 1; e >= 0; e--) - if ((bringToLife[e] = (SUBs[e].coef[i] != 0))) - comingBack++; - - for (e2 = nSUBs - 1; e2 >= 0; e2--) - if (bringToLife[e2]) { - - nVars++; - safeVars++; - if (safeVars < nVars) { - for (e = nGEQs - 1; e >= 0; e--) { - GEQs[e].coef[nVars] = GEQs[e].coef[safeVars]; - GEQs[e].coef[safeVars] = 0; - } - for (e = nEQs - 1; e >= 0; e--) { - EQs[e].coef[nVars] = EQs[e].coef[safeVars]; - EQs[e].coef[safeVars] = 0; - } - for (e = nSUBs - 1; e >= 0; e--) { - SUBs[e].coef[nVars] = SUBs[e].coef[safeVars]; - SUBs[e].coef[safeVars] = 0; - } - var[nVars] = var[safeVars]; - forwardingAddress[var[nVars]] = nVars; - } - else { - for (e = nGEQs - 1; e >= 0; e--) { - GEQs[e].coef[safeVars] = 0; - } - for (e = nEQs - 1; e >= 0; e--) { - EQs[e].coef[safeVars] = 0; - } - for (e = nSUBs - 1; e >= 0; e--) { - SUBs[e].coef[safeVars] = 0; - } - } - - var[safeVars] = SUBs[e2].key; - forwardingAddress[SUBs[e2].key] = safeVars; - - int neweq = newEQ(); - eqnncpy(&(EQs[neweq]), &(SUBs[e2]), nVars); - EQs[neweq].coef[safeVars] = -1; - if (e2 < nSUBs - 1) - eqnncpy(&(SUBs[e2]), &(SUBs[nSUBs - 1]), nVars); - nSUBs--; - } - - if (i < safeVars) { - j = safeVars; - for (e = nSUBs - 1; e >= 0; e--) { - t = SUBs[e].coef[j]; - SUBs[e].coef[j] = SUBs[e].coef[i]; - SUBs[e].coef[i] = t; - } - for (e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[j] != GEQs[e].coef[i]) { - GEQs[e].touched = true; - t = GEQs[e].coef[j]; - GEQs[e].coef[j] = GEQs[e].coef[i]; - GEQs[e].coef[i] = t; - } - for (e = nEQs - 1; e >= 0; e--) { - t = EQs[e].coef[j]; - EQs[e].coef[j] = EQs[e].coef[i]; - EQs[e].coef[i] = t; - } - { - short t; - t = var[j]; - var[j] = var[i]; - var[i] = t; - } - forwardingAddress[var[i]] = i; - forwardingAddress[var[j]] = j; - } - safeVars--; - } - chainUnprotect(); -} - -void Problem::constrainVariableSign( int color, int i, int sign) { - int nV = nVars; - int e, k, j; - - k = forwardingAddress[i]; - if (k < 0) { - k = -1 - k; - - if (sign != 0) { - e = newGEQ(); - eqnncpy(&GEQs[e], &SUBs[k], nVars); - for (j = 0; j <= nV; j++) - GEQs[e].coef[j] *= sign; - GEQs[e].coef[0]--; - GEQs[e].touched = 1; - GEQs[e].color = color; - } - else { - e = newEQ(); - eqnncpy(&EQs[e], &SUBs[k], nVars); - EQs[e].color = color; - } - } - else if (sign != 0) { - e = newGEQ(); - eqnnzero(&GEQs[e], nVars); - GEQs[e].coef[k] = sign; - GEQs[e].coef[0] = -1; - GEQs[e].touched = 1; - GEQs[e].color = color; - } - else { - e = newEQ(); - eqnnzero(&EQs[e], nVars); - EQs[e].coef[k] = 1; - EQs[e].color = color; - } - /* - unprotectVariable(i); - return (simplifyProblem(0,1,0)); - */ -} - -void Problem::constrainVariableValue( int color, int i, int value) { - int e, k; - - k = forwardingAddress[i]; - if (k < 0) { - k = -1 - k; - - e = newEQ(); - eqnncpy(&EQs[e], &SUBs[k], nVars); - EQs[e].coef[0] -= value; - - } - else { - e = newEQ(); - eqnnzero(&EQs[e], nVars); - EQs[e].coef[k] = 1; - EQs[e].coef[0] = -value; - } - EQs[e].color = color; -} - -// Analyze v1-v2 -void Problem:: query_difference(int v1, int v2, coef_t &lowerBound, coef_t &upperBound, bool &guaranteed) { - int nV = nVars; - int e,i,e2; - - coef_t lb1,ub1; - coef_t lb2,ub2; - assert(nSUBs == 0); - lowerBound = negInfinity; - lb1 = lb2 = negInfinity; - upperBound = posInfinity; - ub1 = ub2 = posInfinity; - guaranteed = true; - for (e = nEQs - 1; e >= 0; e--) { - if (EQs[e].coef[v1] == 0 && EQs[e].coef[v2] == 0) - continue; - for(i=nV;i>0;i--) - if (EQs[e].coef[i] && i!=v1 && i != v2) { - break; - } - if (i != 0) { - if (i > safeVars) { - // check to see if this variable appears anywhere else - for(e2 = nEQs-1; e2>=0;e2--) if (e != e2 && EQs[e2].coef[i]) break; - if (e2 < 0) - for(e2 = nGEQs-1; e2>=0;e2--) if (e != e2 && GEQs[e2].coef[i]) break; - if (e2 < 0) - for(e2 = nSUBs-1; e2>=0;e2--) if (e != e2 && SUBs[e2].coef[i]) break; - if (e2 >= 0) guaranteed = false; - } - else guaranteed = false; - continue; - } - if (EQs[e].coef[v1]*EQs[e].coef[v2] == -1) { - // found exact difference - coef_t d = - EQs[e].coef[v1] * EQs[e].coef[0]; - set_max(lowerBound, d); - set_min(upperBound, d); - guaranteed =true; - return; - } - else if (EQs[e].coef[v1] == 0) - lb2 = ub2 = -EQs[e].coef[0]/ EQs[e].coef[v2]; - else if (EQs[e].coef[v2] == 0) - lb1 = ub1 = -EQs[e].coef[0]/ EQs[e].coef[v1]; - else guaranteed = false; - } - - bool isDead[maxmaxGEQs]; - - for (e = nGEQs - 1; e >= 0; e--) isDead[e] = false; - int tryAgain = 1; - while (tryAgain) { - tryAgain = 0; - for (i = nVars; i > 0;i--) - if (i!= v1 && i != v2) { - for (e = nGEQs - 1; e >= 0; e--) - if (!isDead[e] && GEQs[e].coef[i]) - break; - if (e < 0) - e2 = e; - else if (GEQs[e].coef[i] > 0) { - for (e2 = e - 1; e2 >= 0; e2--) - if (!isDead[e2] && GEQs[e2].coef[i] < 0) - break; - } - else { - for (e2 = e - 1; e2 >= 0; e2--) - if (!isDead[e2] && GEQs[e2].coef[i] > 0) - break; - } - if (e2 < 0) { - int e3; - for (e3 = nSUBs - 1; e3 >= 0; e3--) - if (SUBs[e3].coef[i]) - break; - if (e3 >= 0) - continue; - for (e3 = nEQs - 1; e3 >= 0; e3--) - if (EQs[e3].coef[i]) - break; - if (e3 >= 0) - continue; - if (e >= 0) { - isDead[e] = true; - for (e--; e >= 0; e--) - if (GEQs[e].coef[i]) isDead[e] = true; - } - } - } - } - - for (e = nGEQs - 1; e >= 0; e--) - if (!isDead[e]) { - if (GEQs[e].coef[v1] == 0 && GEQs[e].coef[v2] == 0) - continue; - for(i=nV;i>0;i--) - if (GEQs[e].coef[i] && i!=v1 && i != v2) - break; - if (i != 0) { - guaranteed = false; - continue; - } - if (GEQs[e].coef[v1]*GEQs[e].coef[v2] == -1) { - // found relative difference - if (GEQs[e].coef[v1] == 1) { - // v1 - v2 + c >= 0 - set_max(lowerBound, - GEQs[e].coef[0]); - } - else { - // v2 - v1 + c >= 0 - // c >= v1-v2 - set_min(upperBound, GEQs[e].coef[0]); - } - } - else if (GEQs[e].coef[v1] == 0 && GEQs[e].coef[v2] > 0) - lb2 = -GEQs[e].coef[0]/ GEQs[e].coef[v2]; - else if (GEQs[e].coef[v1] == 0 && GEQs[e].coef[v2] < 0) - ub2 = -GEQs[e].coef[0]/ GEQs[e].coef[v2]; - else if (GEQs[e].coef[v2] == 0 && GEQs[e].coef[v1] > 0) - lb1 = -GEQs[e].coef[0]/ GEQs[e].coef[v1]; - else if (GEQs[e].coef[v2] == 0 && GEQs[e].coef[v1] < 0) - ub1 = -GEQs[e].coef[0]/ GEQs[e].coef[v1]; - else guaranteed = false; - } - - // ub1-lb2 >= v1-v2 >= lb1-ub2 - - if (negInfinity < lb2 && ub1 < posInfinity) set_min(upperBound, ub1-lb2); - if (negInfinity < lb1 && ub2 < posInfinity) set_max(lowerBound, lb1-ub2); - if (lowerBound >= upperBound) guaranteed = 1; -} - - -int Problem::queryVariable(int i, coef_t *lowerBound, coef_t *upperBound) { - int nV = nVars; - int e, j; - int isSimple; - int coupled = false; - for(j=1;j<=safeVars;j++) - if (var[j] > 0) - assert(forwardingAddress[var[j]] == j); - - assert(i > 0); - i = forwardingAddress[i]; - assert(i != 0); - - (*lowerBound) = negInfinity; - (*upperBound) = posInfinity; - - if (i < 0) { - int easy = true; - i = -i - 1; - for (j = 1; j <= nV; j++) - if (SUBs[i].coef[j] != 0) - easy = false; - if (easy) { - *upperBound = *lowerBound = SUBs[i].coef[0]; - return (false); - } - return (true); - } - - for (e = nSUBs - 1; e >= 0; e--) - if (SUBs[e].coef[i] != 0) - coupled = true; - - for (e = nEQs - 1; e >= 0; e--) - if (EQs[e].coef[i] != 0) { - isSimple = true; - for (j = 1; j <= nV; j++) - if (i != j && EQs[e].coef[j] != 0) { - isSimple = false; - coupled = true; - break; - } - if (!isSimple) - continue; - else { - *lowerBound = *upperBound = -EQs[e].coef[i] * EQs[e].coef[0]; - return (false); - } - } - for (e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[i] != 0) { - if (GEQs[e].key == i) { - set_max(*lowerBound, -GEQs[e].coef[0]); - } - else if (GEQs[e].key == -i) { - set_min(*upperBound, GEQs[e].coef[0]); - } - else - coupled = true; - } - return (coupled); -} - -int Problem::query_variable_bounds(int i, coef_t *l, coef_t *u) { - int coupled; - *l = negInfinity; - *u = posInfinity; - coupled = queryVariable(i, l, u); - if (!coupled || (nVars == 1 && forwardingAddress[i] == 1)) - return 0; - if (abs(forwardingAddress[i]) == 1 && nVars + nSUBs == 2 && nEQs + nSUBs == 1) { - int couldBeZero; - queryCoupledVariable(i, l, u, &couldBeZero, negInfinity, posInfinity); - return 0; - } - return 1; -} - -void Problem::queryCoupledVariable(int i, coef_t *l, coef_t *u, int *couldBeZero, coef_t lowerBound, coef_t upperBound) { - int e; - coef_t b1, b2; - const eqn *eqn; - coef_t sign; - int v; - - if (abs(forwardingAddress[i]) != 1 || nVars + nSUBs != 2 || nEQs + nSUBs != 1) { - fprintf(outputFile, "queryCoupledVariablecalled with bad parameters\n"); - printProblem(); - exit(2); - } - - if (forwardingAddress[i] == -1) { - eqn = &SUBs[0]; - sign = 1; - v = 1; - } - else { - eqn = &EQs[0]; - sign = -eqn->coef[1]; - v = 2; - } - - /* Variable i is defined in terms of variable v */ - - for (e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[v] != 0) { - if (GEQs[e].coef[v] == 1) { - set_max(lowerBound, -GEQs[e].coef[0]); - } - else { - set_min(upperBound, GEQs[e].coef[0]); - } - } - /* lowerBound and upperBound are bounds on the value of v */ - - if (lowerBound > upperBound) { - *l = posInfinity; - *u = negInfinity; - *couldBeZero = 0; - return; - } - if (lowerBound == negInfinity) { - if (eqn->coef[v] > 0) - b1 = sign * negInfinity; - else - b1 = -sign * negInfinity; - } - else - b1 = sign * (eqn->coef[0] + eqn->coef[v] * lowerBound); - if (upperBound == posInfinity) { - if (eqn->coef[v] > 0) - b2 = sign * posInfinity; - else - b2 = -sign * posInfinity; - } - else - b2 = sign * (eqn->coef[0] + eqn->coef[v] * upperBound); - - /* b1 and b2 are bounds on the value of i (don't know which is upper bound) */ - if (b1 <= b2) { - set_max(*l, b1); - set_min(*u, b2); - } - else { - set_max(*l, b2); - set_min(*u, b1); - } - *couldBeZero = *l <= 0 && 0 <= *u && int_mod(eqn->coef[0], abs(eqn->coef[v])) == 0; -} - - -int Problem::queryVariableSigns(int i, int dd_lt, int dd_eq, int dd_gt, coef_t lowerBound, coef_t upperBound, bool *distKnown, coef_t *dist) { - int result; - coef_t l, u; - int couldBeZero; - - l = negInfinity; - u = posInfinity; - - queryVariable(i, &l, &u); - queryCoupledVariable(i, &l, &u, &couldBeZero, lowerBound, upperBound); - result = 0; - if (l < 0) - result |= dd_gt; - if (u > 0) - result |= dd_lt; - if (couldBeZero) - result |= dd_eq; - if (l == u) { - *distKnown = 1; - *dist = l; - } - else { - *distKnown = 0; - } - return (result); -} - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_quick_kill.cc b/omegalib/omega/src/omega_core/oc_quick_kill.cc deleted file mode 100644 index 1b988d4..0000000 --- a/omegalib/omega/src/omega_core/oc_quick_kill.cc +++ /dev/null @@ -1,775 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Quick inequality elimination. - - Notes: - - History: - 03/31/09 Use BoolSet, Chun Chen -*****************************************************************************/ - -#include <omega/omega_core/oc_i.h> -#include <vector> -#include <algorithm> -#include <basic/BoolSet.h> - -namespace omega { - -int Problem::combineToTighten() { - int effort = min(12+5*(nVars-safeVars),23); - - if (DBUG) { - fprintf(outputFile, "\nin combineToTighten (%d,%d):\n",effort,nGEQs); - printProblem(); - fprintf(outputFile, "\n"); - } - if (nGEQs > effort) { - if (TRACE) { - fprintf(outputFile, "too complicated to tighten\n"); - } - return 1; - } - - for(int e = 1; e < nGEQs; e++) { - for(int e2 = 0; e2 < e; e2++) { - coef_t g = 0; - - bool has_wildcard = false; - bool has_wildcard2 = false; - for (int i = nVars; i > safeVars; i--) { - coef_t a = GEQs[e].coef[i]; - coef_t b = GEQs[e2].coef[i]; - g = gcd(g, abs(a+b)); - if (a != 0) - has_wildcard = true; - if (b != 0) - has_wildcard2 = true; - } - - coef_t c, c2; - if ((has_wildcard && !has_wildcard2) || (!has_wildcard && has_wildcard2)) - c = 0; - else - c = -1; - for (int i = safeVars; i >= 1; i--) { - coef_t a = GEQs[e].coef[i]; - coef_t b = GEQs[e2].coef[i]; - if (a != 0 || b != 0) { - g = gcd(g, abs(a+b)); - - if (c < 0) { - if (g == 1) - break; - } - else if ((a>0 && b<0) || (a<0 && b>0)) { - if (c == 0) { - try { - coef_t prod = lcm(abs(a), abs(b)); - c = prod/abs(a); - c2 = prod/abs(b); - } - catch (std::overflow_error) { - c = -1; - } - } - else { - if (c*a+c2*b != 0) - c = -1; - } - } - else { - c = -1; - } - } - } - - bool done_unit_combine = false; - if (g > 1 && (GEQs[e].coef[0] + GEQs[e2].coef[0]) % g != 0) { - int e3 = newGEQ(); - for(int i = nVars; i >= 1; i--) { - GEQs[e3].coef[i] = (GEQs[e].coef[i] + GEQs[e2].coef[i])/g; - } - GEQs[e3].coef[0] = int_div(GEQs[e].coef[0] + GEQs[e2].coef[0], g); - GEQs[e3].color = GEQs[e].color || GEQs[e2].color; - GEQs[e3].touched = 1; - if (DBUG) { - fprintf(outputFile, "Combined "); - printGEQ(&GEQs[e]); - fprintf(outputFile,"\n and "); - printGEQ(&GEQs[e2]); - fprintf(outputFile,"\n to get #%d: ",e3); - printGEQ(&GEQs[e3]); - fprintf(outputFile,"\n\n"); - } - - done_unit_combine = true; - if (nGEQs > effort+5 || nGEQs > maxmaxGEQs-10) goto doneCombining; - } - - if (c > 0 && !(c == 1 && c2 == 1 && done_unit_combine)) { - bool still_has_wildcard = false; - coef_t p[nVars-safeVars]; - for (int i = nVars; i > safeVars; i--) { - p[i-safeVars-1] = c * GEQs[e].coef[i] + c2 * GEQs[e2].coef[i]; - if (p[i-safeVars-1] != 0) - still_has_wildcard = true; - } - if (still_has_wildcard) { - int e3 = newGEQ(); - for(int i = nVars; i > safeVars; i--) - GEQs[e3].coef[i] = p[i-safeVars-1]; - for (int i = safeVars; i > 0; i--) - GEQs[e3].coef[i] = 0; - GEQs[e3].coef[0] = c * GEQs[e].coef[0] + c2 * GEQs[e2].coef[0]; - GEQs[e3].color = GEQs[e].color || GEQs[e2].color; - GEQs[e3].touched = 1; - if (DBUG) { - fprintf(outputFile, "Additionally combined "); - printGEQ(&GEQs[e]); - fprintf(outputFile,"\n and "); - printGEQ(&GEQs[e2]); - fprintf(outputFile,"\n to get #%d: ",e3); - printGEQ(&GEQs[e3]); - fprintf(outputFile,"\n\n"); - } - - if (nGEQs > effort+5 || nGEQs > maxmaxGEQs-10) goto doneCombining; - } - } - } - } - -doneCombining: - if (normalize() == normalize_false) return 0; - while (nEQs) { - if (!solveEQ()) return 0; - if (normalize() == normalize_false) return 0; - } - return 1; -} - - -void Problem::noteEssential(int onlyWildcards) { - for (int e = nGEQs - 1; e >= 0; e--) { - GEQs[e].essential = 0; - GEQs[e].varCount = 0; - } - if (onlyWildcards) { - for (int e = nGEQs - 1; e >= 0; e--) { - GEQs[e].essential = 1; - for (int i = nVars; i > safeVars; i--) - if (GEQs[e].coef[i] < -1 || GEQs[e].coef[i] > 1) { - GEQs[e].essential = 0; - break; - } - } - } - for (int i = nVars; i >= 1; i--) { - int onlyLB = -1; - int onlyUB = -1; - for (int e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[i] > 0) { - GEQs[e].varCount ++; - if (onlyLB == -1) onlyLB = e; - else onlyLB = -2; - } - else if (GEQs[e].coef[i] < 0) { - GEQs[e].varCount ++; - if (onlyUB == -1) onlyUB = e; - else onlyUB = -2; - } - if (onlyUB >= 0) { - if (DBUG) { - fprintf(outputFile,"only UB: "); - printGEQ(&GEQs[onlyUB]); - fprintf(outputFile,"\n"); - } - GEQs[onlyUB].essential = 1; - } - if (onlyLB >= 0) { - if (DBUG) { - fprintf(outputFile,"only LB: "); - printGEQ(&GEQs[onlyLB]); - fprintf(outputFile,"\n"); - } - GEQs[onlyLB].essential = 1; - } - } - for (int e = nGEQs - 1; e >= 0; e--) - if (!GEQs[e].essential && GEQs[e].varCount > 1) { - int i1,i2,i3; - for (i1 = nVars; i1 >= 1; i1--) if (GEQs[e].coef[i1]) break; - for (i2 = i1-1; i2 >= 1; i2--) if (GEQs[e].coef[i2]) break; - for (i3 = i2-1; i3 >= 1; i3--) if (GEQs[e].coef[i3]) break; - assert(i2 >= 1); - int e2; - for (e2 = nGEQs - 1; e2 >= 0; e2--) - if (e!=e2) { - coef_t crossProduct; - crossProduct = GEQs[e].coef[i1]*GEQs[e2].coef[i1]; - crossProduct += GEQs[e].coef[i2]*GEQs[e2].coef[i2]; - for (int i = i3; i >= 1; i--) - if (GEQs[e2].coef[i]) - crossProduct += GEQs[e].coef[i]*GEQs[e2].coef[i]; - if (crossProduct > 0) { - if (DBUG) fprintf(outputFile,"Cross product of %d and %d is " coef_fmt "\n", e, e2, crossProduct); - break; - } - } - if (e2 < 0) GEQs[e].essential = 1; - } - if (DBUG) { - fprintf(outputFile,"Computed essential equations\n"); - fprintf(outputFile,"essential equations:\n"); - for (int e = 0; e < nGEQs; e++) - if (GEQs[e].essential) { - printGEQ(&GEQs[e]); - fprintf(outputFile,"\n"); - } - fprintf(outputFile,"potentially redundant equations:\n"); - for (int e = 0; e < nGEQs; e++) - if (!GEQs[e].essential) { - printGEQ(&GEQs[e]); - fprintf(outputFile,"\n"); - } - } -} - - -int Problem::findDifference(int e, int &v1, int &v2) { - // if 1 returned, eqn E is of form v1 -coef >= v2 - for(v1=1;v1<=nVars;v1++) - if (GEQs[e].coef[v1]) break; - for(v2=v1+1;v2<=nVars;v2++) - if (GEQs[e].coef[v2]) break; - if (v2 > nVars) { - if (GEQs[e].coef[v1] == -1) { - v2 = v1; - v1 = 0; - return 1; - } - if (GEQs[e].coef[v1] == 1) { - v2 = 0; - return 1; - } - return 0; - } - if (GEQs[e].coef[v1] * GEQs[e].coef[v2] != -1) return 0; - if (GEQs[e].coef[v1] < 0) std::swap(v1,v2); - return 1; -} - - -namespace { - struct succListStruct { - int num; - int notEssential; - int var[maxVars]; - coef_t diff[maxVars]; - int eqn[maxVars]; - }; -} - - -int Problem::chainKill(int color, int onlyWildcards) { - int v1,v2,e; - int essentialPred[maxVars]; - int redundant[maxmaxGEQs]; - int inChain[maxVars]; - int goodStartingPoint[maxVars]; - int tryToEliminate[maxmaxGEQs]; - int triedDoubleKill = 0; - - succListStruct succ[maxVars]; - -restart: - - int anyToKill = 0; - int anyKilled = 0; - int canHandle = 0; - - for(v1=0;v1<=nVars;v1++) { - succ[v1].num = 0; - succ[v1].notEssential = 0; - goodStartingPoint[v1] = 0; - inChain[v1] = -1; - essentialPred[v1] = 0; - } - - int essentialEquations = 0; - for (e = 0; e < nGEQs; e++) { - redundant[e] = 0; - tryToEliminate[e] = !GEQs[e].essential; - if (GEQs[e].essential) essentialEquations++; - if (color && !GEQs[e].color) tryToEliminate[e] = 0; - } - if (essentialEquations == nGEQs) return 0; - if (2*essentialEquations < nVars) return 1; - - for (e = 0; e < nGEQs; e++) - if (tryToEliminate[e] && GEQs[e].varCount <= 2 && findDifference(e,v1,v2)) { - assert(v1 == 0 || GEQs[e].coef[v1] == 1); - assert(v2 == 0 || GEQs[e].coef[v2] == -1); - succ[v2].notEssential++; - int s = succ[v2].num++; - succ[v2].eqn[s] = e; - succ[v2].var[s] = v1; - succ[v2].diff[s] = -GEQs[e].coef[0]; - goodStartingPoint[v2] = 1; - anyToKill++; - canHandle++; - } - if (!anyToKill) { - return canHandle < nGEQs; - } - for (e = 0; e < nGEQs; e++) - if (!tryToEliminate[e] && GEQs[e].varCount <= 2 && findDifference(e,v1,v2)) { - assert(v1 == 0 || GEQs[e].coef[v1] == 1); - assert(v2 == 0 || GEQs[e].coef[v2] == -1); - int s = succ[v2].num++; - essentialPred[v1]++; - succ[v2].eqn[s] = e; - succ[v2].var[s] = v1; - succ[v2].diff[s] = -GEQs[e].coef[0]; - canHandle++; - } - - - if (DBUG) { - int s; - fprintf(outputFile,"In chainkill: [\n"); - for(v1 = 0;v1<=nVars;v1++) { - fprintf(outputFile,"#%d <= %s: ",essentialPred[v1],variable(v1)); - for(s=0;s<succ[v1].notEssential;s++) - fprintf(outputFile," %s(" coef_fmt ") ",variable(succ[v1].var[s]), succ[v1].diff[s]); - for(;s<succ[v1].num;s++) - fprintf(outputFile," %s[" coef_fmt "] ",variable(succ[v1].var[s]), succ[v1].diff[s]); - fprintf(outputFile,"\n"); - } - } - - for(;v1<=nVars;v1++) - if (succ[v1].num == 1 && succ[v1].notEssential == 1) { - succ[v1].notEssential--; - essentialPred[succ[v1].var[succ[v1].notEssential]]++; - } - - if (DBUG) fprintf(outputFile,"Trying quick double kill:\n"); - int s1a,s1b,s2; - int v3; - for(v1 = 0;v1<=nVars;v1++) - for(s1a=0;s1a<succ[v1].notEssential;s1a++) { - v3 = succ[v1].var[s1a]; - for(s1b=0;s1b<succ[v1].num;s1b++) - if (s1a != s1b) { - v2 = succ[v1].var[s1b]; - for(s2=0;s2<succ[v2].num;s2++) - if (succ[v2].var[s2] == v3 && succ[v1].diff[s1b] + succ[v2].diff[s2] >= succ[v1].diff[s1a]) { - if (DBUG) { - fprintf(outputFile,"quick double kill: "); - printGEQ(&GEQs[succ[v1].eqn[s1a]]); - fprintf(outputFile,"\n"); - } - redundant[succ[v1].eqn[s1a]] = 1; - anyKilled++; - anyToKill--; - goto nextVictim; - } - } - nextVictim: v1 = v1; - } - if (anyKilled) { - for (e = nGEQs-1; e >= 0;e--) - if (redundant[e]) { - if (DBUG) { - fprintf(outputFile,"Deleting "); - printGEQ(&GEQs[e]); - fprintf(outputFile,"\n"); - } - deleteGEQ(e); - } - - if (!anyToKill) return canHandle < nGEQs; - noteEssential(onlyWildcards); - triedDoubleKill = 1; - goto restart; - } - - for(v1 = 0;v1<=nVars;v1++) - if (succ[v1].num == succ[v1].notEssential && succ[v1].notEssential > 0) { - succ[v1].notEssential--; - essentialPred[succ[v1].var[succ[v1].notEssential]]++; - } - - while (1) { - int chainLength; - int chain[maxVars]; - coef_t distance[maxVars]; - // pick a place to start - for(v1 = 0;v1<=nVars;v1++) - if (essentialPred[v1] == 0 && succ[v1].num > succ[v1].notEssential) - break; - if (v1 > nVars) - for(v1 = 0;v1<=nVars;v1++) - if (goodStartingPoint[v1] && succ[v1].num > succ[v1].notEssential) - break; - if (v1 > nVars) break; - - chainLength = 1; - chain[0] = v1; - distance[0] = 0; - inChain[v1] = 0; - int s; - - while (succ[v1].num > succ[v1].notEssential) { - s = succ[v1].num-1; - if (inChain[succ[v1].var[s]] >= 0) { - // Found cycle, don't do anything with them yet - break; - } - succ[v1].num = s; - - distance[chainLength]= distance[chainLength-1] + succ[v1].diff[s]; - v1 = chain[chainLength] = succ[v1].var[s]; - essentialPred[v1]--; - assert(essentialPred[v1] >= 0); - inChain[v1] = chainLength; - chainLength++; - } - - - int c; - if (DBUG) { - fprintf(outputFile,"Found chain: \n"); - for (c = 0; c < chainLength; c++) - fprintf(outputFile,"%s:" coef_fmt " ",variable(chain[c]), distance[c]); - fprintf(outputFile,"\n"); - } - - - for (c = 0; c < chainLength; c++) { - v1 = chain[c]; - for(s=0;s<succ[v1].notEssential;s++) { - if (DBUG) - fprintf(outputFile,"checking for %s + " coef_fmt " <= %s \n", variable(v1), succ[v1].diff[s], variable(succ[v1].var[s])); - if (inChain[succ[v1].var[s]] > c+1) { - if (DBUG) - fprintf(outputFile,"%s + " coef_fmt " <= %s is in chain\n", variable(v1), distance[inChain[succ[v1].var[s]]]- distance[c], variable(succ[v1].var[s])); - if ( distance[inChain[succ[v1].var[s]]]- distance[c] >= succ[v1].diff[s]) { - if (DBUG) - fprintf(outputFile,"%s + " coef_fmt " <= %s is redundant\n", variable(v1),succ[v1].diff[s], variable(succ[v1].var[s])); - redundant[succ[v1].eqn[s]] = 1; - } - } - } - } - for (c = 0; c < chainLength; c++) - inChain[chain[c]] = -1; - } - - for (e = nGEQs-1; e >= 0;e--) - if (redundant[e]) { - if (DBUG) { - fprintf(outputFile,"Deleting "); - printGEQ(&GEQs[e]); - fprintf(outputFile,"\n"); - } - deleteGEQ(e); - anyKilled = 1; - } - - if (anyKilled) noteEssential(onlyWildcards); - - if (anyKilled && DBUG) { - fprintf(outputFile,"\nResult:\n"); - printProblem(); - } - if (DBUG) { - fprintf(outputFile,"] end chainkill\n"); - printProblem(); - } - return canHandle < nGEQs; -} - - -namespace { - struct varCountStruct { - int e; - int safeVarCount; - int wildVarCount; - varCountStruct(int e_, int count1_, int count2_) { - e = e_; - safeVarCount = count1_; - wildVarCount = count2_; } - }; - bool operator<(const varCountStruct &a, const varCountStruct &b) { - if (a.wildVarCount < b.wildVarCount) - return true; - else if (a.wildVarCount > b.wildVarCount) - return false; - else - return a.safeVarCount < b.safeVarCount; - } -} - - -// -// Deduct redundant inequalities by combination of any two inequalities. -// Return value: 0 (no solution), -// 1 (nothing killed), -// 2 (some inequality killed). -// -int Problem::quickKill(int onlyWildcards, bool desperate) { - if (!onlyWildcards && !combineToTighten()) - return 0; - noteEssential(onlyWildcards); - int moreToDo = chainKill(0, onlyWildcards); - -#ifdef NDEBUG - if (!moreToDo) return 1; -#endif - - - if (!desperate && nGEQs > 256) { // original 60, increased by chun - if (TRACE) { - fprintf(outputFile, "%d inequalities are too complicated to quick kill\n", nGEQs); - } - return 1; - } - - if (DBUG) { - fprintf(outputFile, "in eliminate Redudant:\n"); - printProblem(); - } - - int isDead[nGEQs]; - std::vector<varCountStruct> killOrder; - std::vector<BoolSet<> > P(nGEQs, BoolSet<>(nVars)), Z(nGEQs, BoolSet<>(nVars)), N(nGEQs, BoolSet<>(nVars)); - BoolSet<> PP, PZ, PN; // possible Positives, possible zeros & possible negatives - - for (int e = nGEQs - 1; e >= 0; e--) { - isDead[e] = 0; - int safeVarCount = 0; - int wildVarCount = 0; - for (int i = nVars; i >= 1; i--) { - if (GEQs[e].coef[i] == 0) - Z[e].set(i-1); - else { - if (i > safeVars) - wildVarCount++; - else - safeVarCount++; - if (GEQs[e].coef[i] < 0) - N[e].set(i-1); - else - P[e].set(i-1); - } - } - - if (!GEQs[e].essential || wildVarCount > 0) - killOrder.push_back(varCountStruct(e, safeVarCount, wildVarCount)); - } - - sort(killOrder.begin(), killOrder.end()); - - if (DEBUG) { - fprintf(outputFile,"Prefered kill order:\n"); - for (int e3I = killOrder.size()-1; e3I >= 0; e3I--) { - fprintf(outputFile,"%2d: ",nGEQs-1-e3I); - printGEQ(&GEQs[killOrder[e3I].e]); - fprintf(outputFile,"\n"); - } - } - - int e3U = killOrder.size()-1; - while (e3U >= 0) { - // each round of elimination is for inequalities of same complexity and rounds are at descending complexity order - int e3L = e3U-1; - for(; e3L >= 0; e3L--) - if (killOrder[e3L].safeVarCount+killOrder[e3L].wildVarCount != killOrder[e3U].safeVarCount + killOrder[e3U].wildVarCount) - break; - - // check if e3 can be eliminated from combination of e1 and e2 - for (int e1 = 0; e1 < nGEQs; e1++) - if (!isDead[e1]) - for (int e2 = e1+1; e2 < nGEQs; e2++) - if (!isDead[e2]) { - coef_t alpha = 0; - int p, q; - for (p = nVars; p > 1; p--) - for (q = p - 1; q > 0; q--) { - try { - alpha = check_mul(GEQs[e1].coef[p], GEQs[e2].coef[q]) - check_mul(GEQs[e2].coef[p], GEQs[e1].coef[q]); - } - catch (std::overflow_error) { - continue; - } - if (alpha != 0) - goto foundPQ; - } - continue; - - foundPQ: - PZ = (Z[e1] & Z[e2]) | (P[e1] & N[e2]) | (N[e1] & P[e2]); - PP = P[e1] | P[e2]; - PN = N[e1] | N[e2]; - if (DEBUG) { - fprintf(outputFile,"Considering combination of "); - printGEQ(&(GEQs[e1])); - fprintf(outputFile," and "); - printGEQ(&(GEQs[e2])); - fprintf(outputFile,"\n"); - } - - for (int e3I = e3U; e3I > e3L; e3I--) { - int e3 = killOrder[e3I].e; - if (!isDead[e3] && e3 != e1 && e3 != e2) - try { - coef_t alpha1, alpha2, alpha3; - - if (!PZ.imply(Z[e3])) - goto nextE3; - - alpha1 = check_mul(GEQs[e2].coef[q], GEQs[e3].coef[p]) - check_mul(GEQs[e2].coef[p], GEQs[e3].coef[q]); - alpha2 = -(check_mul(GEQs[e1].coef[q], GEQs[e3].coef[p]) - check_mul(GEQs[e1].coef[p], GEQs[e3].coef[q])); - alpha3 = alpha; - - if (alpha1 < 0) { - alpha1 = -alpha1; - alpha2 = -alpha2; - alpha3 = -alpha3; - } - if (alpha1 == 0 || alpha2 <= 0) - goto nextE3; - - { - coef_t g = gcd(gcd(alpha1, alpha2), abs(alpha3)); - alpha1 /= g; - alpha2 /= g; - alpha3 /= g; - } - - if (DEBUG) { - fprintf(outputFile, coef_fmt "e1 + " coef_fmt "e2 = " coef_fmt "e3: ",alpha1,alpha2,alpha3); - printGEQ(&(GEQs[e3])); - fprintf(outputFile,"\n"); - } - - if (alpha3 > 0) { // trying to prove e3 is redundant - if (!GEQs[e3].color && (GEQs[e1].color || GEQs[e2].color)) { - goto nextE3; - } - if (!PP.imply(P[e3]) | !PN.imply(N[e3])) - goto nextE3; - - // verify alpha1*v1+alpha2*v2 = alpha3*v3 - for (int k = nVars; k >= 1; k--) - if (check_mul(alpha3, GEQs[e3].coef[k]) != check_mul(alpha1, GEQs[e1].coef[k]) + check_mul(alpha2, GEQs[e2].coef[k])) - goto nextE3; - - coef_t c = check_mul(alpha1, GEQs[e1].coef[0]) + check_mul(alpha2, GEQs[e2].coef[0]); - if (c < check_mul(alpha3, (GEQs[e3].coef[0] + 1))) { - if (DBUG) { - fprintf(outputFile, "found redundant inequality\n"); - fprintf(outputFile, "alpha1, alpha2, alpha3 = " coef_fmt "," coef_fmt "," coef_fmt "\n", alpha1, alpha2, alpha3); - printGEQ(&(GEQs[e1])); - fprintf(outputFile, "\n"); - printGEQ(&(GEQs[e2])); - fprintf(outputFile, "\n=> "); - printGEQ(&(GEQs[e3])); - fprintf(outputFile, "\n\n"); - assert(moreToDo); - } - - isDead[e3] = 1; - } - } - else { // trying to prove e3 <= 0 or e3 = 0 - if (!PN.imply(P[e3]) | !PP.imply(N[e3])) - goto nextE3; - - // verify alpha1*v1+alpha2*v2 = alpha3*v3 - for (int k = nVars; k >= 1; k--) - if (check_mul(alpha3, GEQs[e3].coef[k]) != check_mul(alpha1, GEQs[e1].coef[k]) + check_mul(alpha2, GEQs[e2].coef[k])) - goto nextE3; - - if (DEBUG) { - fprintf(outputFile,"All but constant term checked\n"); - } - coef_t c = check_mul(alpha1, GEQs[e1].coef[0]) + check_mul(alpha2, GEQs[e2].coef[0]); - if (DEBUG) { - fprintf(outputFile,"All but constant term checked\n"); - fprintf(outputFile,"Constant term is " coef_fmt " vs " coef_fmt "\n", - alpha3*GEQs[e3].coef[0], - alpha3*(GEQs[e3].coef[0]-1)); - } - if (c < check_mul(alpha3, (GEQs[e3].coef[0]))) { - // we just proved e3 < 0, so no solutions exist - if (DBUG) { - fprintf(outputFile, "found implied over tight inequality\n"); - fprintf(outputFile, "alpha1, alpha2, alpha3 = " coef_fmt "," coef_fmt "," coef_fmt "\n", alpha1, alpha2, -alpha3); - printGEQ(&(GEQs[e1])); - fprintf(outputFile, "\n"); - printGEQ(&(GEQs[e2])); - fprintf(outputFile, "\n=> not "); - printGEQ(&(GEQs[e3])); - fprintf(outputFile, "\n\n"); - } - return 0; - } - else if (!GEQs[e3].color && (GEQs[e1].color || GEQs[e2].color)) { - goto nextE3; - } - else if (c < check_mul(alpha3, (GEQs[e3].coef[0] - 1))) { - // we just proved e3 <= 0, so e3 = 0 - if (DBUG) { - fprintf(outputFile, "found implied tight inequality\n"); - fprintf(outputFile, "alpha1, alpha2, alpha3 = " coef_fmt "," coef_fmt "," coef_fmt "\n", alpha1, alpha2, -alpha3); - printGEQ(&(GEQs[e1])); - fprintf(outputFile, "\n"); - printGEQ(&(GEQs[e2])); - fprintf(outputFile, "\n=> inverse "); - printGEQ(&(GEQs[e3])); - fprintf(outputFile, "\n\n"); - } - int neweq = newEQ(); - eqnncpy(&EQs[neweq], &GEQs[e3], nVars); - addingEqualityConstraint(neweq); - isDead[e3] = 1; - } - } - nextE3:; - } - catch (std::overflow_error) { - continue; - } - } - } - - e3U = e3L; - } - - bool anything_killed = false; - for (int e = nGEQs - 1; e >= 0; e--) { - if (isDead[e]) { - anything_killed = true; - deleteGEQ(e); - } - } - - if (DBUG) { - fprintf(outputFile,"\nResult:\n"); - printProblem(); - } - - if (anything_killed) - return 2; - else - return 1; -} - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_simple.cc b/omegalib/omega/src/omega_core/oc_simple.cc deleted file mode 100644 index 0e492db..0000000 --- a/omegalib/omega/src/omega_core/oc_simple.cc +++ /dev/null @@ -1,1373 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Support functions for solving a problem. - - Notes: - - History: - 10/13/08 Complete back substitution process, Chun Chen. - 05/28/09 Extend normalize process to handle redundancy involving - wilddcards, Chun Chen -*****************************************************************************/ - -#include <omega/omega_core/oc_i.h> -#include <basic/BoolSet.h> -#include <algorithm> -#include <vector> - -namespace omega { - -int checkIfSingleVar(eqn* e, int i) { - for (; i > 0; i--) - if (e->coef[i]) { - i--; - break; - } - for (; i > 0; i--) - if (e->coef[i]) - break; - return (i == 0); -} - - -int singleVarGEQ(eqn* e) { - return !e->touched && e->key != 0 && -maxVars <= e->key && e->key <= maxVars; -} - - -void checkVars(int nVars) { - if (nVars > maxVars) { - fprintf(stderr, "\nERROR:\n"); - fprintf(stderr, "An attempt was made to create a conjunction with %d variables.\n", nVars); - fprintf(stderr, "The current limit on variables in a single conjunction is %d.\n", maxVars); - fprintf(stderr, "This limit can be changed by changing the #define of maxVars in oc.h.\n\n"); - exit(2); - } -} - - -void Problem::difficulty(int &numberNZs, coef_t &maxMinAbsCoef, coef_t &sumMinAbsCoef) const { - numberNZs=0; - maxMinAbsCoef=0; - sumMinAbsCoef=0; - for (int e = 0; e < nGEQs; e++) { - coef_t maxCoef = 0; - for(int i = 1;i <= nVars;i++) - if (GEQs[e].coef[i]!=0) { - coef_t a = abs(GEQs[e].coef[i]); - maxCoef = max(maxCoef,a); - numberNZs++; - } - coef_t nextCoef = 0; - for(int i = 1;i <= nVars;i++) - if (GEQs[e].coef[i]!=0) { - coef_t a = abs(GEQs[e].coef[i]); - if (a < maxCoef) nextCoef = max(nextCoef,a); - else if (a == maxCoef) maxCoef = 0x7fffffff; - } - maxMinAbsCoef = max(maxMinAbsCoef,nextCoef); - sumMinAbsCoef += nextCoef; - } - - for (int e = 0; e < nEQs; e++) { - coef_t maxCoef = 0; - for(int i = 1;i <= nVars;i++) - if (EQs[e].coef[i]!=0) { - coef_t a = abs(EQs[e].coef[i]); - maxCoef = max(maxCoef,a); - numberNZs++; - } - coef_t nextCoef = 0; - for(int i = 1;i <= nVars;i++) - if (EQs[e].coef[i]!=0) { - coef_t a = abs(EQs[e].coef[i]); - if (a < maxCoef) nextCoef = max(nextCoef,a); - else if (a == maxCoef) maxCoef = 0x7fffffff; - } - maxMinAbsCoef = max(maxMinAbsCoef,nextCoef); - sumMinAbsCoef += nextCoef; - } -} - -int Problem::countRedGEQs() const { - int result = 0; - for (int e = 0; e < nGEQs; e++) - if (GEQs[e].color == EQ_RED) result++; - return result; -} - -int Problem::countRedEQs() const { - int result = 0; - for (int e = 0; e < nEQs; e++) - if (EQs[e].color == EQ_RED) result++; - return result; -} - -int Problem::countRedEquations() const { - int result = 0; - for (int e = 0; e < nEQs; e++) - if (EQs[e].color == EQ_RED) { - int i; - for (i = nVars; i > 0; i--) if (EQs[e].coef[i]) break; - if (i == 0 && EQs[e].coef[0] != 0) return 0; - else result+=2; - } - for (int e = 0; e < nGEQs; e++) - if (GEQs[e].color == EQ_RED) result+=1; - for (int e = 0; e < nMemories; e++) - switch(redMemory[e].kind ) { - case redEQ: - case redStride: - e++; - case redLEQ: - case redGEQ: - e++; - case notRed: - ; /* avoid warning about notRed not handled */ - } - return result; -} - -void Problem::deleteBlack() { - int RedVar[maxVars]; - for(int i = safeVars+1;i <= nVars;i++) RedVar[i] = 0; - - assert(nSUBs == 0); - - for (int e = nEQs-1; e >= 0; e--) - if (EQs[e].color != EQ_RED) { - eqnncpy(&EQs[e],&EQs[nEQs-1], nVars); - nEQs--; - } - else - for(int i = safeVars+1;i <= nVars;i++) - if (EQs[e].coef[i]) RedVar[i] = 1; - - for (int e = nGEQs-1; e >= 0; e--) - if (GEQs[e].color != EQ_RED) { - eqnncpy(&GEQs[e],&GEQs[nGEQs-1], nVars); - nGEQs--; - } - else - for(int i = safeVars+1;i <= nVars;i++) - if (GEQs[e].coef[i]) RedVar[i] = 1; - - assert(nSUBs == 0); - - for(int i = nVars; i > safeVars;i--) { - if (!RedVar[i]) deleteVariable(i); - } -} - - -void Problem::deleteRed() { - int BlackVar[maxVars]; - for(int i = safeVars+1;i <= nVars;i++) BlackVar[i] = 0; - - assert(nSUBs == 0); - for (int e = nEQs-1; e >=0; e--) - if (EQs[e].color) { - eqnncpy(&EQs[e],&EQs[nEQs-1], nVars); - nEQs--; - } - else - for(int i = safeVars+1;i <= nVars;i++) - if (EQs[e].coef[i]) BlackVar[i] = 1; - - for (int e = nGEQs-1; e >=0; e--) - if (GEQs[e].color) { - eqnncpy(&GEQs[e],&GEQs[nGEQs-1], nVars); - nGEQs--; - } - else - for(int i = safeVars+1;i <= nVars;i++) - if (GEQs[e].coef[i]) BlackVar[i] = 1; - - assert(nSUBs == 0); - - for(int i = nVars; i> safeVars;i--) { - if (!BlackVar[i]) deleteVariable(i); - } -} - - -void Problem::turnRedBlack() { - for (int e = nEQs-1; e >= 0; e--) EQs[e].color = 0; - for (int e = nGEQs-1; e >= 0; e--) GEQs[e].color = 0; -} - - -void Problem::useWildNames() { - for(int i = safeVars+1; i <= nVars; i++) nameWildcard(i); -} - - -void negateCoefficients(eqn* eqn, int nVars) { - for (int i = nVars; i >= 0; i--) - eqn-> coef[i] = -eqn->coef[i]; - eqn->touched = true; -} - - -void Problem::negateGEQ(int e) { - negateCoefficients(&GEQs[e],nVars); - GEQs[e].coef[0]--; -} - - -void Problem:: deleteVariable(int i) { - if (i < safeVars) { - int j = safeVars; - for (int e = nGEQs - 1; e >= 0; e--) { - GEQs[e].touched = true; - GEQs[e].coef[i] = GEQs[e].coef[j]; - GEQs[e].coef[j] = GEQs[e].coef[nVars]; - } - for (int e = nEQs - 1; e >= 0; e--) { - EQs[e].coef[i] = EQs[e].coef[j]; - EQs[e].coef[j] = EQs[e].coef[nVars]; - } - for (int e = nSUBs - 1; e >= 0; e--) { - SUBs[e].coef[i] = SUBs[e].coef[j]; - SUBs[e].coef[j] = SUBs[e].coef[nVars]; - } - var[i] = var[j]; - var[j] = var[nVars]; - } - else if (i < nVars) { - for (int e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[nVars]) { - GEQs[e].coef[i] = GEQs[e].coef[nVars]; - GEQs[e].touched = true; - } - for (int e = nEQs - 1; e >= 0; e--) - EQs[e].coef[i] = EQs[e].coef[nVars]; - for (int e = nSUBs - 1; e >= 0; e--) - SUBs[e].coef[i] = SUBs[e].coef[nVars]; - var[i] = var[nVars]; - } - if (i <= safeVars) - safeVars--; - nVars--; -} - - -void Problem::setInternals() { - if (!variablesInitialized) { - initializeVariables(); - } - - var[0] = 0; - nextWildcard = 0; - for(int i = 1;i <= nVars;i++) - if (var[i] < 0) - var[i] = --nextWildcard; - - assert(nextWildcard >= -maxWildcards); - - CHECK_FOR_DUPLICATE_VARIABLE_NAMES; - - int v = nSUBs; - for(int i = 1;i <= safeVars;i++) if (var[i] > 0) v++; - varsOfInterest = v; - - if (nextKey * 3 > maxKeys) { - omega::hashVersion++; - nextKey = maxVars + 1; - for (int e = nGEQs - 1; e >= 0; e--) - GEQs[e].touched = true; - for (int i = 0; i < hashTableSize; i++) - hashMaster[i].touched = -1; - hashVersion = omega::hashVersion; - } - else if (hashVersion != omega::hashVersion) { - for (int e = nGEQs - 1; e >= 0; e--) - GEQs[e].touched = true; - hashVersion = omega::hashVersion; - } -} - - -void Problem::setExternals() { - for (int i = 1; i <= safeVars; i++) - forwardingAddress[var[i]] = i; - for (int i = 0; i < nSUBs; i++) - forwardingAddress[SUBs[i].key] = -i - 1; -} - - -void setOutputFile(FILE * file) { - /* sets the file to which printProblem should send its output to "file" */ - - outputFile = file; -} - - -void setPrintLevel(int level) { - /* Sets the nber of points printed before constraints in printProblem */ - headerLevel = level; -} - - -void Problem::putVariablesInStandardOrder() { - for(int i = 1;i <= safeVars;i++) { - int b = i; - for(int j=i+1;j<=safeVars;j++) { - if (var[b] < var[j]) b = j; - } - if (b != i) swapVars(i,b); - } -} - - -void Problem::nameWildcard(int i) { - int j; - do { - --nextWildcard; - if (nextWildcard < -maxWildcards) - nextWildcard = -1; - var[i] = nextWildcard; - for(j = nVars; j > 0;j--) if (i!=j && var[j] == nextWildcard) break; - } while (j != 0); -} - - -int Problem::protectWildcard(int i) { - assert (i > safeVars); - if (i != safeVars+1) swapVars(i,safeVars+1); - safeVars++; - nameWildcard(safeVars); - return safeVars; -} - - -int Problem::addNewProtectedWildcard() { - int i = ++safeVars; - nVars++; - if (nVars != i) { - for (int e = nGEQs - 1; e >= 0; e--) { - if (GEQs[e].coef[i] != 0) - GEQs[e].touched = true; - GEQs[e].coef[nVars] = GEQs[e].coef[i]; - } - for (int e = nEQs - 1; e >= 0; e--) { - EQs[e].coef[nVars] = EQs[e].coef[i]; - } - for (int e = nSUBs - 1; e >= 0; e--) { - SUBs[e].coef[nVars] = SUBs[e].coef[i]; - } - var[nVars] = var[i]; - } - for (int e = nGEQs - 1; e >= 0; e--) - GEQs[e].coef[i] = 0; - for (int e = nEQs - 1; e >= 0; e--) - EQs[e].coef[i] = 0; - for (int e = nSUBs - 1; e >= 0; e--) - SUBs[e].coef[i] = 0; - nameWildcard(i); - return (i); -} - - -int Problem::addNewUnprotectedWildcard() { - int i = ++nVars; - for (int e = nGEQs - 1; e >= 0; e--) GEQs[e].coef[i] = 0; - for (int e = nEQs - 1; e >= 0; e--) EQs[e].coef[i] = 0; - for (int e = nSUBs - 1; e >= 0; e--) SUBs[e].coef[i] = 0; - nameWildcard(i); - return i; -} - - -void Problem::cleanoutWildcards() { - bool renormalize = false; - - // substituting wildcard equality - for (int e = nEQs-1; e >= 0; e--) { - for (int i = nVars; i >= safeVars+1; i--) - if (EQs[e].coef[i] != 0) { - coef_t c = EQs[e].coef[i]; - coef_t a = abs(c); - - bool preserveThisConstraint = true; - for (int e2 = nEQs-1; e2 >= 0; e2--) - if (e2 != e && EQs[e2].coef[i] != 0 && EQs[e2].color >= EQs[e].color) { - preserveThisConstraint = preserveThisConstraint && (gcd(a,abs(EQs[e2].coef[i])) != 1); - coef_t k = lcm(a, abs(EQs[e2].coef[i])); - coef_t coef1 = (EQs[e2].coef[i]>0?1:-1) * k / c; - coef_t coef2 = k / abs(EQs[e2].coef[i]); - for (int j = nVars; j >= 0; j--) - EQs[e2].coef[j] = EQs[e2].coef[j] * coef2 - EQs[e].coef[j] * coef1; - - coef_t g = 0; - for (int j = nVars; j >= 0; j--) { - g = gcd(abs(EQs[e2].coef[j]), g); - if (g == 1) - break; - } - if (g != 0 && g != 1) - for (int j = nVars; j >= 0; j--) - EQs[e2].coef[j] /= g; - } - - for (int e2 = nGEQs-1; e2 >= 0; e2--) - if (GEQs[e2].coef[i] != 0 && GEQs[e2].color >= EQs[e].color) { - coef_t k = lcm(a, abs(GEQs[e2].coef[i])); - coef_t coef1 = (GEQs[e2].coef[i]>0?1:-1) * k / c; - coef_t coef2 = k / abs(GEQs[e2].coef[i]); - for (int j = nVars; j >= 0; j--) - GEQs[e2].coef[j] = GEQs[e2].coef[j] * coef2 - EQs[e].coef[j] * coef1; - - GEQs[e2].touched = 1; - renormalize = true; - } - - for (int e2 = nSUBs-1; e2 >= 0; e2--) - if (SUBs[e2].coef[i] != 0 && SUBs[e2].color >= EQs[e].color) { - coef_t k = lcm(a, abs(SUBs[e2].coef[i])); - coef_t coef1 = (SUBs[e2].coef[i]>0?1:-1) * k / c; - coef_t coef2 = k / abs(SUBs[e2].coef[i]); - for (int j = nVars; j >= 0; j--) - SUBs[e2].coef[j] = SUBs[e2].coef[j] * coef2 - EQs[e].coef[j] * coef1; - - coef_t g = 0; - for (int j = nVars; j >= 0; j--) { - g = gcd(abs(SUBs[e2].coef[j]), g); - if (g == 1) - break; - } - if (g != 0 && g != 1) - for (int j = nVars; j >= 0; j--) - SUBs[e2].coef[j] /= g; - } - - // remove redundent wildcard equality - if (!preserveThisConstraint) { - if (e < nEQs-1) - eqnncpy (&EQs[e], &EQs[nEQs-1], nVars); - nEQs--; - deleteVariable(i); - } - - break; - } - } - - // remove multi-wildcard equality in approximation mode - if (inApproximateMode) - for (int e = nEQs-1; e >= 0; e--) - for (int i = nVars; i >= safeVars+1; i--) - if (EQs[e].coef[i] != 0) { - int j = i-1; - for (; j >= safeVars+1; j--) - if (EQs[e].coef[j] != 0) - break; - - if (j != safeVars) { - if (e < nEQs-1) - eqnncpy (&EQs[e], &EQs[nEQs-1], nVars); - nEQs--; - } - - break; - } - - if (renormalize) - normalize(); -} - - -void Problem:: check() const { -#ifndef NDEBUG - int v = nSUBs; - checkVars(nVars+1); - for(int i = 1; i <= safeVars; i++) if (var[i] > 0) v++; - assert(v == varsOfInterest); - for(int e = 0; e < nGEQs; e++) assert(GEQs[e].touched || GEQs[e].key != 0); - if(!mayBeRed) { - for(int e = 0; e < nEQs; e++) assert(!EQs[e].color); - for(int e = 0; e < nGEQs; e++) assert(!GEQs[e].color); - } - else - for(int i = safeVars+1; i <= nVars; i++) { - int isBlack = 0; - int isRed = 0; - for(int e = 0; e < nEQs; e++) - if (EQs[e].coef[i]) { - if (EQs[e].color) isRed = 1; - else isBlack = 1; - } - for(int e = 0; e < nGEQs; e++) - if (GEQs[e].coef[i]) { - if (GEQs[e].color) isRed = 1; - else isBlack = 1; - } - if (isBlack && isRed && 0) { - fprintf(outputFile,"Mixed Red and Black variable:\n"); - printProblem(); - } - } -#endif -} - - -void Problem::rememberRedConstraint(eqn *e, redType type, coef_t stride) { - // Check if this is really a stride constraint - if (type == redEQ && newVar == nVars && e->coef[newVar]) { - type = redStride; - stride = e->coef[newVar]; - } - // else for(int i = safeVars+1; i <= nVars; i++) assert(!e->coef[i]); // outdated -- by chun 10/30/2008 - - assert(type != notRed); - assert(type == redStride || stride == 0); - - if (TRACE) { - fprintf(outputFile,"being asked to remember red constraint:\n"); - switch(type) { - case notRed: fprintf(outputFile,"notRed: "); - break; - case redGEQ: fprintf(outputFile,"Red: 0 <= "); - break; - case redLEQ: fprintf(outputFile,"Red: 0 >= "); - break; - case redEQ: fprintf(outputFile,"Red: 0 == "); - break; - case redStride: fprintf(outputFile,"Red stride " coef_fmt ": ",stride); - break; - } - printTerm(e,1); - fprintf(outputFile,"\n"); - printProblem(); - fprintf(outputFile,"----\n"); - } - - // Convert redLEQ to redGEQ - eqn mem; - eqnncpy(&mem,e, nVars); - e = &mem; - if (type == redLEQ) { - for(int i = 0; i <= safeVars; i++) - e->coef[i] = -e->coef[i]; - type = redGEQ; - } - - // Prepare coefficient array for red constraint - bool has_wildcard = false; - coef_t coef[varsOfInterest-nextWildcard+1]; - for (int i = 0; i <= varsOfInterest-nextWildcard; i++) - coef[i] = 0; - for (int i = 0; i <= safeVars; i++) { - if (var[i] < 0) { - if (e->coef[i] != 0) { - coef[varsOfInterest-var[i]] = e->coef[i]; - has_wildcard = true; - } - } - else - coef[var[i]] = e->coef[i]; - } - - // Sophisticated back substituion for wildcards, use Gaussian elimination - // as a fallback if no simple equations available. -- by chun 10/13/2008 - if (has_wildcard) { - // Find substitutions involving wildcard - coef_t *repl_subs[nSUBs]; - int num_wild_in_repl_subs[nSUBs]; - int num_repl_subs = 0; - for (int i = 0; i < nSUBs; i++) { - int t = 0; - for (int j = 1; j <= safeVars; j++) { - if (var[j] < 0 && SUBs[i].coef[j] != 0) - t++; - } - if (t > 0) { - repl_subs[num_repl_subs] = new coef_t[varsOfInterest-nextWildcard+1]; - for (int j = 0; j <= varsOfInterest-nextWildcard; j++) - repl_subs[num_repl_subs][j] = 0; - - for (int k = 0; k <= safeVars; k++) - repl_subs[num_repl_subs][(var[k]<0)?varsOfInterest-var[k]:var[k]] = SUBs[i].coef[k]; - repl_subs[num_repl_subs][SUBs[i].key] = -1; - num_wild_in_repl_subs[num_repl_subs] = t; - num_repl_subs++; - } - } - - int wild_solved[-nextWildcard+1]; - bool has_unsolved = false; - for (int i = 1; i <= -nextWildcard; i++) { - int minimum_wild = 0; - int pos; - for (int j = 0; j < num_repl_subs; j++) - if (repl_subs[j][varsOfInterest+i] != 0 && (minimum_wild == 0 || num_wild_in_repl_subs[j] < minimum_wild)) { - minimum_wild = num_wild_in_repl_subs[j]; - pos = j; - } - - if (minimum_wild == 0) { - wild_solved[i] = -1; - if (coef[varsOfInterest+i] != 0) { - fprintf(outputFile,"No feasible back substitutions available\n"); - printProblem(); - exit(1); - } - } - else if (minimum_wild == 1) - wild_solved[i] = pos; - else { - wild_solved[i] = -1; - if (coef[varsOfInterest+i] != 0) - has_unsolved = true; - } - } - - // Gaussian elimination - while (has_unsolved) { - for (int i = 0; i < num_repl_subs; i++) - if (num_wild_in_repl_subs[i] > 1) { - for (int j = 1; j <= -nextWildcard; j++) { - if (repl_subs[i][varsOfInterest+j] != 0 && wild_solved[j] >= 0) { - int s = wild_solved[j]; - coef_t l = lcm(abs(repl_subs[i][varsOfInterest+j]), abs(repl_subs[s][varsOfInterest+j])); - coef_t scale_1 = l/abs(repl_subs[i][varsOfInterest+j]); - coef_t scale_2 = l/abs(repl_subs[s][varsOfInterest+j]); - int sign = ((repl_subs[i][varsOfInterest+j]>0)?1:-1) * ((repl_subs[s][varsOfInterest+j]>0)?1:-1); - for (int k = 0; k <= varsOfInterest-nextWildcard; k++) - repl_subs[i][k] = scale_1*repl_subs[i][k] - sign*scale_2*repl_subs[s][k]; - num_wild_in_repl_subs[i]--; - } - } - - if (num_wild_in_repl_subs[i] == 1) { - for (int j = 1; j <= -nextWildcard; j++) - if (repl_subs[i][varsOfInterest+j] != 0) { - assert(wild_solved[j]==-1); - wild_solved[j] = i; - break; - } - } - else if (num_wild_in_repl_subs[i] > 1) { - int pos = 0; - for (int j = 1; j <= -nextWildcard; j++) - if (repl_subs[i][varsOfInterest+j] != 0) { - pos = j; - break; - } - assert(pos > 0); - - for (int j = i+1; j < num_repl_subs; j++) - if (repl_subs[j][varsOfInterest+pos] != 0) { - coef_t l = lcm(abs(repl_subs[i][varsOfInterest+pos]), abs(repl_subs[j][varsOfInterest+pos])); - coef_t scale_1 = l/abs(repl_subs[i][varsOfInterest+pos]); - coef_t scale_2 = l/abs(repl_subs[j][varsOfInterest+pos]); - int sign = ((repl_subs[i][varsOfInterest+pos]>0)?1:-1) * ((repl_subs[j][varsOfInterest+pos]>0)?1:-1); - for (int k = 0; k <= varsOfInterest-nextWildcard; k++) - repl_subs[j][k] = scale_2*repl_subs[j][k] - sign*scale_1*repl_subs[i][k]; - - num_wild_in_repl_subs[j] = 0; - int first_wild = 0; - for (int k = 1; k <= -nextWildcard; k++) - if (repl_subs[j][varsOfInterest+k] != 0) { - num_wild_in_repl_subs[j]++; - first_wild = k; - } - - if (num_wild_in_repl_subs[j] == 1) { - if (wild_solved[first_wild] < 0) - wild_solved[first_wild] = j; - } - } - } - } - - has_unsolved = false; - for (int i = 1; i <= -nextWildcard; i++) - if (coef[varsOfInterest+i] != 0 && wild_solved[i] < 0) { - has_unsolved = true; - break; - } - } - - // Substitute all widecards in the red constraint - for (int i = 1; i <= -nextWildcard; i++) { - if (coef[varsOfInterest+i] != 0) { - int s = wild_solved[i]; - assert(s >= 0); - - coef_t l = lcm(abs(coef[varsOfInterest+i]), abs(repl_subs[s][varsOfInterest+i])); - coef_t scale_1 = l/abs(coef[varsOfInterest+i]); - coef_t scale_2 = l/abs(repl_subs[s][varsOfInterest+i]); - int sign = ((coef[varsOfInterest+i]>0)?1:-1) * ((repl_subs[s][varsOfInterest+i]>0)?1:-1); - for (int j = 0; j <= varsOfInterest-nextWildcard; j++) - coef[j] = scale_1*coef[j] - sign*scale_2*repl_subs[s][j]; - - if (scale_1 != 1) - stride *= scale_1; - } - } - - for (int i = 0; i < num_repl_subs; i++) - delete []repl_subs[i]; - } - - // Ready to insert into redMemory - int m = nMemories++; - redMemory[m].length = 0; - redMemory[m].kind = type; - redMemory[m].constantTerm = coef[0]; - for(int i = 1; i <= varsOfInterest; i++) - if (coef[i]) { - int j = redMemory[m].length++; - redMemory[m].coef[j] = coef[i]; - redMemory[m].var[j] = i; - } - if (type == redStride) redMemory[m].stride = stride; - if (DBUG) { - fprintf(outputFile,"Red constraint remembered\n"); - printProblem(); - } -} - -void Problem::recallRedMemories() { - if (nMemories) { - if (TRACE) { - fprintf(outputFile,"Recalling red memories\n"); - printProblem(); - } - - eqn* e = 0; - for(int m = 0; m < nMemories; m++) { - switch(redMemory[m].kind) { - case redGEQ: - { - int temporary_eqn = newGEQ(); - e = &GEQs[temporary_eqn]; - eqnnzero(e, nVars); - e->touched = 1; - break; - } - case redEQ: - { - int temporary_eqn = newEQ(); - e = &EQs[temporary_eqn]; - eqnnzero(e, nVars); - break; - } - case redStride: - { - int temporary_eqn = newEQ(); - e = &EQs[temporary_eqn]; - eqnnzero(e, nVars); - int i = addNewUnprotectedWildcard(); - e->coef[i] = -redMemory[m].stride; - break; - } - default: - assert(0); - } - e->color = EQ_RED; - e->coef[0] = redMemory[m].constantTerm; - for(int i = 0; i < redMemory[m].length; i++) { - int v = redMemory[m].var[i]; - assert(var[forwardingAddress[v]] == v); - e->coef[forwardingAddress[v]] = redMemory[m].coef[i]; - } - } - - nMemories = 0; - if (TRACE) { - fprintf(outputFile,"Red memories recalled\n"); - printProblem(); - } - } -} - -void Problem::swapVars(int i, int j) { - if (DEBUG) { - use_ugly_names++; - fprintf(outputFile, "Swapping %d and %d\n", i, j); - printProblem(); - use_ugly_names--; - } - std::swap(var[i], var[j]); - for (int e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[i] != GEQs[e].coef[j]) { - GEQs[e].touched = true; - coef_t t = GEQs[e].coef[i]; - GEQs[e].coef[i] = GEQs[e].coef[j]; - GEQs[e].coef[j] = t; - } - for (int e = nEQs - 1; e >= 0; e--) - if (EQs[e].coef[i] != EQs[e].coef[j]) { - coef_t t = EQs[e].coef[i]; - EQs[e].coef[i] = EQs[e].coef[j]; - EQs[e].coef[j] = t; - } - for (int e = nSUBs - 1; e >= 0; e--) - if (SUBs[e].coef[i] != SUBs[e].coef[j]) { - coef_t t = SUBs[e].coef[i]; - SUBs[e].coef[i] = SUBs[e].coef[j]; - SUBs[e].coef[j] = t; - } - if (DEBUG) { - use_ugly_names++; - fprintf(outputFile, "Swapping complete \n"); - printProblem(); - fprintf(outputFile, "\n"); - use_ugly_names--; - } -} - -void Problem::addingEqualityConstraint(int e) { - if (addingOuterEqualities && originalProblem != noProblem && - originalProblem != this && !conservative) { - int e2 = originalProblem->newEQ(); - if (TRACE) - fprintf(outputFile, "adding equality constraint %d to outer problem\n", e2); - eqnnzero(&originalProblem->EQs[e2], originalProblem->nVars); - for (int i = nVars; i >= 1; i--) { - int j; - for (j = originalProblem->nVars; j >= 1; j--) - if (originalProblem->var[j] == var[i]) - break; - if (j <= 0 || (outerColor && j > originalProblem->safeVars)) { - if (DBUG) - fprintf(outputFile, "retracting\n"); - originalProblem->nEQs--; - return; - } - originalProblem->EQs[e2].coef[j] = EQs[e].coef[i]; - } - originalProblem->EQs[e2].coef[0] = EQs[e].coef[0]; - - originalProblem->EQs[e2].color = outerColor; - if (DBUG) - originalProblem->printProblem(); - } -} - - -// Initialize hash codes for inequalities, remove obvious redundancy. -// Case 1: -// a1*x1+a2*x2+...>=c (1) -// a1*x2+a2*x2+...>=c' (2) -// if c>=c' then (2) is redundant, and vice versa. -// -// case 2: -// a1*x1+a2*x2+...>=c (1) -// a1*x1+a2*x2+...<=c' (2) -// if c=c' then add equality of (1) or (2), -// if c>c' then no solution. -// -// Finally it calls extended normalize process which handles -// wildcards in redundacy removal. -normalizeReturnType Problem::normalize() { - int i, j; - bool coupledSubscripts = false; - - check(); - - for (int e = 0; e < nGEQs; e++) { - if (!GEQs[e].touched) { - if (!singleVarGEQ(&GEQs[e])) - coupledSubscripts = true; - } - else { // normalize e - coef_t g; - int topVar; - int i0; - coef_t hashCode; - - { - int *p = &packing[0]; - for (int k = 1; k <= nVars; k++) - if (GEQs[e].coef[k]) { - *(p++) = k; - } - topVar = (p - &packing[0]) - 1; - } - - if (topVar == -1) { - if (GEQs[e].coef[0] < 0) { - // e has no solution - return (normalize_false); - } - deleteGEQ(e); - e--; - continue; - } - else if (topVar == 0) { - int singleVar = packing[0]; - g = GEQs[e].coef[singleVar]; - if (g > 0) { - GEQs[e].coef[singleVar] = 1; - GEQs[e].key = singleVar; - } - else { - g = -g; - GEQs[e].coef[singleVar] = -1; - GEQs[e].key = -singleVar; - } - if (g > 1) - GEQs[e].coef[0] = int_div(GEQs[e].coef[0], g); - } - else { - coupledSubscripts = true; - i0 = topVar; - i = packing[i0--]; - g = GEQs[e].coef[i]; - hashCode = g * (i + 3); - if (g < 0) - g = -g; - for (; i0 >= 0; i0--) { - coef_t x; - i = packing[i0]; - x = GEQs[e].coef[i]; - hashCode = hashCode * keyMult * (i + 3) + x; - if (x < 0) - x = -x; - if (x == 1) { - g = 1; - i0--; - break; - } - else - g = gcd(x, g); - } - for (; i0 >= 0; i0--) { - coef_t x; - i = packing[i0]; - x = GEQs[e].coef[i]; - hashCode = hashCode * keyMult * (i + 3) + x; - } - if (g > 1) { - GEQs[e].coef[0] = int_div(GEQs[e].coef[0], g); - i0 = topVar; - i = packing[i0--]; - GEQs[e].coef[i] = GEQs[e].coef[i] / g; - hashCode = GEQs[e].coef[i] * (i + 3); - for (; i0 >= 0; i0--) { - i = packing[i0]; - GEQs[e].coef[i] = GEQs[e].coef[i] / g; - hashCode = hashCode * keyMult * (i + 3) + GEQs[e].coef[i]; - } - } - - { - coef_t g2 = abs(hashCode); // get e's hash code - j = static_cast<int>(g2 % static_cast<coef_t>(hashTableSize)); - assert (g2 % (coef_t) hashTableSize == j); - while (1) { - eqn *proto = &(hashMaster[j]); - if (proto->touched == g2) { - if (proto->coef[0] == topVar) { - if (hashCode >= 0) - for (i0 = topVar; i0 >= 0; i0--) { - i = packing[i0]; - if (GEQs[e].coef[i] != proto->coef[i]) - break; - } - else - for (i0 = topVar; i0 >= 0; i0--) { - i = packing[i0]; - if (GEQs[e].coef[i] != -proto->coef[i]) - break; - } - - if (i0 < 0) { - if (hashCode >= 0) - GEQs[e].key = proto->key; - else - GEQs[e].key = -proto->key; - break; - } - } - } - else if (proto->touched < 0) { //insert e into the empty entry in hash table - eqnnzero(proto, nVars); - if (hashCode >= 0) - for (i0 = topVar; i0 >= 0; i0--) { - i = packing[i0]; - proto->coef[i] = GEQs[e].coef[i]; - } - else - for (i0 = topVar; i0 >= 0; i0--) { - i = packing[i0]; - proto->coef[i] = -GEQs[e].coef[i]; - } - proto->coef[0] = topVar; - proto->touched = g2; - proto->key = nextKey++; - - if (proto->key > maxKeys) { - fprintf(outputFile, "too many hash keys generated \n"); - fflush(outputFile); - exit(2); - } - if (hashCode >= 0) - GEQs[e].key = proto->key; - else - GEQs[e].key = -proto->key; - break; - } - j = (j + 1) % hashTableSize; - } - } - } - } - - GEQs[e].touched = false; - - { - int eKey = GEQs[e].key; - int e2; - if (e > 0) { - e2 = fastLookup[maxKeys - eKey]; - if (e2 >= 0 && e2 < e && GEQs[e2].key == -eKey) { - // confirm it is indeed a match -- by chun 10/29/2008 - int k; - for (k = nVars; k >= 1; k--) - if (GEQs[e2].coef[k] != -GEQs[e].coef[k]) - break; - - if (k == 0) { - if (GEQs[e2].coef[0] < -GEQs[e].coef[0]) { - // there is no solution from e and e2 - return (normalize_false); - } - else if (GEQs[e2].coef[0] == -GEQs[e].coef[0]) { - // reduce e and e2 to an equation - int neweq = newEQ(); - eqnncpy(&EQs[neweq], &GEQs[e], nVars); - EQs[neweq].color = GEQs[e].color || GEQs[e2].color; - addingEqualityConstraint(neweq); - } - } - } - - e2 = fastLookup[maxKeys + eKey]; - if (e2 >= 0 && e2 < e && GEQs[e2].key == eKey) { - // confirm it is indeed a match -- by chun 10/29/2008 - int k; - for (k = nVars; k >= 1; k--) - if (GEQs[e2].coef[k] != GEQs[e].coef[k]) - break; - - if (k == 0) { - if (GEQs[e2].coef[0] > GEQs[e].coef[0] || - (GEQs[e2].coef[0] == GEQs[e].coef[0] && GEQs[e2].color)) { - // e2 is redundant - GEQs[e2].coef[0] = GEQs[e].coef[0]; - GEQs[e2].color = GEQs[e].color; - deleteGEQ(e); - e--; - continue; - } - else { - // e is redundant - deleteGEQ(e); - e--; - continue; - } - } - } - } - fastLookup[maxKeys + eKey] = e; - } - } - - // bypass entended normalization for temporary problem - if (!isTemporary && !inApproximateMode) - normalize_ext(); - - return coupledSubscripts ? normalize_coupled : normalize_uncoupled; -} - -// -// Extended normalize process, remove redundancy involving wildcards. -// e.g. -// exists alpha, beta: -// v1+8*alpha<=v2<=15+8*alpha (1) -// v1+8*beta<=v2<=15+8*beta (2) -// if there are no other inequalities involving alpha or beta, -// then either (1) or (2) is redundant. Such case can't be simplified -// by fourier-motzkin algorithm due to special meanings of existentials. -// -void Problem::normalize_ext() { - std::vector<BoolSet<> > disjoint_wildcards(nVars-safeVars, BoolSet<>(nVars-safeVars)); - std::vector<BoolSet<> > wildcards_in_inequality(nVars-safeVars, BoolSet<>(nGEQs)); - for (int i = 0; i < nVars-safeVars; i++) { - disjoint_wildcards[i].set(i); - } - - // create disjoint wildcard sets according to inequalities - for (int e = 0; e < nGEQs; e++) { - std::vector<BoolSet<> >::iterator first_set = disjoint_wildcards.end(); - for (int i = 0; i < nVars-safeVars; i++) - if (GEQs[e].coef[i+safeVars+1] != 0) { - wildcards_in_inequality[i].set(e); - - std::vector<BoolSet<> >::iterator cur_set = disjoint_wildcards.end(); - for (std::vector<BoolSet<> >::iterator j = disjoint_wildcards.begin(); j != disjoint_wildcards.end(); j++) - if ((*j).get(i)) { - cur_set = j; - break; - } - assert(cur_set!=disjoint_wildcards.end()); - if (first_set == disjoint_wildcards.end()) - first_set = cur_set; - else if (first_set != cur_set) { - *first_set |= *cur_set; - disjoint_wildcards.erase(cur_set); - } - } - } - - // do not consider wildcards appearing in equalities - for (int e = 0; e < nEQs; e++) - for (int i = 0; i < nVars-safeVars; i++) - if (EQs[e].coef[i+safeVars+1] != 0) { - for (std::vector<BoolSet<> >::iterator j = disjoint_wildcards.begin(); j != disjoint_wildcards.end(); j++) - if ((*j).get(i)) { - disjoint_wildcards.erase(j); - break; - } - } - - // create disjoint inequality sets - std::vector<BoolSet<> > disjoint_inequalities(disjoint_wildcards.size()); - for (size_t i = 0; i < disjoint_wildcards.size(); i++) - for (int j = 0; j < nVars-safeVars; j++) - if (disjoint_wildcards[i].get(j)) - disjoint_inequalities[i] |= wildcards_in_inequality[j]; - - // hash the inequality again, this time separate wildcard variables from - // regular variables - coef_t hash_safe[nGEQs]; - coef_t hash_wild[nGEQs]; - for (int e = 0; e < nGEQs; e++) { - coef_t hashCode = 0; - for (int i = 1; i <= safeVars; i++) - if (GEQs[e].coef[i] != 0) - hashCode = hashCode * keyMult * (i+3) + GEQs[e].coef[i]; - hash_safe[e] = hashCode; - - hashCode = 0; - for (int i = safeVars+1; i <= nVars; i++) - if (GEQs[e].coef[i] != 0) - hashCode = hashCode * keyMult + GEQs[e].coef[i]; - hash_wild[e] = hashCode; - } - - // sort hash keys for each disjoint set - std::vector<std::vector<std::pair<int, std::pair<coef_t, coef_t> > > > disjoint_hash(disjoint_inequalities.size()); - for (size_t i = 0; i < disjoint_inequalities.size(); i++) - for (int e = 0; e < nGEQs; e++) - if (disjoint_inequalities[i].get(e)) { - std::vector<std::pair<int, std::pair<coef_t, coef_t> > >::iterator j = disjoint_hash[i].begin(); - for (; j != disjoint_hash[i].end(); j++) - if ((hash_safe[e] > (*j).second.first) || - (hash_safe[e] == (*j).second.first && hash_wild[e] > (*j).second.second)) - break; - disjoint_hash[i].insert(j, std::make_pair(e, std::make_pair(hash_safe[e], hash_wild[e]))); - } - - // test wildcard equivalance - std::vector<bool> is_dead(nGEQs, false); - for (size_t i = 0; i < disjoint_wildcards.size(); i++) { - if (disjoint_inequalities[i].num_elem() == 0) - continue; - - for (size_t j = i+1; j < disjoint_wildcards.size(); j++) { - if (disjoint_wildcards[i].num_elem() != disjoint_wildcards[j].num_elem() || - disjoint_hash[i].size() != disjoint_hash[j].size()) - continue; - - bool match = true; - for (size_t k = 0; k < disjoint_hash[i].size(); k++) { - if (disjoint_hash[i][k].second != disjoint_hash[j][k].second) { - match = false; - break; - } - } - if (!match) - continue; - - // confirm same coefficients for regular variables - for (size_t k = 0; k < disjoint_hash[i].size(); k++) { - for (int p = 1; p <= safeVars; p++) - if (GEQs[disjoint_hash[i][k].first].coef[p] != GEQs[disjoint_hash[j][k].first].coef[p]) { - match = false; - break; - } - if (!match) - break; - } - if (!match) - continue; - - // now try combinatory wildcard matching - std::vector<int> wild_map(nVars-safeVars, -1); - for (size_t k = 0; k < disjoint_hash[i].size(); k++) { - int e1 = disjoint_hash[i][k].first; - int e2 = disjoint_hash[j][k].first; - - for (int p = 0; p < nVars-safeVars; p++) - if (GEQs[e1].coef[p+safeVars+1] != 0) { - if (wild_map[p] == -1) { - for (int q = 0; q < nVars-safeVars; q++) - if (wild_map[q] == -1 && - GEQs[e2].coef[q+safeVars+1] == GEQs[e1].coef[p+safeVars+1]) { - wild_map[p] = q; - wild_map[q] = p; - break; - } - if (wild_map[p] == -1) { - match = false; - break; - } - } - else if (GEQs[e2].coef[wild_map[p]+safeVars+1] != GEQs[e1].coef[p+safeVars+1]) { - match = false; - break; - } - } - if (!match) - break; - - for (int p = 0; p < nVars-safeVars; p++) - if (GEQs[e2].coef[p+safeVars+1] != 0 && - (wild_map[p] == -1 || GEQs[e2].coef[p+safeVars+1] != GEQs[e1].coef[wild_map[p]+safeVars+1])) { - match = false; - break; - } - if (!match) - break; - } - if (!match) - continue; - - // check constants - int dir = 0; - for (size_t k = 0; k < disjoint_hash[i].size(); k++) { - if (GEQs[disjoint_hash[i][k].first].coef[0] > GEQs[disjoint_hash[j][k].first].coef[0]) { - if (dir == 0) - dir = 1; - else if (dir == -1) { - match = false; - break; - } - } - else if (GEQs[disjoint_hash[i][k].first].coef[0] < GEQs[disjoint_hash[j][k].first].coef[0]) { - if (dir == 0) - dir = -1; - else if (dir == 1) { - match = false; - break; - } - } - } - if (!match) - continue; - - // check redness - int red_dir = 0; - for (size_t k = 0; k < disjoint_hash[i].size(); k++) { - if (GEQs[disjoint_hash[i][k].first].color > GEQs[disjoint_hash[j][k].first].color) { - if (red_dir == 0) - red_dir = 1; - else if (red_dir == -1) { - match = false; - break; - } - } - else if (GEQs[disjoint_hash[i][k].first].color < GEQs[disjoint_hash[j][k].first].color) { - if (red_dir == 0) - red_dir = -1; - else if (red_dir == 1) { - match = false; - break; - } - } - } - if (!match) - continue; - - // remove redundant inequalities - if (dir == 1 || (dir == 0 && red_dir == 1)) { - for (size_t k = 0; k < disjoint_hash[i].size(); k++) { - GEQs[disjoint_hash[i][k].first].coef[0] = GEQs[disjoint_hash[j][k].first].coef[0]; - GEQs[disjoint_hash[i][k].first].color = GEQs[disjoint_hash[j][k].first].color; - is_dead[disjoint_hash[j][k].first] = true; - } - } - else { - for (size_t k = 0; k < disjoint_hash[i].size(); k++) { - is_dead[disjoint_hash[j][k].first] = true; - } - } - } - } - - // eliminate dead inequalities - for (int e = nGEQs-1; e >= 0; e--) - if (is_dead[e]) { - deleteGEQ(e); - } -} - - -void initializeOmega(void) { - if (omegaInitialized) - return; - -// assert(sizeof(eqn)==sizeof(int)*(headerWords)+sizeof(coef_t)*(1+maxVars)); - nextWildcard = 0; - nextKey = maxVars + 1; - for (int i = 0; i < hashTableSize; i++) - hashMaster[i].touched = -1; - - sprintf(wildName[1], "__alpha"); - sprintf(wildName[2], "__beta"); - sprintf(wildName[3], "__gamma"); - sprintf(wildName[4], "__delta"); - sprintf(wildName[5], "__tau"); - sprintf(wildName[6], "__sigma"); - sprintf(wildName[7], "__chi"); - sprintf(wildName[8], "__omega"); - sprintf(wildName[9], "__pi"); - sprintf(wildName[10], "__ni"); - sprintf(wildName[11], "__Alpha"); - sprintf(wildName[12], "__Beta"); - sprintf(wildName[13], "__Gamma"); - sprintf(wildName[14], "__Delta"); - sprintf(wildName[15], "__Tau"); - sprintf(wildName[16], "__Sigma"); - sprintf(wildName[17], "__Chi"); - sprintf(wildName[18], "__Omega"); - sprintf(wildName[19], "__Pi"); - - omegaInitialized = 1; -} - -// -// This is experimental (I would say, clinical) fact: -// If the code below is removed then simplifyProblem cycles. -// -class brainDammage { -public: - brainDammage(); -}; - -brainDammage::brainDammage() { - initializeOmega(); -} - -static brainDammage Podgorny; - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_solve.cc b/omegalib/omega/src/omega_core/oc_solve.cc deleted file mode 100644 index c25b6d0..0000000 --- a/omegalib/omega/src/omega_core/oc_solve.cc +++ /dev/null @@ -1,1378 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Solve ineqalities. - - Notes: - - History: -*****************************************************************************/ - -#include <omega/omega_core/oc_i.h> - -namespace omega { - -static int solveDepth = 0; -#define maxDead maxmaxGEQs - -int Problem::solve(int desiredResult) { - assert(omegaInitialized); - int result; - - checkVars(nVars+1); - assert(nVars >= safeVars); - if (desiredResult != OC_SOLVE_SIMPLIFY) - safeVars = 0; - - solveDepth++; - if (solveDepth > 50) { - fprintf(outputFile, "Solve depth = %d, inApprox = %d, aborting\n", solveDepth, inApproximateMode); - printProblem(); - fflush(outputFile); - - if (solveDepth > 60) - exit(2); - } - - check(); - do { - doItAgain = 0; - check(); - if (solveEQ() == false) { - solveDepth--; - return (false); - } - check(); - if (!nGEQs) { - result = true; - nVars = safeVars; - break; - } - else - result = solveGEQ(desiredResult); - check(); - } - while (doItAgain && desiredResult == OC_SOLVE_SIMPLIFY); - solveDepth--; - - return (result); -} - - -// Supporting functions of solveGEQ -int Problem::smoothWeirdEquations() { - int e1, e2, e3, p, q, k; - coef_t alpha, alpha1, alpha2, alpha3; - coef_t c; - int v; - int result = 0; - - for (e1 = nGEQs - 1; e1 >= 0; e1--) - if (!GEQs[e1].color) { - coef_t g = 999999; - for (v = nVars; v >= 1; v--) - if (GEQs[e1].coef[v] != 0 && abs(GEQs[e1].coef[v]) < g) - g = abs(GEQs[e1].coef[v]); - if (g > 20) { - e3 = newGEQ(); /* Create a scratch GEQ,not part of the prob.*/ - nGEQs--; - for (v = nVars; v >= 1; v--) - GEQs[e3].coef[v] = int_div(6 * GEQs[e1].coef[v] + g / 2, g); - GEQs[e3].color = EQ_BLACK; - GEQs[e3].touched = 1; - GEQs[e3].coef[0] = 9997; - if (DBUG) { - fprintf(outputFile, "Checking to see if we can derive: "); - printGEQ(&GEQs[e3]); - fprintf(outputFile, "\n from: "); - printGEQ(&GEQs[e1]); - fprintf(outputFile, "\n"); - } - - - for (e2 = nGEQs - 1; e2 >= 0; e2--) - if (e1 != e2 && !GEQs[e2].color) { - for (p = nVars; p > 1; p--) { - for (q = p - 1; q > 0; q--) { - alpha = check_mul(GEQs[e1].coef[p], GEQs[e2].coef[q]) - check_mul(GEQs[e2].coef[p], GEQs[e1].coef[q]); - if (alpha != 0) - goto foundPQ; - } - } - continue; - - foundPQ: - - alpha1 = check_mul(GEQs[e2].coef[q], GEQs[e3].coef[p]) - check_mul(GEQs[e2].coef[p], GEQs[e3].coef[q]); - alpha2 = -(check_mul(GEQs[e1].coef[q], GEQs[e3].coef[p]) - check_mul(GEQs[e1].coef[p], GEQs[e3].coef[q])); - alpha3 = alpha; - - if (alpha1 * alpha2 <= 0) - continue; - if (alpha1 < 0) { - alpha1 = -alpha1; - alpha2 = -alpha2; - alpha3 = -alpha3; - } - if (alpha3 > 0) { - /* Trying to prove e3 is redundant */ - - /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */ - for (k = nVars; k >= 1; k--) - if (check_mul(alpha3, GEQs[e3].coef[k]) - != check_mul(alpha1, GEQs[e1].coef[k]) + check_mul(alpha2, GEQs[e2].coef[k])) - goto nextE2; - - c = check_mul(alpha1, GEQs[e1].coef[0]) + check_mul(alpha2, GEQs[e2].coef[0]); - if (c < check_mul(alpha3, (GEQs[e3].coef[0] + 1))) - GEQs[e3].coef[0] = int_div(c, alpha3); - - } - nextE2:; - } - if (GEQs[e3].coef[0] < 9997) { - result++; -#if !defined NDEBUG - int e4 = -#endif - newGEQ(); -#if !defined NDEBUG - assert(e3 == e4); -#endif - if (DBUG) { - fprintf(outputFile, "Smoothing wierd equations; adding:\n"); - printGEQ(&GEQs[e3]); - fprintf(outputFile, "\nto:\n"); - printProblem(); - fprintf(outputFile, "\n\n"); - } - } - } - } - return (result); -} - - -void Problem::analyzeElimination( - int &v, - int &darkConstraints, - int &darkShadowFeasible, - int &unit, - coef_t ¶llelSplinters, - coef_t &disjointSplinters, - coef_t &lbSplinters, - coef_t &ubSplinters, - int ¶llelLB) { - - parallelSplinters = (posInfinity); // was MAXINT - disjointSplinters = 0; - lbSplinters = 0; - ubSplinters = 0; - - darkConstraints = 0; - darkShadowFeasible = 1; - coef_t maxUBc = 0; - coef_t maxLBc = 0; - int e,e2; - unit = 0; - int exact = 1; - - for (e = nGEQs - 1; e >= 0; e--) { - coef_t c = GEQs[e].coef[v]; - - if (c < 0) { - coef_t Lc, Uc, g, diff, grey; - - set_max(maxUBc, -c); - Uc = -c; - for (e2 = nGEQs - 1; e2 >= 0; e2--) - if (GEQs[e2].coef[v] > 0) { - Lc = GEQs[e2].coef[v]; - g = 0; - grey = (Lc - 1) * (Uc - 1); - - for (int j = nVars; j >= 1; j--) { - coef_t diff = check_mul(Lc, GEQs[e].coef[j]) + check_mul(Uc, GEQs[e2].coef[j]); - if (diff < 0) diff = -diff; - g = gcd(g, diff); - if (g == 1) - break; - } - diff = check_mul(Lc, GEQs[e].coef[0]) + check_mul(Uc, GEQs[e2].coef[0]); - if (g == 0) { - if (diff < 0) { - /* Real shadow must be true */ - /* otherwise we would have found it during */ - /* check for opposing constraints */ - fprintf(outputFile, "Found conflicting constraints "); - printGEQ(&GEQs[e]); - fprintf(outputFile," and "); - printGEQ(&GEQs[e2]); - fprintf(outputFile,"\nin\n"); - printProblem(); - assert(diff >= 0); - } - if (diff < grey) { - darkShadowFeasible = 0; - if (parallelSplinters > diff+1) { - parallelSplinters = diff + 1; - parallelLB = e2; - } - } - else {/* dark shadow is true, don't need to worry about this constraint pair */ - } - } - else { - coef_t splinters= int_div(diff, g) - int_div(diff - grey, g); - if (splinters) exact = 0; - disjointSplinters += splinters; - if (g > 1) unit++; - darkConstraints++; - } - } - } - else if (c > 0) { - set_max(maxLBc, c); - } /* else - darkConstraints++; */ - } - - if (darkShadowFeasible) { - disjointSplinters++; - ubSplinters++; - lbSplinters++; - } - else disjointSplinters = (posInfinity); // was MAXINT - - - if (!darkShadowFeasible || !exact) - for (e = nGEQs - 1; e >= 0; e--) { - coef_t c = GEQs[e].coef[v]; - if (c < -1) { - c = -c; - ubSplinters += 1+(check_mul(c, maxLBc) - c - maxLBc) / maxLBc; - } - else if (c > 1) { - lbSplinters += 1+ (check_mul(c, maxUBc) - c - maxUBc) / maxUBc; - } - } - - if (DEBUG) { - fprintf(outputFile,"analyzing elimination of %s(%d)\n",variable(v),v); - if (darkShadowFeasible) - fprintf(outputFile," # dark constraints = %d\n", darkConstraints); - else - fprintf(outputFile," dark shadow obviously unfeasible\n"); - - fprintf(outputFile," " coef_fmt " LB splinters\n", lbSplinters); - fprintf(outputFile," " coef_fmt " UB splinters\n", ubSplinters); - if (disjointSplinters != (posInfinity)) - fprintf(outputFile," " coef_fmt " disjoint splinters\n", disjointSplinters); - if (parallelSplinters != (posInfinity)) - fprintf(outputFile," " coef_fmt " parallel splinters\n", parallelSplinters); - fprintf(outputFile, "\n"); - fprintf(outputFile," %3d unit score \n", unit); - } -} - - -void Problem::partialElimination() { - if (DBUG) { - fprintf(outputFile, "Performing Partial elimination\n"); - printProblem(); - } - int fv; - if (0) - fv = 0; - else - fv = safeVars; - bool somethingHappened = false; - for (int i = nVars; i > fv; i--) { - bool isDead[maxmaxGEQs]; - int e; - for (e = nGEQs-1; e >= 0; e--) isDead[e] = false; - int deadEqns[maxDead]; - int numDead = 0; - for (int e1 = nGEQs-1; e1 >= 0; e1--) - if (abs(GEQs[e1].coef[i]) == 1) { - bool isGood = true; - for (int e2 = nGEQs-1; e2 >= 0; e2--) - if (check_mul(GEQs[e2].coef[i], GEQs[e1].coef[i]) < 0) - if (GEQs[e1].key != -GEQs[e2].key) { - coef_t Uc = abs(GEQs[e2].coef[i]); - for (int k = nVars; k > fv; k--) - if (GEQs[e2].coef[k] + check_mul(GEQs[e1].coef[k], Uc) != 0) - isGood = false; - } - if (isGood) { - somethingHappened = true; - for (int e2 = nGEQs-1; e2 >= 0; e2--) - if (check_mul(GEQs[e2].coef[i], GEQs[e1].coef[i]) < 0) { - if (GEQs[e1].key != -GEQs[e2].key) { - coef_t Uc = abs(GEQs[e2].coef[i]); - int new_eqn; - if (numDead == 0) { - new_eqn = newGEQ(); - } - else { - new_eqn = deadEqns[--numDead]; - } - isDead[new_eqn] = false; - if (DBUG) { - fprintf(outputFile,"Eliminating constraint on %s\n", variable(i)); - fprintf(outputFile, "e1 = %d, e2 = %d, gen = %d\n", e1, e2, new_eqn); - printGEQ(&(GEQs[e1])); - fprintf(outputFile, "\n"); - printGEQ(&(GEQs[e2])); - fprintf(outputFile, "\n"); - } - - for (int k = nVars; k >= 0; k--) - GEQs[new_eqn].coef[k] = GEQs[e2].coef[k] + check_mul(GEQs[e1].coef[k], Uc); - GEQs[new_eqn].touched = true; - GEQs[new_eqn].color = GEQs[e2].color | GEQs[e1].color; - if (DBUG) { - fprintf(outputFile, "give "); - printGEQ(&(GEQs[new_eqn])); - fprintf(outputFile, "\n"); - } - assert(GEQs[new_eqn].coef[i] == 0); - } - } - deadEqns[numDead++] = e1; - isDead[e1] = true; - if (DEBUG) - fprintf(outputFile, "Killed %d\n", e1); - } - } - for (e = nGEQs - 1; e >= 0; e--) - if (isDead[e]) { - deleteGEQ(e); - } - } - if (somethingHappened && DBUG) { - fprintf(outputFile, "Result of Partial elimination\n"); - printProblem(); - } -} - - -int Problem:: solveGEQ(int desiredResult) { - int i, j, k, e; - int fv; - int result; - int coupledSubscripts; - int eliminateAgain; - int smoothed = 0; - int triedEliminatingRedundant = 0; - j = 0; - - if (desiredResult != OC_SOLVE_SIMPLIFY) { - nSUBs = 0; - nMemories = 0; - safeVars = 0; - varsOfInterest = 0; - } - -solveGEQstart: - while (1) { - assert(desiredResult == OC_SOLVE_SIMPLIFY || nSUBs == 0); - check_number_GEQs(nGEQs); - - if (DEBUG) { - fprintf(outputFile, "\nSolveGEQ(%d,%d):\n", desiredResult, pleaseNoEqualitiesInSimplifiedProblems); - printProblem(); - fprintf(outputFile, "\n"); - } - -#ifndef NDEBUG - for(e=0;e<nSUBs;e++) - for(i=safeVars+1;i<=nVars;i++) - assert(!SUBs[e].coef[i]); -#endif - - check(); - - if (nVars == 1) { - int uColor = EQ_BLACK; - int lColor = EQ_BLACK; - coef_t upperBound = posInfinity; - coef_t lowerBound = negInfinity; - for (e = nGEQs - 1; e >= 0; e--) { - coef_t a = GEQs[e].coef[1]; - coef_t c = GEQs[e].coef[0]; - /* our equation is ax + c >= 0, or ax >= -c, or c >= -ax */ - if (a == 0) { - if (c < 0) { - if (TRACE) - fprintf(outputFile, "equations have no solution (G)\n"); - return (false); - } - } - else if (a > 0) { - if (a != 1) - c = int_div(c, a); - if (lowerBound < -c || (lowerBound == -c && !isRed(&GEQs[e]))) { - lowerBound = -c; - lColor = GEQs[e].color; - } - } - else { - if (a != -1) - c = int_div(c, -a); - if (upperBound > c || (upperBound == c && !isRed(&GEQs[e]))) { - upperBound = c; - uColor = GEQs[e].color; - } - } - } - if (DEBUG) - fprintf(outputFile, "upper bound = " coef_fmt "\n", upperBound); - if (DEBUG) - fprintf(outputFile, "lower bound = " coef_fmt "\n", lowerBound); - if (lowerBound > upperBound) { - if (TRACE) - fprintf(outputFile, "equations have no solution (H)\n"); - return (false); - } - if (desiredResult == OC_SOLVE_SIMPLIFY) { - nGEQs = 0; - if (safeVars == 1) { - if (lowerBound == upperBound && !uColor && !lColor) { - int e = newEQ(); - assert(e == 0); - EQs[e].coef[0] = -lowerBound; - EQs[e].coef[1] = 1; - EQs[e].color = lColor | uColor; - return (solve(desiredResult)); - } - else { - if (lowerBound > negInfinity) { - int e = newGEQ(); - assert(e == 0); - GEQs[e].coef[0] = -lowerBound; - GEQs[e].coef[1] = 1; - GEQs[e].key = 1; - GEQs[e].color = lColor; - GEQs[e].touched = 0; - } - if (upperBound < posInfinity) { - int e = newGEQ(); - GEQs[e].coef[0] = upperBound; - GEQs[e].coef[1] = -1; - GEQs[e].key = -1; - GEQs[e].color = uColor; - GEQs[e].touched = 0; - } - } - } - else - nVars = 0; - return (true); - } - if (originalProblem != noProblem && !lColor && !uColor && !conservative && lowerBound == upperBound) { - int e = newEQ(); - assert(e == 0); - EQs[e].coef[0] = -lowerBound; - EQs[e].coef[1] = 1; - EQs[e].color = EQ_BLACK; - addingEqualityConstraint(0); - } - return (true); - } - - if (!variablesFreed) { - variablesFreed = 1; - if (desiredResult != OC_SOLVE_SIMPLIFY) - freeEliminations(0); - else - freeEliminations(safeVars); - if (nVars == 1) - continue; - } - - - switch (normalize()) { - case normalize_false: - return (false); - break; - case normalize_coupled: - coupledSubscripts = true; - break; - case normalize_uncoupled: - coupledSubscripts = false; - break; - default: - coupledSubscripts = false; - assert(0 && "impossible case in SolveGEQ"); - } - - - if ((doTrace && desiredResult == OC_SOLVE_SIMPLIFY) || DBUG) { - fprintf(outputFile, "\nafter normalization:\n"); - printProblem(); - fprintf(outputFile, "\n"); - for(e=0;e<nGEQs;e++) assert(!GEQs[e].touched); - fprintf(outputFile, "eliminating variable using fourier-motzkin elimination\n"); - } - - // eliminating variable using fourier-motzkin elimination - do { - eliminateAgain = 0; - - if (nEQs > 0) - return (solve(desiredResult)); - - if (!coupledSubscripts) { - if (safeVars == 0) - nGEQs = 0; - else - for (e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].key > safeVars || -safeVars > GEQs[e].key) - deleteGEQ(e); - nVars = safeVars; - return (true); - } - - if (desiredResult != OC_SOLVE_SIMPLIFY) - fv = 0; - else - fv = safeVars; - - if (nVars == 0 || nGEQs == 0) { - nGEQs = 0; - if (desiredResult == OC_SOLVE_SIMPLIFY) - nVars = safeVars; - return (true); - } - if (desiredResult == OC_SOLVE_SIMPLIFY && nVars == safeVars) { - return (true); - } - - - if (nGEQs+6 > maxGEQs || nGEQs > 2 * nVars * nVars + 4 * nVars + 10) { - if (TRACE) - fprintf(outputFile, "TOO MANY EQUATIONS; %d equations, %d variables, ELIMINATING REDUNDANT ONES\n", nGEQs, nVars); - if (!quickKill(0,true)) - return 0; - if (nEQs > 0) - return (solve(desiredResult)); - if (TRACE) - fprintf(outputFile, "END ELIMINATION OF REDUNDANT EQUATIONS\n"); - if (DBUG) printProblem(); - } - - - { - int darkConstraints, darkShadowFeasible, unit, parallelLB; - coef_t parallelSplinters, disjointSplinters, lbSplinters, ubSplinters, splinters; - coef_t bestScore, score; - int bestVar; - int exact; - int Ue,Le; - - if (desiredResult != OC_SOLVE_SIMPLIFY) fv = 0; - else fv = safeVars; - - if (DEBUG) { - fprintf(outputFile,"Considering elimination possibilities[ \n"); - printProblem(); - } - - analyzeGEQstart: - try { - bestScore = posInfinity; - bestVar = -1; - for (i = nVars; i != fv; i--) { - analyzeElimination(i, darkConstraints, darkShadowFeasible, unit, parallelSplinters, disjointSplinters, lbSplinters, ubSplinters, parallelLB); - - score = min(min(parallelSplinters,disjointSplinters), - min(lbSplinters,ubSplinters)); - exact = score == 1; - score = 10000*(score-1) + darkConstraints; - if (score >= posInfinity) // too big the score - score = posInfinity - 1; - score -= 3*unit; - - if (score < bestScore) { - bestScore = score; - bestVar = i; - if (i > 4 && score < nGEQs) break; - } - } - assert(bestVar>=0); - exact = bestScore < 10000; - i = bestVar; - assert(i<=nVars); - analyzeElimination(i, darkConstraints, darkShadowFeasible, unit, parallelSplinters, disjointSplinters, lbSplinters, ubSplinters, parallelLB); - if (DEBUG) { - fprintf(outputFile,"] Choose to eliminate %s \n",variable(i)); - } - splinters = lbSplinters; - if (splinters <= parallelSplinters) - parallelSplinters = posInfinity; - else splinters = parallelSplinters; - if (disjointSplinters == 1) splinters = 1; - exact = splinters == 1; - if (inApproximateMode) exact = 1; - } - catch (std::overflow_error) { - int result = quickKill(0, true); - if (result == 0) - return 0; - else if (result == 1) - return true; - else { - if (nEQs > 0) - return (solve(desiredResult)); - triedEliminatingRedundant = 1; - goto analyzeGEQstart; - } - } - - if (!triedEliminatingRedundant && darkConstraints > maxGEQs) { - if (TRACE) - fprintf(outputFile, "Elimination will create TOO MANY EQUATIONS; %d equations, %d variables, %d new constraints, ELIMINATING REDUNDANT ONES\n", nGEQs, nVars,darkConstraints); - if (!quickKill(0)) - return 0; - if (nEQs > 0) - return (solve(desiredResult)); - if (TRACE) - fprintf(outputFile, "END ELIMINATION OF REDUNDANT EQUATIONS\n"); - if (DBUG) printProblem(); - - triedEliminatingRedundant = 1; - eliminateAgain = 1; - continue; - } - - if (!exact && !triedEliminatingRedundant && - safeVars > 0 && desiredResult == OC_SOLVE_SIMPLIFY) { - if (TRACE) - fprintf(outputFile, "Trying to produce exact elimination by finding redundant constraints [\n"); - if (!quickKill(1)) return 0; - if (TRACE) - fprintf(outputFile, "]\n"); - triedEliminatingRedundant = 1; - eliminateAgain = 1; - continue; - } - triedEliminatingRedundant = 0; - - if (desiredResult == OC_SOLVE_SIMPLIFY && !exact) { - partialElimination(); - switch (normalize()) { - case normalize_false: - return (false); - break; - case normalize_coupled: - case normalize_uncoupled: - break; - } - if (nEQs) return solveEQ(); - if (DBUG) fprintf(outputFile,"Stopping short due to non-exact elimination\n"); - return (true); - } - - if ( desiredResult == OC_SOLVE_SIMPLIFY && darkConstraints > maxGEQs) { - if (DBUG) fprintf(outputFile,"Stopping short due to overflow of GEQs: %d\n", darkConstraints); - return (true); - } - - if ((doTrace && desiredResult == OC_SOLVE_SIMPLIFY) || DBUG) { - fprintf(outputFile, "going to eliminate %s, (%d)\n", variable(i), i); - if (DEBUG) - printProblem(); - fprintf(outputFile, "score = " coef_fmt "/" coef_fmt "\n", bestScore,splinters); - } - - if (!exact && desiredResult == OC_SOLVE_SIMPLIFY && parallelSplinters == splinters) { - return parallelSplinter(parallelLB, parallelSplinters, desiredResult); - } - - // smoothed = 0; // what a bug!!! -- by chun 6/10/2008 - - if (i != nVars) { - j = nVars; - swapVars(i,j); - - i = j; - } - else if (DEBUG) { - printVars(); - fprintf(outputFile, "No swap needed before eliminating %s(%d/%d)\n",variable(i),i,nVars); - for(j=1;j<=i;j++) fprintf(outputFile,"var #%d = %s(%x)\n",j,variable(j),var[j]); - printProblem(); - } - nVars--; - - if (exact) { - if (nVars == 1) { - coef_t upperBound = posInfinity; - coef_t lowerBound = negInfinity; - int ub_color = 0; - int lb_color = 0; - coef_t constantTerm, coefficient; - int topEqn = nGEQs - 1; - coef_t Lc; - for (Le = topEqn; Le >= 0; Le--) - if ((Lc = GEQs[Le].coef[i]) == 0) { - if (GEQs[Le].coef[1] == 1) { - constantTerm = -GEQs[Le].coef[0]; - if (constantTerm > lowerBound || (constantTerm == lowerBound && !isRed(&GEQs[Le]))) { - lowerBound = constantTerm; - lb_color = GEQs[Le].color; - } - if (DEBUG) { - if (GEQs[Le].color == EQ_BLACK) - fprintf(outputFile, " :::=> %s >= " coef_fmt "\n", variable(1), constantTerm); - else - fprintf(outputFile, " :::=> [%s >= " coef_fmt "]\n", variable(1), constantTerm); - } - } - else { - constantTerm = GEQs[Le].coef[0]; - if (constantTerm < upperBound || (constantTerm == upperBound && !isRed(&GEQs[Le]))) { - upperBound = constantTerm; - ub_color = GEQs[Le].color; - } - if (DEBUG) { - if (GEQs[Le].color == EQ_BLACK) - fprintf(outputFile, " :::=> %s <= " coef_fmt "\n", variable(1), constantTerm); - else - fprintf(outputFile, " :::=> [%s <= " coef_fmt "]\n", variable(1), constantTerm); - } - } - } - else if (Lc > 0) { - for (Ue = topEqn; Ue >= 0; Ue--) - if (GEQs[Ue].coef[i] < 0) { - if (GEQs[Le].key != -GEQs[Ue].key) { - coef_t Uc = -GEQs[Ue].coef[i]; - coefficient = check_mul(GEQs[Ue].coef[1], Lc) + check_mul(GEQs[Le].coef[1], Uc); - constantTerm = check_mul(GEQs[Ue].coef[0], Lc) + check_mul(GEQs[Le].coef[0], Uc); - if (DEBUG) { - printGEQextra(&(GEQs[Ue])); - fprintf(outputFile, "\n"); - printGEQextra(&(GEQs[Le])); - fprintf(outputFile, "\n"); - } - if (coefficient > 0) { - constantTerm = -(int_div(constantTerm, coefficient)); - /* assert(black == 0) */ - if (constantTerm > lowerBound || - (constantTerm == lowerBound && - (desiredResult != OC_SOLVE_SIMPLIFY || (GEQs[Ue].color == EQ_BLACK && GEQs[Le].color == EQ_BLACK)))) { - lowerBound = constantTerm; - lb_color = GEQs[Ue].color || GEQs[Le].color; - } - if (DEBUG) { - if (GEQs[Ue].color || GEQs[Le].color) - fprintf(outputFile, " ::=> [%s >= " coef_fmt "]\n", variable(1), constantTerm); - else - fprintf(outputFile, " ::=> %s >= " coef_fmt "\n", variable(1), constantTerm); - } - } - else if (coefficient < 0) { - constantTerm = (int_div(constantTerm, -coefficient)); - if (constantTerm < upperBound || - (constantTerm == upperBound && GEQs[Ue].color == EQ_BLACK && GEQs[Le].color == EQ_BLACK)) { - upperBound = constantTerm; - ub_color = GEQs[Ue].color || GEQs[Le].color; - } - if (DEBUG) { - if (GEQs[Ue].color || GEQs[Le].color) - fprintf(outputFile, " ::=> [%s <= " coef_fmt "]\n", variable(1), constantTerm); - else - fprintf(outputFile, " ::=> %s <= " coef_fmt "\n", variable(1), constantTerm); - } - } - } - } - } - nGEQs = 0; - if (DEBUG) - fprintf(outputFile, " therefore, %c" coef_fmt " <= %c%s%c <= " coef_fmt "%c\n", lb_color ? '[' : ' ', lowerBound, (lb_color && !ub_color) ? ']' : ' ', variable(1), (!lb_color && ub_color) ? '[' : ' ', upperBound, ub_color ? ']' : ' '); - if (lowerBound > upperBound) - return (false); - - if (upperBound == lowerBound) { - int e = newEQ(); - assert(e == 0); - EQs[e].coef[1] = -1; - EQs[e].coef[0] = upperBound; - EQs[e].color = ub_color | lb_color; - addingEqualityConstraint(0); - } - else if (safeVars == 1) { - if (upperBound != posInfinity) { - int e = newGEQ(); - assert(e == 0); - GEQs[e].coef[1] = -1; - GEQs[e].coef[0] = upperBound; - GEQs[e].color = ub_color; - GEQs[e].key = -1; - GEQs[e].touched = 0; - } - if (lowerBound != negInfinity) { - int e = newGEQ(); - GEQs[e].coef[1] = 1; - GEQs[e].coef[0] = -lowerBound; - GEQs[e].color = lb_color; - GEQs[e].key = 1; - GEQs[e].touched = 0; - } - } - if (safeVars == 0) - nVars = 0; - return (true); - } - eliminateAgain = 1; - - { - int deadEqns[maxDead]; - int numDead = 0; - int topEqn = nGEQs - 1; - int lowerBoundCount = 0; - for (Le = topEqn; Le >= 0; Le--) - if (GEQs[Le].coef[i] > 0) - lowerBoundCount++; - if (DEBUG) - fprintf(outputFile, "lower bound count = %d\n", lowerBoundCount); - if (lowerBoundCount == 0) { - if (desiredResult != OC_SOLVE_SIMPLIFY) fv = 0; - else fv = safeVars; - nVars++; - freeEliminations(fv); - continue; - } - for (Le = topEqn; Le >= 0; Le--) - if (GEQs[Le].coef[i] > 0) { - coef_t Lc = GEQs[Le].coef[i]; - for (Ue = topEqn; Ue >= 0; Ue--) - if (GEQs[Ue].coef[i] < 0) { - if (GEQs[Le].key != -GEQs[Ue].key) { - coef_t Uc = -GEQs[Ue].coef[i]; - int e2; - if (numDead == 0) { - /*( Big kludge warning ) */ - /* this code is still using location nVars+1 */ - /* but newGEQ, if it reallocates, only copies*/ - /* locations up to nVars. This fixes that. */ - nVars++; - e2 = newGEQ(); - nVars--; - } - else { - e2 = deadEqns[--numDead]; - } - if (DEBUG) - fprintf(outputFile, "Le = %d, Ue = %d, gen = %d\n", Le, Ue, e2); - if (DEBUG) { - printGEQextra(&(GEQs[Le])); - fprintf(outputFile, "\n"); - printGEQextra(&(GEQs[Ue])); - fprintf(outputFile, "\n"); - } - eliminateAgain = 0; - coef_t g = gcd(Lc,Uc); - coef_t Lc_over_g = Lc/g; - coef_t Uc_over_g = Uc/g; - - for (k = nVars; k >= 0; k--) - GEQs[e2].coef[k] = - check_mul(GEQs[Ue].coef[k], Lc_over_g) + check_mul(GEQs[Le].coef[k], Uc_over_g); - - GEQs[e2].coef[nVars + 1] = 0; - GEQs[e2].touched = true; - GEQs[e2].color = GEQs[Ue].color | GEQs[Le].color; - - if (DEBUG) { - printGEQ(&(GEQs[e2])); - fprintf(outputFile, "\n"); - } - } - if (lowerBoundCount == 1) { - deadEqns[numDead++] = Ue; - if (DEBUG) - fprintf(outputFile, "Killed %d\n", Ue); - } - } - lowerBoundCount--; - deadEqns[numDead++] = Le; - if (DEBUG) - fprintf(outputFile, "Killed %d\n", Le); - } - - { - int isDead[maxmaxGEQs]; - for (e = nGEQs - 1; e >= 0; e--) - isDead[e] = false; - while (numDead > 0) { - e = deadEqns[--numDead]; - isDead[e] = true; - } - for (e = nGEQs - 1; e >= 0; e--) - if (isDead[e]) { - nVars++; - deleteGEQ(e); - nVars--; - } - } - continue; - } - } - else { - Problem *rS, *iS; - - rS = new Problem; - iS = new Problem; - - iS->nVars = rS->nVars = nVars; // do this immed.; in case of reallocation, we - // need to know how much to copy - rS->get_var_name = get_var_name; - rS->getVarNameArgs = getVarNameArgs; - iS->get_var_name = get_var_name; - iS->getVarNameArgs = getVarNameArgs; - - for (e = 0; e < nGEQs; e++) - if (GEQs[e].coef[i] == 0) { - int re2 = rS->newGEQ(); - int ie2 = iS->newGEQ(); - eqnncpy(&(rS->GEQs[re2]), &GEQs[e], nVars); - eqnncpy(&(iS->GEQs[ie2]), &GEQs[e], nVars); - if (DEBUG) { - int t; - fprintf(outputFile, "Copying (%d, " coef_fmt "): ", i, GEQs[e].coef[i]); - printGEQextra(&GEQs[e]); - fprintf(outputFile, "\n"); - for (t = 0; t <= nVars + 1; t++) - fprintf(outputFile, coef_fmt " ", GEQs[e].coef[t]); - fprintf(outputFile, "\n"); - } - } - for (Le = nGEQs - 1; Le >= 0; Le--) - if (GEQs[Le].coef[i] > 0) { - coef_t Lc = GEQs[Le].coef[i]; - for (Ue = nGEQs - 1; Ue >= 0; Ue--) - if (GEQs[Ue].coef[i] < 0) - if (GEQs[Le].key != -GEQs[Ue].key) { - coef_t Uc = -GEQs[Ue].coef[i]; - coef_t g = gcd(Lc,Uc); - coef_t Lc_over_g = Lc/g; - coef_t Uc_over_g = Uc/g; - int re2 = rS->newGEQ(); - int ie2 = iS->newGEQ(); - rS->GEQs[re2].touched = iS->GEQs[ie2].touched = true; - if (DEBUG) { - fprintf(outputFile, "---\n"); - fprintf(outputFile, "Le(Lc) = %d(" coef_fmt "), Ue(Uc) = %d(" coef_fmt "), gen = %d\n", Le, Lc, Ue, Uc, ie2); - printGEQextra(&GEQs[Le]); - fprintf(outputFile, "\n"); - printGEQextra(&GEQs[Ue]); - fprintf(outputFile, "\n"); - } - - if (Uc == Lc) { - for (k = nVars; k >= 0; k--) - iS->GEQs[ie2].coef[k] = rS->GEQs[re2].coef[k] = - GEQs[Ue].coef[k] + GEQs[Le].coef[k]; - iS->GEQs[ie2].coef[0] -= (Uc - 1); - } - else { - for (k = nVars; k >= 0; k--) - iS->GEQs[ie2].coef[k] = rS->GEQs[re2].coef[k] = - check_mul(GEQs[Ue].coef[k], Lc_over_g) + check_mul(GEQs[Le].coef[k], Uc_over_g); - iS->GEQs[ie2].coef[0] -= check_mul(Uc_over_g-1, Lc_over_g-1); - } - - iS->GEQs[ie2].color = rS->GEQs[re2].color - = GEQs[Ue].color || GEQs[Le].color; - - if (DEBUG) { - printGEQ(&(rS->GEQs[re2])); - fprintf(outputFile, "\n"); - } - // ie2 = iS->newGEQ(); - // re2 = rS->newGEQ(); - } - - } - iS->variablesInitialized = rS->variablesInitialized = 1; - iS->nEQs = rS->nEQs = 0; - assert(desiredResult != OC_SOLVE_SIMPLIFY); - assert(nSUBs == 0); - iS->nSUBs = rS->nSUBs = nSUBs; - iS->safeVars = rS->safeVars = safeVars; - int t; - for (t = nVars; t >= 0; t--) - rS->var[t] = var[t]; - for (t = nVars; t >= 0; t--) - iS->var[t] = var[t]; - nVars++; - if (desiredResult != true) { - int t = trace; - if (TRACE) - fprintf(outputFile, "\nreal solution(%d):\n", depth); - depth++; - trace = 0; - if (originalProblem == noProblem) { - originalProblem = this; - result = rS->solveGEQ(false); - originalProblem = noProblem; - } - else - result = rS->solveGEQ(false); - trace = t; - depth--; - if (result == false) { - delete rS; - delete iS; - return (result); - } - - if (nEQs > 0) { - /* An equality constraint must have been found */ - delete rS; - delete iS; - return (solve(desiredResult)); - } - } - if (desiredResult != false) { - if (darkShadowFeasible) { - if (TRACE) - fprintf(outputFile, "\ninteger solution(%d):\n", depth); - depth++; - conservative++; - result = iS->solveGEQ(desiredResult); - conservative--; - depth--; - if (result != false) { - delete rS; - delete iS; - return (result); - } - } - if (TRACE) - fprintf(outputFile, "have to do exact analysis\n"); - - { - coef_t worstLowerBoundConstant=1; - int lowerBounds = 0; - int lowerBound[maxmaxGEQs]; - int smallest; - int t; - conservative++; - for (e = 0; e < nGEQs; e++) - if (GEQs[e].coef[i] < -1) { - set_max(worstLowerBoundConstant, - -GEQs[e].coef[i]); - } - else if (GEQs[e].coef[i] > 1) - lowerBound[lowerBounds++] = e; - /* sort array */ - for (j = 0; j < lowerBounds; j++) { - smallest = j; - for (k = j + 1; k < lowerBounds; k++) - if (GEQs[lowerBound[smallest]].coef[i] > GEQs[lowerBound[k]].coef[i]) - smallest = k; - t = lowerBound[smallest]; - lowerBound[smallest] = lowerBound[j]; - lowerBound[j] = t; - } - if (DEBUG) { - fprintf(outputFile, "lower bound coeeficients = "); - for (j = 0; j < lowerBounds; j++) - fprintf(outputFile, " " coef_fmt, GEQs[lowerBound[j]].coef[i]); - fprintf(outputFile, "\n"); - } - - - for (j = 0; j < lowerBounds; j++) { - coef_t maxIncr; - coef_t c; - e = lowerBound[j]; - maxIncr = (check_mul(GEQs[e].coef[i]-1, worstLowerBoundConstant-1) - 1) / worstLowerBoundConstant; - - /* maxIncr += 2; */ - if ((doTrace && desiredResult == OC_SOLVE_SIMPLIFY) || DBUG) { - fprintf(outputFile, "for equation "); - printGEQ(&GEQs[e]); - fprintf(outputFile, "\ntry decrements from 0 to " coef_fmt "\n", maxIncr); - printProblem(); - } - if (maxIncr > 50) { - if (!smoothed && smoothWeirdEquations()) { - conservative--; - delete rS; - delete iS; - smoothed = 1; - goto solveGEQstart; - } - } - int neweq = newEQ(); - assert(neweq == 0); - eqnncpy(&EQs[neweq], &GEQs[e], nVars); - /* - * if (GEQs[e].color) fprintf(outputFile,"warning: adding black equality constraint - * based on red inequality\n"); - */ - EQs[neweq].color = EQ_BLACK; - eqnnzero(&GEQs[e], nVars); - GEQs[e].touched = true; - for (c = maxIncr; c >= 0; c--) { - if (DBUG) - fprintf(outputFile, "trying next decrement of " coef_fmt "\n", maxIncr - c); - if (DBUG) - printProblem(); - *rS = *this; - if (DEBUG) - rS->printProblem(); - result = rS->solve(desiredResult); - if (result == true) { - delete rS; - delete iS; - conservative--; - return (true); - } - EQs[0].coef[0]--; - } - if (j + 1 < lowerBounds) { - nEQs = 0; - eqnncpy(&GEQs[e], &EQs[0], nVars); - GEQs[e].touched = 1; - GEQs[e].color = EQ_BLACK; - *rS = *this; - if (DEBUG) - fprintf(outputFile, "exhausted lower bound, checking if still feasible "); - result = rS->solve(false); - if (result == false) - break; - } - } - if ((doTrace && desiredResult == OC_SOLVE_SIMPLIFY) || DBUG) - fprintf(outputFile, "fall-off the end\n"); - delete rS; - delete iS; - - conservative--; - return (false); - } - } - delete rS; - delete iS; - } - return (OC_SOLVE_UNKNOWN); - } - } - while (eliminateAgain); - } -} - - -int Problem::parallelSplinter(int e, int diff, int desiredResult) { - Problem *tmpProblem; - int i; - if (DBUG) { - fprintf(outputFile, "Using parallel splintering\n"); - printProblem(); - } - tmpProblem = new Problem; - int neweq = newEQ(); - assert(neweq == 0); - eqnncpy(&EQs[0], &GEQs[e], nVars); - for (i = 0; i <= diff; i++) { - *tmpProblem = * this; - tmpProblem->isTemporary = true; - if (DBUG) { - fprintf(outputFile, "Splinter # %i\n", i); - printProblem(); - } - if (tmpProblem->solve(desiredResult)) { - delete tmpProblem; - return true; - } - EQs[0].coef[0]--; - } - delete tmpProblem; - return false; -} - - -int Problem::verifyProblem() { - int result; - int e; - int areRed; - check(); - Problem tmpProblem(*this); - tmpProblem.varsOfInterest = 0; - tmpProblem.safeVars = 0; - tmpProblem.nSUBs = 0; - tmpProblem.nMemories = 0; - tmpProblem.isTemporary = true; - areRed = 0; - if (mayBeRed) { - for(e=0; e<nEQs; e++) if (EQs[e].color) areRed = 1; - for(e=0; e<nGEQs; e++) if (GEQs[e].color) areRed = 1; - if (areRed) tmpProblem.turnRedBlack(); - } - originalProblem = this; - assert(!outerColor); - outerColor = areRed; - if (TRACE) { - fprintf(outputFile, "verifying problem: [\n"); - printProblem(); - } - tmpProblem.check(); - tmpProblem.freeEliminations(0); - result = tmpProblem.solve(OC_SOLVE_UNKNOWN); - originalProblem = noProblem; - outerColor = 0; - if (TRACE) { - if (result) - fprintf(outputFile, "] verified problem\n"); - else - fprintf(outputFile, "] disproved problem\n"); - printProblem(); - } - check(); - return result; -} - - -void Problem:: freeEliminations(int fv) { - int tryAgain = 1; - int i, e, e2; - while (tryAgain) { - tryAgain = 0; - for (i = nVars; i > fv; i--) { - for (e = nGEQs - 1; e >= 0; e--) - if (GEQs[e].coef[i]) - break; - if (e < 0) - e2 = e; - else if (GEQs[e].coef[i] > 0) { - for (e2 = e - 1; e2 >= 0; e2--) - if (GEQs[e2].coef[i] < 0) - break; - } - else { - for (e2 = e - 1; e2 >= 0; e2--) - if (GEQs[e2].coef[i] > 0) - break; - } - if (e2 < 0) { - int e3; - for (e3 = nSUBs - 1; e3 >= 0; e3--) - if (SUBs[e3].coef[i]) - break; - if (e3 >= 0) - continue; - for (e3 = nEQs - 1; e3 >= 0; e3--) - if (EQs[e3].coef[i]) - break; - if (e3 >= 0) - continue; - if (DBUG) - fprintf(outputFile, "a free elimination of %s (%d)\n", variable(i),e); - if (e >= 0) { - deleteGEQ(e); - for (e--; e >= 0; e--) - if (GEQs[e].coef[i]) { - deleteGEQ(e); - } - tryAgain = (i < nVars); - } - deleteVariable(i); - } - } - } - - if (DEBUG) { - fprintf(outputFile, "\nafter free eliminations:\n"); - printProblem(); - fprintf(outputFile, "\n"); - } -} - - -void Problem::freeRedEliminations() { - int tryAgain = 1; - int i, e, e2; - int isRedVar[maxVars]; - int isDeadVar[maxVars]; - int isDeadGEQ[maxmaxGEQs]; - for (i = nVars; i > 0; i--) { - isRedVar[i] = 0; - isDeadVar[i] = 0; - } - for (e = nGEQs - 1; e >= 0; e--) { - isDeadGEQ[e] = 0; - if (GEQs[e].color) - for (i = nVars; i > 0; i--) - if (GEQs[e].coef[i] != 0) - isRedVar[i] = 1; - } - - while (tryAgain) { - tryAgain = 0; - for (i = nVars; i > 0; i--) - if (!isRedVar[i] && !isDeadVar[i]) { - for (e = nGEQs - 1; e >= 0; e--) - if (!isDeadGEQ[e] && GEQs[e].coef[i]) - break; - if (e < 0) - e2 = e; - else if (GEQs[e].coef[i] > 0) { - for (e2 = e - 1; e2 >= 0; e2--) - if (!isDeadGEQ[e2] && GEQs[e2].coef[i] < 0) - break; - } - else { - for (e2 = e - 1; e2 >= 0; e2--) - if (!isDeadGEQ[e2] && GEQs[e2].coef[i] > 0) - break; - } - if (e2 < 0) { - int e3; - for (e3 = nSUBs - 1; e3 >= 0; e3--) - if (SUBs[e3].coef[i]) - break; - if (e3 >= 0) - continue; - for (e3 = nEQs - 1; e3 >= 0; e3--) - if (EQs[e3].coef[i]) - break; - if (e3 >= 0) - continue; - if (DBUG) - fprintf(outputFile, "a free red elimination of %s\n", variable(i)); - for (; e >= 0; e--) - if (GEQs[e].coef[i]) - isDeadGEQ[e] = 1; - tryAgain = 1; - isDeadVar[i] = 1; - } - } - } - - for (e = nGEQs - 1; e >= 0; e--) - if (isDeadGEQ[e]) - deleteGEQ(e); - - for (i = nVars; i > safeVars; i--) - if (isDeadVar[i]) - deleteVariable(i); - - - if (DEBUG) { - fprintf(outputFile, "\nafter free red eliminations:\n"); - printProblem(); - fprintf(outputFile, "\n"); - } -} - -} // namespace diff --git a/omegalib/omega/src/omega_core/oc_util.cc b/omegalib/omega/src/omega_core/oc_util.cc deleted file mode 100644 index a7d21be..0000000 --- a/omegalib/omega/src/omega_core/oc_util.cc +++ /dev/null @@ -1,327 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - - Notes: - - History: -*****************************************************************************/ - -#include <omega/omega_core/oc_i.h> -#include <algorithm> - -namespace omega { - -void Problem:: problem_merge(Problem &p2) { - int newLocation[maxVars]; - int i,e2; - - resurrectSubs(); - p2.resurrectSubs(); - setExternals(); - p2.setExternals(); - - assert(safeVars == p2.safeVars); - if(DBUG) { - fprintf(outputFile,"Merging:\n"); - printProblem(); - fprintf(outputFile,"and\n"); - p2.printProblem(); - } - for(i=1; i<= p2.safeVars; i++) { - assert(p2.var[i] > 0) ; - newLocation[i] = forwardingAddress[p2.var[i]]; - } - for(; i<= p2.nVars; i++) { - int j = ++(nVars); - newLocation[i] = j; - zeroVariable(j); - var[j] = -1; - } - newLocation[0] = 0; - - for (e2 = p2.nEQs - 1; e2 >= 0; e2--) { - int e1 = newEQ(); - eqnnzero(&(EQs[e1]), nVars); - for(i=0;i<=p2.nVars;i++) - EQs[e1].coef[newLocation[i]] = p2.EQs[e2].coef[i]; - } - for (e2 = p2.nGEQs - 1; e2 >= 0; e2--) { - int e1 = newGEQ(); - eqnnzero(&(GEQs[e1]), nVars); - GEQs[e1].touched = 1; - for(i=0;i<=p2.nVars;i++) - GEQs[e1].coef[newLocation[i]] = p2.GEQs[e2].coef[i]; - } - int w = -1; - for (i = 1; i <= nVars; i++) - if (var[i] < 0) var[i] = w--; - if(DBUG) { - fprintf(outputFile,"to get:\n"); - printProblem(); - } -} - - - -void Problem::chainUnprotect() { - int i, e; - int unprotect[maxVars]; - int any = 0; - for (i = 1; i <= safeVars; i++) { - unprotect[i] = (var[i] < 0); - for (e = nSUBs - 1; e >= 0; e--) - if (SUBs[e].coef[i]) - unprotect[i] = 0; - } - for (i = 1; i <= safeVars; i++) if (unprotect[i]) any=1; - if (!any) return; - - if (DBUG) { - fprintf(outputFile, "Doing chain reaction unprotection\n"); - printProblem(); - for (i = 1; i <= safeVars; i++) - if (unprotect[i]) - fprintf(outputFile, "unprotecting %s\n", variable(i)); - } - for (i = 1; i <= safeVars; i++) - if (unprotect[i]) { - /* wild card */ - if (i < safeVars) { - int j = safeVars; - std::swap(var[i], var[j]); - for (e = nGEQs - 1; e >= 0; e--) { - GEQs[e].touched = 1; - std::swap(GEQs[e].coef[i], GEQs[e].coef[j]); - } - for (e = nEQs - 1; e >= 0; e--) - std::swap(EQs[e].coef[i], EQs[e].coef[j]); - for (e = nSUBs - 1; e >= 0; e--) - std::swap(SUBs[e].coef[i], SUBs[e].coef[j]); - std::swap(unprotect[i], unprotect[j]); - i--; - } - safeVars--; - } - if (DBUG) { - fprintf(outputFile, "After chain reactions\n"); - printProblem(); - } -} - -void Problem::resurrectSubs() { - if (nSUBs > 0 && !pleaseNoEqualitiesInSimplifiedProblems) { - int i, e, n, m,mbr; - mbr = 0; - for (e = nGEQs - 1; e >= 0; e--) if (GEQs[e].color) mbr=1; - for (e = nEQs - 1; e >= 0; e--) if (EQs[e].color) mbr=1; - if (nMemories) mbr = 1; - - assert(!mbr || mayBeRed); - - if (DBUG) { - fprintf(outputFile, "problem reduced, bringing variables back to life\n"); - if(mbr && !mayBeRed) fprintf(outputFile, "Red equations we don't expect\n"); - printProblem(); - } - if (DBUG && nEQs > 0) - fprintf(outputFile,"This is wierd: problem has equalities\n"); - - for (i = 1; i <= safeVars; i++) - if (var[i] < 0) { - /* wild card */ - if (i < safeVars) { - int j = safeVars; - std::swap(var[i], var[j]); - for (e = nGEQs - 1; e >= 0; e--) { - GEQs[e].touched = 1; - std::swap(GEQs[e].coef[i], GEQs[e].coef[j]); - } - for (e = nEQs - 1; e >= 0; e--) - std::swap(EQs[e].coef[i], EQs[e].coef[j]); - for (e = nSUBs - 1; e >= 0; e--) - std::swap(SUBs[e].coef[i], SUBs[e].coef[j]); - i--; - } - safeVars--; - } - - m = nSUBs; - n = nVars; - if (n < safeVars + m) - n = safeVars + m; - for (e = nGEQs - 1; e >= 0; e--) { - if (singleVarGEQ(&GEQs[e])) { - i = abs(GEQs[e].key); - if (i >= safeVars + 1) - GEQs[e].key += (GEQs[e].key > 0 ? m : -m); - } - else { - GEQs[e].touched = true; - GEQs[e].key = 0; - } - } - for (i = nVars; i >= safeVars + 1; i--) { - var[i + m] = var[i]; - for (e = nGEQs - 1; e >= 0; e--) - GEQs[e].coef[i + m] = GEQs[e].coef[i]; - for (e = nEQs - 1; e >= 0; e--) - EQs[e].coef[i + m] = EQs[e].coef[i]; - for (e = nSUBs - 1; e >= 0; e--) - SUBs[e].coef[i + m] = SUBs[e].coef[i]; - } - for (i = safeVars + m; i >= safeVars + 1; i--) { - for (e = nGEQs - 1; e >= 0; e--) GEQs[e].coef[i] = 0; - for (e = nEQs - 1; e >= 0; e--) EQs[e].coef[i] = 0; - for (e = nSUBs - 1; e >= 0; e--) SUBs[e].coef[i] = 0; - } - nVars += m; - safeVars += m; - for (e = nSUBs - 1; e >= 0; e--) - var[safeVars -m + 1 + e] = SUBs[e].key; - for (i = 1; i <= safeVars; i++) - forwardingAddress[var[i]] = i; - if (DBUG) { - fprintf(outputFile,"Ready to wake substitutions\n"); - printProblem(); - } - for (e = nSUBs - 1; e >= 0; e--) { - int neweq = newEQ(); - eqnncpy(&(EQs[neweq]), &(SUBs[e]), nVars); - EQs[neweq].coef[safeVars -m + 1 + e] = -1; - EQs[neweq].color = EQ_BLACK; - if (DBUG) { - fprintf(outputFile, "brought back: "); - printEQ(&EQs[neweq]); - fprintf(outputFile, "\n"); - } - } - nSUBs = 0; - - if (DBUG) { - fprintf(outputFile, "variables brought back to life\n"); - printProblem(); - } - } - - coalesce(); - recallRedMemories(); - cleanoutWildcards(); -} - - -void Problem::reverseProtectedVariables() { - int v1,v2,e,i; - coef_t t; - for (v1 = 1; v1 <= safeVars; v1++) { - v2 = safeVars+1-v1; - if (v2>=v1) break; - for(e=0;e<nEQs;e++) { - t = EQs[e].coef[v1]; - EQs[e].coef[v1] = EQs[e].coef[v2]; - EQs[e].coef[v2] = t; - } - for(e=0;e<nGEQs;e++) { - t = GEQs[e].coef[v1]; - GEQs[e].coef[v1] = GEQs[e].coef[v2]; - GEQs[e].coef[v2] = t; - GEQs[e].touched = 1; - } - for(e=0;e<nSUBs;e++) { - t = SUBs[e].coef[v1]; - SUBs[e].coef[v1] = SUBs[e].coef[v2]; - SUBs[e].coef[v2] = t; - } - } - - for (i = 1; i <= safeVars; i++) - forwardingAddress[var[i]] = i; - for (i = 0; i < nSUBs; i++) - forwardingAddress[SUBs[i].key] = -i - 1; -} - -void Problem::ordered_elimination(int symbolic) { - int i,j,e; - int isDead[maxmaxGEQs]; - for(e=0;e<nEQs;e++) isDead[e] = 0; - - if (!variablesInitialized) { - initializeVariables(); - } - - for(i=nVars;i>symbolic;i--) - for(e=0;e<nEQs;e++) - if (EQs[e].coef[i] == 1 || EQs[e].coef[i] == -1) { - for(j=nVars;j>i;j--) if (EQs[e].coef[j]) break; - if (i==j) { - doElimination(e, i); - isDead[e] = 1; - break; - } - } - - for(e=nEQs-1;e>=0;e--) - if (isDead[e]) { - nEQs--; - if (e < nEQs) eqnncpy(&EQs[e], &EQs[nEQs], nVars); - } - - for (i = 1; i <= safeVars; i++) - forwardingAddress[var[i]] = i; - for (i = 0; i < nSUBs; i++) - forwardingAddress[SUBs[i].key] = -i - 1; -} - - -coef_t Problem::checkSum() const { - coef_t cs; - int e; - cs = 0; - for(e=0;e<nGEQs;e++) { - coef_t c = GEQs[e].coef[0]; - cs += c*c*c; - } - return cs; -} - - -void Problem::coalesce() { - int e, e2, colors; - int isDead[maxmaxGEQs]; - int foundSomething = 0; - - - colors = 0; - for (e = 0; e < nGEQs; e++) - if (GEQs[e].color) - colors++; - if (colors < 2) - return; - for (e = 0; e < nGEQs; e++) - isDead[e] = 0; - for (e = 0; e < nGEQs; e++) - if (!GEQs[e].touched) - for (e2 = e + 1; e2 < nGEQs; e2++) - if (!GEQs[e2].touched && GEQs[e].key == -GEQs[e2].key - && GEQs[e].coef[0] == -GEQs[e2].coef[0]) { - int neweq = newEQ(); - eqnncpy(&EQs[neweq], &GEQs[e], nVars); - EQs[neweq].color = GEQs[e].color || GEQs[e2].color; - foundSomething++; - isDead[e] = 1; - isDead[e2] = 1; - } - for (e = nGEQs - 1; e >= 0; e--) - if (isDead[e]) { - deleteGEQ(e); - } - if (DEBUG && foundSomething) { - fprintf(outputFile, "Coalesced GEQs into %d EQ's:\n", foundSomething); - printProblem(); - } -} - -} // namespace diff --git a/omegalib/omega/src/pres_beaut.cc b/omegalib/omega/src/pres_beaut.cc deleted file mode 100644 index c23962a..0000000 --- a/omegalib/omega/src/pres_beaut.cc +++ /dev/null @@ -1,235 +0,0 @@ -#include <omega/pres_tree.h> -#include <omega/pres_conj.h> -#include <omega/Relation.h> -#include <omega/omega_i.h> - -///////////////////////// -// // -// Beautify functions // -// // -///////////////////////// - - -namespace omega { - -// -// f & true = f -// f | false = f -// f1 & f2 & ... & fn = Conjunct(f1,f2,...,fn) -// - -void Rel_Body::beautify() { - assert(children().length()==1); - set_parent(NULL,this); - - skip_finalization_check++; - formula()->beautify(); - Formula *child = formula(); - if(child->node_type()==Op_And && child->children().empty()) { - remove_child(child); - delete child; - add_conjunct(); - } - skip_finalization_check--; - - if(pres_debug) { - fprintf(DebugFile, "\n=== Beautified TREE ===\n"); - prefix_print(DebugFile); - } - assert(children().length()==1); -} - -void Formula::beautify() { - // copy list of children, as they may be removed as we work - List<Formula*> kiddies = myChildren; - - for(List_Iterator<Formula*> c(kiddies); c; c++) - (*c)->beautify(); -} - -void F_Exists::beautify() { - Formula::beautify(); - assert(children().length()==1); - - if(myLocals.empty()) { - // exists( : ***) - parent().remove_child(this); - parent().add_child(children().remove_front()); - delete this; - } - else if (children()[1]->node_type() == Op_And && children()[1]->children().empty()) { - // exists(*** : TRUE) --chun 6/4/2008 - parent().remove_child(this); - parent().add_child(children().remove_front()); - delete this; - } - else { - Formula *child = children().front(); - if(child->node_type() == Op_Conjunct || child->node_type() == Op_Exists) { - child->push_exists(myLocals); - parent().remove_child(this); - parent().add_child(child); - children().remove_front(); - delete this; - } - } -} - -void F_Forall::beautify() { - Formula::beautify(); - assert(children().length()==1); - - if(myLocals.empty()) { - parent().remove_child(this); - parent().add_child(children().remove_front()); - delete this; - } -} - - -// -// The Pix-free versions of beautify for And and Or are a bit -// less efficient than the previous code, as we keep moving -// things from one list to another, but they do not depend on -// knowing that a Pix is valid after the list is updated, and -// they can always be optimized later if necessary. -// - -void F_Or::beautify() { - Formula::beautify(); - - List<Formula*> uglies, beauties; - uglies.join(children()); assert(children().empty()); -#if ! defined NDEBUG - foreach(c,Formula*,uglies,c->set_parent(0)); -#endif - - while(!uglies.empty()) { - Formula *f = uglies.remove_front(); - if(f->node_type()==Op_And && f->children().empty() ) { - // smth | true = true - foreach(c,Formula*,uglies,delete c); - foreach(c,Formula*,beauties,delete c); - parent().remove_child(this); - parent().add_and(); - delete f; - delete this; - return; - } - else if(f->node_type()==Op_Or) { - // OR(f[1-m], OR(c[1-n])) = OR(f[1-m], c[1-n]) -#if ! defined NDEBUG - foreach(c,Formula*,f->children(),c->set_parent(0)); -#endif - uglies.join(f->children()); - delete f; - } - else - beauties.prepend(f); - } - - if(beauties.length()==1) { - beauties.front()->set_parent(&parent()); - parent().remove_child(this); - parent().add_child(beauties.remove_front()); - delete this; - } - else { - foreach(c,Formula*,beauties,(c->set_parent(this), - c->set_relation(relation()))); - assert(children().empty()); - children().join(beauties); - } -} - -void F_And::beautify() { - Formula::beautify(); - - Conjunct *conj = NULL; - - List<Formula*> uglies, beauties; - uglies.join(children()); assert(children().empty()); -#if ! defined NDEBUG - foreach(c,Formula*,uglies,c->set_parent(0)); -#endif - - while(!uglies.empty()) { - Formula *f = uglies.remove_front(); - if (f->node_type() == Op_Conjunct) { - if(conj==NULL) - conj = f->really_conjunct(); - else { - Conjunct *conj1 = merge_conjs(conj, f->really_conjunct(), MERGE_REGULAR); - delete f; - delete conj; - conj = conj1; - } - } - else if(f->node_type()==Op_Or && f->children().empty()) { - // smth & false = false - foreach(c,Formula*,uglies,delete c); - foreach(c,Formula*,beauties,delete c); - parent().remove_child(this); - parent().add_or(); - delete f; - delete conj; - delete this; - return; - } - else if(f->node_type()==Op_And) { - // AND(f[1-m], AND(c[1-n])) = AND(f[1-m], c[1-n]) -#if ! defined NDEBUG - foreach(c,Formula*,f->children(),c->set_parent(0)); -#endif - uglies.join(f->children()); - delete f; - } - else - beauties.prepend(f); - } - - if(conj!=NULL) - beauties.prepend(conj); - - if(beauties.length()==1) { - beauties.front()->set_parent(&parent()); - parent().remove_child(this); - parent().add_child(beauties.remove_front()); - delete this; - } - else { - foreach(c,Formula*,beauties,(c->set_parent(this), - c->set_relation(relation()))); - assert(children().empty()); - children().join(beauties); - } -} - -void F_Not::beautify() { - Formula::beautify(); - assert(children().length()==1); - Formula *child = children().front(); - - if(child->node_type()==Op_And && child->children().empty()) { - // Not TRUE = FALSE - parent().remove_child(this); - parent().add_or(); - delete this; - } - else if (child->node_type()==Op_Or && child->children().empty()) { - // Not FALSE = TRUE - parent().remove_child(this); - parent().add_and(); - delete this; - } -} - -void Conjunct::beautify() { - if(is_true()) { - parent().remove_child(this); - parent().add_and(); - delete this; - } -} - -} // namespace diff --git a/omegalib/omega/src/pres_cnstr.cc b/omegalib/omega/src/pres_cnstr.cc deleted file mode 100644 index a8ebd15..0000000 --- a/omegalib/omega/src/pres_cnstr.cc +++ /dev/null @@ -1,450 +0,0 @@ -#include <omega/pres_cnstr.h> -#include <omega/pres_conj.h> -#include <omega/Relation.h> -#include <omega/omega_i.h> - -namespace omega { - -Constraint_Handle::Constraint_Handle(Conjunct *_c, eqn **_eqns, int _e): - c(_c), eqns(_eqns), e(_e) { -} - -GEQ_Handle::GEQ_Handle(Conjunct *_c, int _e): - Constraint_Handle(_c,&(_c->problem->GEQs),_e) { -} - -bool Constraint_Handle::is_const(Variable_ID v) { - bool is_const=true; - for(Constr_Vars_Iter cvi(*this, false); cvi && is_const; cvi++) - is_const = ((*cvi).coef == 0 || ((*cvi).var == v && (*cvi).coef !=0)); - return is_const; -} - -bool Constraint_Handle::is_const_except_for_global(Variable_ID v){ - bool is_const=true; - for(Constr_Vars_Iter cvi(*this, false); cvi && is_const; cvi++) - if((*cvi).var->kind() != Global_Var) - is_const = ((*cvi).coef == 0 || ((*cvi).var == v && (*cvi).coef !=0)); - return is_const; -} - -bool EQ_Handle::operator==(const Constraint_Handle &that) { - Constraint_Handle &e1=*this; - const Constraint_Handle &e2=that; - int sign = 0; - for(Constr_Vars_Iter cvi(e1, false); cvi; cvi++) { - coef_t c1 = (*cvi).coef; - coef_t c2 = e2.get_coef((*cvi).var); - if (sign == 0) sign = (c1*c2>=0?1:-1); - if (sign*c1 != c2) return false; - } - assert(sign != 0); - { - for(Constr_Vars_Iter cvi(e2, false); cvi; cvi++) { - coef_t c1 = e1.get_coef((*cvi).var); - coef_t c2 = (*cvi).coef; - if (sign*c1 != c2) return false; - } - } - return sign * e1.get_const() == e2.get_const(); -} - -bool GEQ_Handle::operator==(const Constraint_Handle &that) { - Constraint_Handle &e1=*this; - const Constraint_Handle &e2=that; - for(Constr_Vars_Iter cvi(e1, false); cvi; cvi++) { - coef_t c1 = (*cvi).coef; - coef_t c2 = e2.get_coef((*cvi).var); - if (c1 != c2) return false; - } - { - for(Constr_Vars_Iter cvi(e2, false); cvi; cvi++) { - coef_t c1 = e1.get_coef((*cvi).var); - coef_t c2 = (*cvi).coef; - if (c1 != c2) return false; - } - } - return e1.get_const() == e2.get_const(); -} - - - - -void GEQ_Handle::negate() { - assert(! this->relation()->is_simplified()); - int i; - for(i=1; i<=c->problem->nVars; i++) { - (*eqns)[e].coef[i] = -(*eqns)[e].coef[i]; - } - (*eqns)[e].coef[0] = -(*eqns)[e].coef[0]-1; -} - -bool Constraint_Handle::has_wildcards() const { - Constr_Vars_Iter C(*this, true); - if (C.live()) { - assert(C.curr_var()->kind() == Wildcard_Var); - assert(C.curr_coef() != 0); - return 1; - } - return 0; -} - -int Constraint_Handle::max_tuple_pos() const { - int m = 0; - for( Constr_Vars_Iter C(*this, false); C.live() ; C.next()) { - switch (C.curr_var()->kind()) { - case Input_Var: - case Output_Var: { - int pos = C.curr_var()->get_position(); - if (m < pos) m = pos; - break; - } - default: - ; - } - } - return m; -} - -int Constraint_Handle::min_tuple_pos() const { - int m = 0; - for( Constr_Vars_Iter C(*this, false); C.live() ; C.next()) { - switch (C.curr_var()->kind()) { - case Input_Var: - case Output_Var: { - int pos = C.curr_var()->get_position(); - if (m == 0 || m > pos) m = pos; - break; - } - default: - ; - } - } - return m; -} - - -EQ_Handle::EQ_Handle(Conjunct *_c, int _e): Constraint_Handle(_c,&(_c->problem->EQs),_e) { -} - -// -// Update functions. -// -void Constraint_Handle::update_coef(Variable_ID D, coef_t I) { - assert(! this->relation()->is_simplified()); - assert(D != 0); - // The next two assertions are somewhat high-cost. -#if !defined(NDEBUG) - // skip_set_checks++; - assert((D->kind() != Input_Var || D->get_position() <= this->relation()->n_inp())); - assert((D->kind() != Output_Var || D->get_position() <= this->relation()->n_out())); - // skip_set_checks--; -#endif - int col = c->get_column(D); - (*eqns)[e].coef[col] += I; -} - -void Constraint_Handle::update_const(coef_t I) { - assert(! this->relation()->is_simplified()); - (*eqns)[e].coef[0] += I; -} - - -// update a coefficient of a variable that already exists in mappedvars - -void Constraint_Handle::update_coef_during_simplify(Variable_ID D, coef_t I) { - assert(D != 0); - int col = c->get_column(D); - (*eqns)[e].coef[col] += I; -} - -void Constraint_Handle::update_const_during_simplify(coef_t I) { - (*eqns)[e].coef[0] += I; -} - -// -// Get functions. -// - -coef_t Constraint_Handle::get_coef(Variable_ID v) const { - assert(this->relation()->is_simplified()); - assert(v != 0); - int col = c->find_column(v); - if(col == 0) { - return 0; - } - else { - return (*eqns)[e].coef[col]; - } -} - -coef_t Constraint_Handle::get_coef_during_simplify(Variable_ID v) const { - assert(v != 0); - int col = c->find_column(v); - if(col == 0) { - return 0; - } - else { - return (*eqns)[e].coef[col]; - } -} - -coef_t Constraint_Handle::get_const() const { - assert(this->relation()->is_simplified()); - return((*eqns)[e].coef[0]); -} - -coef_t Constraint_Handle::get_const_during_simplify() const { - return((*eqns)[e].coef[0]); -} - -Variable_ID Constraint_Handle::get_local(const Global_Var_ID G) { - return relation()->get_local(G); -} - -Variable_ID Constraint_Handle::get_local(const Global_Var_ID G, Argument_Tuple of) { - return relation()->get_local(G, of); -} - -void Constraint_Handle::finalize() { - c->n_open_constraints--; -} - -void Constraint_Handle::multiply(int multiplier) { - int i; - assert(! this->relation()->is_simplified()); - for(i=1; i<=c->problem->nVars; i++) { - (*eqns)[e].coef[i] = (*eqns)[e].coef[i] * multiplier; - } - (*eqns)[e].coef[0] = (*eqns)[e].coef[0] * multiplier; -} - -Rel_Body *Constraint_Handle::relation() const { - return c->relation(); -} - - -// -// Variables of constraint iterator. -// -Constr_Vars_Iter::Constr_Vars_Iter(const Constraint_Handle &ch, bool _wild_only): eqns(ch.eqns), e(ch.e), prob(ch.c->problem), vars(ch.c->mappedVars), wild_only(_wild_only) { - assert(vars.size() == prob->nVars); - for(current=1; current<=prob->nVars; current++) { - if((*eqns)[e].coef[current]!=0 && - (!wild_only || vars[current]->kind()==Wildcard_Var)) - return; - } -} - -int Constr_Vars_Iter::live() const { - return (current<=prob->nVars); -} - - -void Constr_Vars_Iter::operator++() { this->operator++(0); } - -void Constr_Vars_Iter::operator++(int) { - for(current++ ; current <=prob->nVars; current++) - if((*eqns)[e].coef[current]!=0 && - (!wild_only || vars[current]->kind()==Wildcard_Var)) - return; -} - - -Variable_ID Constr_Vars_Iter::curr_var() const { - assert(current <= prob->nVars); - return vars[current]; -} - -coef_t Constr_Vars_Iter::curr_coef() const { - assert(current <= prob->nVars); - return (*eqns)[e].coef[current]; -} - -Variable_Info Constr_Vars_Iter::operator*() const { - assert(current <= prob->nVars); - return Variable_Info(vars[current],(*eqns)[e].coef[current]); -} - -// -// Constraint iterator. -// -Constraint_Iterator Conjunct::constraints() { - return Constraint_Iterator(this); -} - -Constraint_Iterator::Constraint_Iterator(Conjunct *_c): c(_c), current(0), - last(c->problem->nGEQs-1), eqns(&(c->problem->GEQs)) { - if(!this->live()) (*this)++; // switch to EQ's if no GEQs -} - -int Constraint_Iterator::live() const { - return current <=last; -} - -void Constraint_Iterator::operator++() { - this->operator++(0); -} - -void Constraint_Iterator::operator++(int) { - if(++current > last) - if(eqns == &(c->problem->GEQs)) { // Switch to EQs - eqns = &(c->problem->EQs); - current = 0; - last = c->problem->nEQs-1; - } -} - -Constraint_Handle Constraint_Iterator::operator*() { - assert((c && eqns && current <= last) && "Constraint_Iterator::operator*: bad call"); - return Constraint_Handle(c,eqns,current); -} - -Constraint_Handle Constraint_Iterator::operator*() const { - assert((c && eqns && current <= last) && "Constraint_Iterator::operator*: bad call"); - return Constraint_Handle(c,eqns,current); -} - - -// -// EQ iterator. -// -EQ_Iterator Conjunct::EQs() { - return EQ_Iterator(this); -} - -EQ_Iterator::EQ_Iterator(Conjunct *_c) : c(_c) { - last = c->problem->nEQs-1; - current = 0; -} - -int EQ_Iterator::live() const { - return current <= last; -} - -void EQ_Iterator::operator++() { - this->operator++(0); -} - -void EQ_Iterator::operator++(int) { - current++; -} - -EQ_Handle EQ_Iterator::operator*() { - assert((c && current <= last) && "EQ_Iterator::operator*: bad call"); - return EQ_Handle(c,current); -} - -EQ_Handle EQ_Iterator::operator*() const { - assert((c && current <= last) && "EQ_Iterator::operator*: bad call"); - return EQ_Handle(c,current); -} - - -// -// GEQ iterator. -// -GEQ_Iterator Conjunct::GEQs() { - return GEQ_Iterator(this); -} - -GEQ_Iterator::GEQ_Iterator(Conjunct *_c) : c(_c) { - last = c->problem->nGEQs-1; - current = 0; -} - -int GEQ_Iterator::live() const { - return current <= last; -} - -void GEQ_Iterator::operator++() { - this->operator++(0); -} - -void GEQ_Iterator::operator++(int) { - current++; -} - - -GEQ_Handle GEQ_Iterator::operator*() { - assert((c && current <= last) && "GEQ_Iterator::operator*: bad call"); - return GEQ_Handle(c,current); -} - -GEQ_Handle GEQ_Iterator::operator*() const { - assert((c && current <= last) && "GEQ_Iterator::operator*: bad call"); - return GEQ_Handle(c,current); -} - - -void copy_constraint(Constraint_Handle H, const Constraint_Handle initial) { - // skip_set_checks++; -// assert(H.relation()->n_inp() == initial.relation()->n_inp()); -// assert(H.relation()->n_out() == initial.relation()->n_out()); - - H.update_const_during_simplify(initial.get_const_during_simplify()); - if (H.relation() == initial.relation()) { - for( Constr_Vars_Iter C(initial, false); C.live() ; C.next()) { - assert(C.curr_var()->kind()!= Forall_Var && - C.curr_var()->kind()!= Exists_Var); - if (C.curr_var()->kind()!= Wildcard_Var) - H.update_coef_during_simplify(C.curr_var(), C.curr_coef()); - else - // Must add a new wildcard, - // since they can't be used outside local Conjunct - H.update_coef_during_simplify(H.c->declare(), C.curr_coef()); - } - } - else { - Rel_Body *this_rel = H.relation(); - for( Constr_Vars_Iter C(initial, false); C.live() ; C.next()) { - switch (C.curr_var()->kind()) { - case Forall_Var: - case Exists_Var: - assert(0 && "Can't copy quantified constraints across relations"); - break; - case Wildcard_Var: - // for each wildcard var we see, create a new wildcard - // will lead to lots of wildcards, but Wayne likes it - // that way - { - H.update_coef_during_simplify(H.c->declare(), C.curr_coef()); - break; - } - case Input_Var: //use variable_ID of corresponding position - { - int pos = C.curr_var()->get_position(); - assert(this_rel->n_inp() >= pos); - Variable_ID V = this_rel->input_var(pos); - H.update_coef_during_simplify(V, C.curr_coef()); - break; - } - case Output_Var: //use variable_ID of corresponding position - { - int pos = C.curr_var()->get_position(); - assert(this_rel->n_out() >= pos); - Variable_ID V = this_rel->output_var(pos); - H.update_coef_during_simplify(V, C.curr_coef()); - break; - } - - case Global_Var: // get this Global's Var_ID in this relation - { - Variable_ID V; - Global_Var_ID G = C.curr_var()->get_global_var(); - if (G->arity() == 0) - V = this_rel->get_local(G); - else - V = this_rel->get_local(G,C.curr_var()->function_of()); - H.update_coef_during_simplify(V, C.curr_coef()); - break; - } - default: - assert(0 && "copy_constraint: variable of impossible type"); - } - } - } - // skip_set_checks--; -} - -} // namespace diff --git a/omegalib/omega/src/pres_col.cc b/omegalib/omega/src/pres_col.cc deleted file mode 100644 index 1569116..0000000 --- a/omegalib/omega/src/pres_col.cc +++ /dev/null @@ -1,104 +0,0 @@ -#include <omega/pres_conj.h> -#include <omega/RelBody.h> -#include <omega/omega_i.h> - -namespace omega { - -// -// Copy column fr_col of problem fp -// to column to_col of problem tp. -// Displacement for constraints in tp are start_EQ and start_GEQ. -// -void copy_column(Problem *tp, int to_col, - Problem *fp, int fr_col, - int start_EQ, int start_GEQ) { - checkVars(to_col); - assert(start_EQ + fp->nEQs <= tp->allocEQs); - assert(start_GEQ + fp->nGEQs <= tp->allocGEQs); - - int i; - for(i=0; i<fp->nEQs; i++) { - tp->EQs[i+start_EQ].coef[to_col] = fp->EQs[i].coef[fr_col]; - } - for(i=0; i<fp->nGEQs; i++) { - tp->GEQs[i+start_GEQ].coef[to_col] = fp->GEQs[i].coef[fr_col]; - } -} - -// -// Zero column to_col of problem tp. -// Displacement for constraints in to_conj are start_EQ and start_GEQ. -// Number of constraints to zero are no_EQ and no_GEQ. -// -void zero_column(Problem *tp, int to_col, - int start_EQ, int start_GEQ, - int no_EQs, int no_GEQs) { - assert(start_EQ + no_EQs <= tp->allocEQs); - assert(start_GEQ + no_GEQs <= tp->allocGEQs); - - int i; - for(i=0; i<no_EQs; i++) { - tp->EQs[i+start_EQ].coef[to_col] = 0; - } - for(i=0; i<no_GEQs; i++) { - tp->GEQs[i+start_GEQ].coef[to_col] = 0; - } -} - -// -// return column for D in conjunct -// -int Conjunct::get_column(Variable_ID D) { - int col = find_column(D); - if (col == 0) // if it does not already have a column assigned - col = map_to_column(D); - assert(col > 0); // Not substituted - return col; -} - -// -// Find column in conjunct. -// -int Conjunct::find_column(Variable_ID D) { - assert(D != 0); - int column = mappedVars.index(D); - - // If it has been through the omega core (variablesInitialized), - // and it exists in the problem, check to see if it has been forwarded. - // This will likely only be the case if substitutions have been done; - // that won't arise in user code, only in print_with_subs and the - // Substitutions class. - if (problem->variablesInitialized && column > 0) { - assert(problem->forwardingAddress[column] != 0); - column = problem->forwardingAddress[column]; - } - assert (column <= problem->nVars); - return column; -} - -// -// Create new column in conjunct. -// -int Conjunct::map_to_column(Variable_ID D) { - assert(D != 0); - // This heavy-duty assertion says that if you are trying to use a global - // var's local representative in a relation, that you have first told the - // relation that you are using it here. PUFS requires that we know - // all the function symbols that might be used in a relation. - // If one wanted to be less strict, one could just tell the relation - // that the global variable was being used. - assert(D->kind() != Global_Var || - (relation()->has_local(D->get_global_var(), D->function_of()) - && "Attempt to update global var without a local variable ID")); - - cols_ordered = false; // extremely important - checkVars(problem->nVars+2); - int col = ++problem->nVars; - mappedVars.append(D); - problem->forwardingAddress[col] = col; - problem->var[col] = col; - zero_column(problem, col, 0, 0, problem->nEQs, problem->nGEQs); - return col; -} - -} // namespace diff --git a/omegalib/omega/src/pres_conj.cc b/omegalib/omega/src/pres_conj.cc deleted file mode 100644 index f3f458d..0000000 --- a/omegalib/omega/src/pres_conj.cc +++ /dev/null @@ -1,1460 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - class Conjunct. - - Notes: - - History: -*****************************************************************************/ - -#include <omega/omega_core/oc.h> -#include <omega/pres_conj.h> -#include <omega/pres_cmpr.h> -#include <omega/Relation.h> -#include <omega/omega_i.h> -#include <set> - -namespace omega { - -int NR_CONJUNCTS, MAX_CONJUNCTS; - -/* - * Make a new wildcard variable, return WC number. - * Should be static to this file, but must be a friend of conjunct. - */ -int new_WC(Conjunct *nc, Problem *) { - Variable_ID wc = nc->declare(); - int wc_no = nc->map_to_column(wc); - return(wc_no); -} - - -const char* get_var_name(unsigned int col, void * void_conj) { -#if defined PRINT_COLUMN_NUMBERS - static char scum[512]; -#endif - Conjunct *c = (Conjunct *) void_conj; - if (col == 0) - return 0; - Variable_ID v = c->mappedVars[col]; - assert(v!=0); -#if defined PRINT_COLUMN_NUMBERS - strcpy(scum, v->char_name()); - sprintf(scum + strlen(scum), "(%d)", col); - return scum; -#endif - return v->char_name(); -} - -void Conjunct::promise_that_ub_solutions_exist(Relation &R) { -#ifndef NDEBUG - Relation verify=Relation(R, this); - assert(verify.is_upper_bound_satisfiable()); -#endif - verified = true; -} - - -int Conjunct::max_ufs_arity_of_set() { - int ma = 0, a; - for (Variable_ID_Iterator v(mappedVars); v; v++) - if ((*v)->kind() == Global_Var && (*v)->function_of() == Set_Tuple - && query_variable_used(*v)) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - - -int Conjunct::max_ufs_arity_of_in() { - int ma = 0, a; - for (Variable_ID_Iterator v(mappedVars); v; v++) - if ((*v)->kind() == Global_Var && (*v)->function_of() == Input_Tuple - && query_variable_used(*v)) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - - -int Conjunct::max_ufs_arity_of_out() { - int ma = 0, a; - for (Variable_ID_Iterator v(mappedVars); v; v++) - if ((*v)->kind() == Global_Var && (*v)->function_of() == Output_Tuple - && query_variable_used(*v)) { - a = (*v)->get_global_var()->arity(); - if (a > ma) - ma = a; - } - return ma; -} - - -bool Conjunct::is_unknown() const { - assert(problem || comp_problem); - return !exact && ((problem && problem->nEQs==0 && problem->nGEQs==0) || - (comp_problem && comp_problem->no_constraints())); -} - - -/* - * Remove black constraints from the problem. - * Make all the remaining red constraints black. - */ -void Conjunct::rm_color_constrs() { - int geqs = 0, eqs = 0; - - possible_leading_0s = -1; - guaranteed_leading_0s = -1; - leading_dir = 0; - - for(int i=0; i<problem->nGEQs; i++) { - if(problem->GEQs[i].color) { - if(geqs!=i) - eqnncpy(&problem->GEQs[geqs], &problem->GEQs[i], problem->nVars); - problem->GEQs[geqs].color = EQ_BLACK; - geqs++; - } - } - problem->nGEQs = geqs; - - for(int i=0; i<problem->nEQs; i++) { - if(problem->EQs[i].color) { - if(eqs!=i) - eqnncpy(&problem->EQs[eqs], &problem->EQs[i], problem->nVars); - problem->EQs[eqs].color = EQ_BLACK; - eqs++; - } - } - problem->nEQs = eqs; -} - - - -// -// Conjunct constructors. -// -Conjunct::Conjunct() : - F_Declaration(NULL, NULL), - mappedVars(0), - n_open_constraints(0), - cols_ordered(false), - simplified(false), - verified(false), - guaranteed_leading_0s(-1), - possible_leading_0s(-1), - leading_dir(0), - exact(true), - r_constrs(0) { - NR_CONJUNCTS++; - if (NR_CONJUNCTS>MAX_CONJUNCTS) MAX_CONJUNCTS = NR_CONJUNCTS; - problem = new Problem; - comp_problem = NULL; - problem->get_var_name = get_var_name; - problem->getVarNameArgs = (void *) this; -} - - -Conjunct::Conjunct(Formula *f, Rel_Body *r) : - F_Declaration(f,r), - mappedVars(0), - n_open_constraints(0), - cols_ordered(false), - simplified(false), - verified(false), - guaranteed_leading_0s(-1), - possible_leading_0s(-1), - leading_dir(0), - exact(true), - r_constrs(0) { - NR_CONJUNCTS++; - if (NR_CONJUNCTS>MAX_CONJUNCTS) MAX_CONJUNCTS = NR_CONJUNCTS; - problem = new Problem; - comp_problem = NULL; - problem->get_var_name = get_var_name; - problem->getVarNameArgs = (void *) this ; -} - -void internal_copy_conjunct(Conjunct* to, Conjunct* fr); - -// -// Copy Conjunct. -// -Conjunct* Conjunct::copy_conj_diff_relation(Formula *parent, Rel_Body *rel_body) { - Conjunct *new_conj; - if(problem && comp_problem==NULL) { - new_conj = new Conjunct(parent, rel_body); - internal_copy_conjunct(new_conj, this); - } - else if (problem==NULL && comp_problem) { - /* copy compressed conjunct */ - assert(0 && "copy compressed conjunct"); - new_conj = 0; - } - else { - assert(0 && "problem == NULL"); - new_conj = 0; - } - return new_conj; -} - - -void internal_copy_conjunct(Conjunct* to, Conjunct* fr) { - copy_conj_header(to, fr); - - // - // We repeat part of what is done by copy_conj_header(to, fr) by - // calling Problem::operator=(const Problem &). - // copy_conj_header should go away, but there is some code that still needs - // it in negate_conj. - // - to->r_constrs = fr->r_constrs; - to->simplified = fr->simplified; - to->verified = fr->verified; - to->guaranteed_leading_0s = fr->guaranteed_leading_0s; - to->possible_leading_0s = fr->possible_leading_0s; - to->leading_dir = fr->leading_dir; - // the following duplicates some work of the "copy_conj_header" brain damage - *to->problem = *fr->problem; - to->problem->getVarNameArgs = (void *)to; // important -} - - -// -// Copy Conjunct variable declarations -// and problem parameters but not problem itself. -// -void copy_conj_header(Conjunct* to, Conjunct* fr) { - free_var_decls(to->myLocals); to->myLocals.clear(); - - copy_var_decls(to->myLocals, fr->myLocals); - to->mappedVars = fr->mappedVars; - to->remap(); - reset_remap_field(fr->myLocals); - - to->cols_ordered = fr->cols_ordered; - to->r_constrs = fr->r_constrs; - to->simplified = fr->simplified; - to->verified = fr->verified; - to->guaranteed_leading_0s = fr->guaranteed_leading_0s; - to->possible_leading_0s = fr->possible_leading_0s; - to->leading_dir = fr->leading_dir; - to->n_open_constraints = fr->n_open_constraints; - to->exact=fr->exact; - - Problem *fp = fr->problem; - Problem *tp = to->problem; - tp->nVars = fp->nVars; - tp->safeVars = fp->safeVars; - tp->variablesInitialized = fp->variablesInitialized; - tp->variablesFreed = fp->variablesFreed; - for(int i=1; i<=maxVars; i++) { // only need nVars of var - tp->forwardingAddress[i] = fp->forwardingAddress[i]; - tp->var[i] = fp->var[i]; - } - to->problem->get_var_name = get_var_name; - to->problem->getVarNameArgs = (void *)to ; -} - - -void Conjunct::reverse_leading_dir_info() { - leading_dir *= -1; -} - - -void Conjunct::enforce_leading_info(int guaranteed, int possible, int dir) { - skip_finalization_check++; - guaranteed_leading_0s = guaranteed; - - int d = min(relation()->n_inp(),relation()->n_out()); - - assert(0 <= guaranteed); - assert(guaranteed <= possible); - assert(possible <= d); - - for(int i = 1; i <= guaranteed; i++) { - EQ_Handle e = add_EQ(); - e.update_coef_during_simplify(input_var(i), -1); - e.update_coef_during_simplify(output_var(i), 1); - e.finalize(); - } - - - if (guaranteed == possible && guaranteed >= 0 && possible+1 <= d && dir) { - GEQ_Handle g = add_GEQ(); - if (dir > 0) { - g.update_coef_during_simplify(input_var(possible+1), -1); - g.update_coef_during_simplify(output_var(possible+1), 1); - } - else { - g.update_coef_during_simplify(input_var(possible+1), 1); - g.update_coef_during_simplify(output_var(possible+1), -1); - } - g.update_const_during_simplify(-1); - g.finalize(); - possible_leading_0s = possible; - leading_dir = dir; - } - else { - possible_leading_0s = d; - leading_dir = 0; - } - - skip_finalization_check--; -#if ! defined NDEBUG - assert_leading_info(); -#endif -} - - -void Conjunct::invalidate_leading_info(int changed) { - if (changed == -1) { - guaranteed_leading_0s = possible_leading_0s = -1; - leading_dir = 0; - } - else { - int d = min(relation()->n_inp(), relation()->n_out()); - assert(1 <= changed && changed <= d); - if (possible_leading_0s == changed -1) { - possible_leading_0s = d; - } - guaranteed_leading_0s = min(guaranteed_leading_0s,changed-1); - } -#if ! defined NDEBUG - assert_leading_info(); -#endif -} - - -int Conjunct::leading_dir_valid_and_known() { - if (relation()->is_set()) { - return 0; - } - // if we know leading dir, we can rule out extra possible 0's - assert(leading_dir == 0 || - possible_leading_0s == guaranteed_leading_0s); - - return (possible_leading_0s == guaranteed_leading_0s && - possible_leading_0s >= 0 && - possible_leading_0s < min(relation()->n_inp(),relation()->n_out()) - && leading_dir); -} - - -#if ! defined NDEBUG -void Conjunct::assert_leading_info() { - if (relation()->is_set()) { - return; - } - - int d = min(relation()->n_inp(), relation()->n_out()); - - if ( guaranteed_leading_0s == -1 - && guaranteed_leading_0s == possible_leading_0s) - assert(leading_dir == 0); - - if(leading_dir != 0 && - possible_leading_0s != guaranteed_leading_0s) { - use_ugly_names++; - prefix_print(DebugFile); - use_ugly_names--; - } - - assert(leading_dir == 0 || possible_leading_0s == guaranteed_leading_0s); - - assert(possible_leading_0s <= d && guaranteed_leading_0s <= d); - - assert(possible_leading_0s == -1 || guaranteed_leading_0s <= possible_leading_0s); - - // check that there must be "guaranteed_leading_0s" 0s - int carried_level; - for (carried_level = 1; carried_level <= guaranteed_leading_0s; carried_level++) { - Variable_ID in = input_var(carried_level), - out = output_var(carried_level); - coef_t lb, ub; - bool guar; - query_difference(out, in, lb, ub, guar); - if (lb != 0 && ub != 0) { - // probably "query_difference" is just approximate - // add the negation of leading_dir and assert that - // the result is unsatisfiable; - // add in > out (in-out-1>=0) and assert unsatisfiable. - - Conjunct *test = copy_conj_same_relation(); - test->problem->turnRedBlack(); - skip_finalization_check++; - - GEQ_Handle g = test->add_GEQ(); - g.update_coef_during_simplify(in, -1); - g.update_coef_during_simplify(out, 1); - g.update_const_during_simplify(-1); - g.finalize(); - assert(!simplify_conj(test, true, 0, 0)); - // test was deleted by simplify_conj, as it was FALSE - - test = copy_conj_same_relation(); - test->problem->turnRedBlack(); - g = test->add_GEQ(); - g.update_coef_during_simplify(in, 1); - g.update_coef_during_simplify(out, -1); - g.update_const_during_simplify(-1); - g.finalize(); - assert(!simplify_conj(test, true, 0, 0)); - // test was deleted by simplify_conj, as it was FALSE - - skip_finalization_check--; - } - } - - carried_level = possible_leading_0s+1; - - // check that there can't be another - if (guaranteed_leading_0s == possible_leading_0s - && possible_leading_0s >= 0 && - carried_level <= min(relation()->n_inp(), relation()->n_out())) { - Variable_ID in = input_var(carried_level), - out = output_var(carried_level); - coef_t lb, ub; - bool guar; - query_difference(out, in, lb, ub, guar); - if (lb <= 0 && ub >= 0) { - // probably "query_difference" is just approximate - // add a 0 and see if its satisfiable - - Conjunct *test = copy_conj_same_relation(); - test->problem->turnRedBlack(); - skip_finalization_check++; - - EQ_Handle e = test->add_EQ(); - e.update_coef_during_simplify(in, -1); - e.update_coef_during_simplify(out, 1); - e.finalize(); - assert(!simplify_conj(test, true, 0, 0)); - // test was deleted by simplify_conj, as it was FALSE - - skip_finalization_check--; - } - } - - // check leading direction info - if (leading_dir_valid_and_known()) { - Variable_ID in = input_var(guaranteed_leading_0s+1), - out = output_var(guaranteed_leading_0s+1); - coef_t lb, ub; - bool guar; - query_difference(out, in, lb, ub, guar); - if ((leading_dir < 0 && ub >= 0) || - (leading_dir > 0 && lb <= 0)) { - // probably "query_difference" is just approximate - // add the negation of leading_dir and assert that - // the result is unsatisfiable; - // eg for leading_dir = +1 (in must be < out), - // add in >= out (in-out>=0) and assert unsatisfiable. - - Conjunct *test = copy_conj_same_relation(); - test->problem->turnRedBlack(); - skip_finalization_check++; - - GEQ_Handle g = test->add_GEQ(); - g.update_coef_during_simplify(in, leading_dir); - g.update_coef_during_simplify(out, -leading_dir); - g.finalize(); - - assert(!simplify_conj(test, true, 0, 0)); - // test was deleted by simplify_conj, as it was FALSE - - skip_finalization_check--; - } - } -} -#endif - - -Variable_ID Conjunct::declare(Const_String s) { - return do_declare(s, Wildcard_Var); -} - -Variable_ID Conjunct::declare() { - return do_declare(Const_String(), Wildcard_Var); -} - -Variable_ID Conjunct::declare(Variable_ID v) { - return do_declare(v->base_name, Wildcard_Var); -} - -Conjunct* Conjunct::really_conjunct() { - return this; -} - - -Variable_ID_Tuple* Conjunct::variables() { - return &mappedVars; -} - -Stride_Handle Conjunct::add_stride(int step, int preserves_level) { - assert_not_finalized(); - Variable_ID wild = declare(); - int c; - c = problem->newEQ(); - simplified = false; - verified = false; - if (! preserves_level) { - if (leading_dir == 0) - possible_leading_0s = -1; - // otherwise we must still have leading_dir, and thus no more 0's - } - problem->EQs[c].color = EQ_BLACK; - eqnnzero(&problem->EQs[c],problem->nVars); - n_open_constraints++; - EQ_Handle h = EQ_Handle(this, c); - h.update_coef(wild,step); - return h; -} - -// This should only be used to copy constraints from simplified relations, -// i.e. there are no quantified variables in c except wildcards. -EQ_Handle Conjunct::add_EQ(const Constraint_Handle &c, int /*preserves_level, currently unused*/) { - EQ_Handle e = add_EQ(); - copy_constraint(e,c); - return e; -} - - -EQ_Handle Conjunct::add_EQ(int preserves_level) { - assert_not_finalized(); - int c; - c = problem->newEQ(); - simplified = false; - verified = false; - if (!preserves_level) { - if (leading_dir == 0) - possible_leading_0s = -1; - // otherwise we must still have leading_dir, and thus no more 0's - } - problem->EQs[c].color = EQ_BLACK; - eqnnzero(&problem->EQs[c],problem->nVars); - n_open_constraints++; - return EQ_Handle(this, c); -} - - -// This should only be used to copy constraints from simplified relations, -// i.e. there are no quantified variables in c except wildcards. -GEQ_Handle Conjunct::add_GEQ(const Constraint_Handle &c, int /*preserves_level, currently unused */) { - GEQ_Handle g = add_GEQ(); - copy_constraint(g,c); - return g; -} - - -GEQ_Handle Conjunct::add_GEQ(int preserves_level) { - assert_not_finalized(); - int c; - c = problem->newGEQ(); - simplified = false; - verified = false; - if (!preserves_level) { - if (leading_dir == 0) - possible_leading_0s = -1; - // otherwise we must still have leading_dir, and thus no more 0's - } - problem->GEQs[c].color = EQ_BLACK; - eqnnzero(&problem->GEQs[c],problem->nVars); - n_open_constraints++; - return GEQ_Handle(this, c); -} - - -Conjunct *Conjunct::find_available_conjunct() { - return this; -} - - -bool Conjunct::can_add_child() { - return false; -} - - -void Conjunct::combine_columns() { - int nvars = mappedVars.size(),i,j,k; - - for(i=1; i<=nvars; i++) - for(j=i+1; j<=nvars; j++) { - // If they are the same, copy into the higher numbered column. - // That way we won't have problems with already-merged columns later - assert(i != j); - if(mappedVars[i] == mappedVars[j]) { - if (pres_debug) - fprintf(DebugFile, "combine_col:Actually combined %d,%d\n", - j,i); - for(k=0; k<problem->nEQs; k++) - problem->EQs[k].coef[j] += problem->EQs[k].coef[i]; - for(k=0; k<problem->nGEQs; k++) - problem->GEQs[k].coef[j] += problem->GEQs[k].coef[i]; - zero_column(problem, i, 0, 0, problem->nEQs, problem->nGEQs); - // Create a wildcard w/no constraints. temporary measure, - // so we don't have to shuffle columns - Variable_ID zero_var = declare(); - mappedVars[i] = zero_var; - break; - } - } -} - - -void Conjunct::finalize() { -// Debugging version of finalize; copy the conjunct and free the old one, -// so that purify will catch accesses to finalized constraints -// assert(n_open_constraints == 0); -// Conjunct *C = this->copy(); -// parent().replace_child(this, C); -// delete this; -} - -Conjunct::~Conjunct() { - NR_CONJUNCTS--; - delete problem; - delete comp_problem; -} - - -// -// Cost = # of terms in DNF when negated -// or CantBeNegated if too bad (i.e. bad wildcards) -// or AvoidNegating if it would be inexact -// -// Also check pres_legal_negations -- -// If set to any_negation, just return the number -// If set to one_geq_or_stride, return CantBeNegated if c > 1 -// If set to one_geq_or_eq, return CantBeNegated if not a single geq or eq -// - -int Conjunct::cost() { - int c; - int i; - int wc_no; - int wc_j = 0; // initialize to shut up the compiler - - // cost 1 per GEQ, and if 1 GEQ has wildcards, +2 for each of them - - c = problem->nGEQs; - for(i=0; i<problem->nGEQs; i++) { - wc_no = 0; - for(int j=1; j<=problem->nVars; j++) if(problem->GEQs[i].coef[j]!=0) { - Variable_ID v = mappedVars[j]; - if(v->kind()==Wildcard_Var) { - wc_no++; - c+=2; - wc_j = j; - } - } - if (wc_no > 1) return CantBeNegated; - } - - for(i=0; i<problem->nEQs; i++) { - wc_no = 0; - for(int j=1; j<=problem->nVars; j++) if(problem->EQs[i].coef[j]!=0) { - Variable_ID v = mappedVars[j]; - if(v->kind()==Wildcard_Var) { - wc_no++; - wc_j = j; - } - } - - if (wc_no == 0) // no wildcards - c+=2; - else if (wc_no == 1) { // one wildcard - maybe we can negate it - int i2; - for(i2=0; i2<problem->nEQs; i2++) - if(i != i2 && problem->EQs[i2].coef[wc_j]!=0) break; - if (i2 >= problem->nEQs) // Stride constraint - c++; - else // We are not ready to handle this - return CantBeNegated; - } - else // Multiple wildcards - return CantBeNegated; - } - if (!exact) return AvoidNegating; - - if (pres_legal_negations == any_negation) { - return c; - } - else { - // single GEQ ok either way as long as no wildcards - // (we might be able to handle wildcards, but I haven't thought about it) - if (problem->nEQs==0 && problem->nGEQs<=1) { - if (c>1) { // the GEQ had a wildcard -- I'm not ready to go here. - if (pres_debug > 0) { - fprintf(DebugFile, - "Refusing to negate a GEQ with wildcard(s)" - " under restricted_negation; " - "It may be possible to fix this.\n"); - } - return CantBeNegated; - } - return c; - } - else if (problem->nEQs==1 && problem->nGEQs==0) { - assert(c == 1 || c == 2); - - if (pres_legal_negations == one_geq_or_stride) { - if (c == 1) - return c; // stride constraint is ok - else { - if (pres_debug > 0) { - fprintf(DebugFile, "Refusing to negate a non-stride EQ under current pres_legal_negations.\n"); - } - return CantBeNegated; - } - } - else { - assert(pres_legal_negations == one_geq_or_eq); - return c; - } - } - else { - if (pres_debug > 0) { - fprintf(DebugFile, "Refusing to negate multiple constraints under current pres_legal_negations.\n"); - } - return CantBeNegated; - } - } -} - - -// -// Merge CONJ1 & CONJ2 -> CONJ. -// Action: MERGE_REGULAR or MERGE_COMPOSE: regular merge. -// MERGE_GIST make constraints from conj2 red, i.e. -// Gist Conj2 given Conj1 (T.S. comment). -// Reorder columns as we go. -// Merge the columns for identical variables. -// We assume we know nothing about the ordering of conj1, conj2. -// -// Does not consume its arguments -// -// Optional 4th argument gives the relation for the result - if -// null, conj1 and conj2 must have the same relation, which will -// be used for the result -// -// The only members of conj1 and conj2 that are used are: problem, -// mappedVars and declare(), and the leading_0s/leading_dir members -// and exact. -// -// NOTE: variables that are shared between conjuncts are necessarily -// declared above, not here; so we can simply create columns for the -// locals of each conj after doing the protected vars. -// -Conjunct* merge_conjs(Conjunct* conj1, Conjunct* conj2, - Merge_Action action, Rel_Body *body) { - // body must be set unless both conjuncts are from the same relation - assert(body || conj1->relation() == conj2->relation()); - - if (body == conj1->relation() && body == conj2->relation()) - body = 0; // we test this later to see if there is a new body - - Conjunct *conj3 = new Conjunct(NULL, body ? body : conj2->relation()); - Problem *p1 = conj1->problem; - Problem *p2 = conj2->problem; - Problem *p3 = conj3->problem; - int i; - - if (action != MERGE_COMPOSE) { - conj1->assert_leading_info(); - conj2->assert_leading_info(); - } - - if(pres_debug>=2) { - use_ugly_names++; - fprintf(DebugFile, ">>> Merge conjuncts: Merging%s:\n", - (action == MERGE_GIST ? " for gist" : - (action == MERGE_COMPOSE ? " for composition" : ""))); - conj1->prefix_print(DebugFile); - conj2->prefix_print(DebugFile); - fprintf(DebugFile, "\n"); - use_ugly_names--; - } - - - - switch(action) { - case MERGE_REGULAR: - case MERGE_COMPOSE: - conj3->exact=conj1->exact && conj2->exact; - break; - case MERGE_GIST: - conj3->exact=conj2->exact; - break; - } - - if (action == MERGE_COMPOSE) { - conj3->guaranteed_leading_0s=min(conj1->guaranteed_leading_0s, - conj2->guaranteed_leading_0s); - conj3->possible_leading_0s=min((unsigned int) conj1->possible_leading_0s, - (unsigned int) conj2->possible_leading_0s); - - assert( conj3->guaranteed_leading_0s <= conj3->possible_leading_0s); - - // investigate leading_dir - not well tested code - if (conj1->guaranteed_leading_0s<0 || conj2->guaranteed_leading_0s<0) { - conj3->leading_dir = 0; - } - else if (conj1->guaranteed_leading_0s == conj2->guaranteed_leading_0s) - if (conj1->leading_dir == conj2->leading_dir) - conj3->leading_dir = conj1->leading_dir; - else - conj3->leading_dir = 0; - else if (conj1->guaranteed_leading_0s < conj2->guaranteed_leading_0s) { - conj3->leading_dir = conj1->leading_dir; - } - else { // (conj1->guaranteed_leading_0s > conj2->guaranteed_leading_0s) - conj3->leading_dir = conj2->leading_dir; - } - - if (conj3->leading_dir == 0) - conj3->possible_leading_0s = min(conj3->relation()->n_inp(), - conj3->relation()->n_out()); - - assert(conj3->guaranteed_leading_0s <= conj3->possible_leading_0s); - assert(conj3->guaranteed_leading_0s == conj3->possible_leading_0s - || !conj3->leading_dir); - } - else if (!body) { // if body is set, who knows what leading 0's mean? - assert(action == MERGE_REGULAR || action == MERGE_GIST); - - int feasable = 1; - - int redAndBlackGuarLeadingZeros = max(conj1->guaranteed_leading_0s, - conj2->guaranteed_leading_0s); - if (action == MERGE_REGULAR) - conj3->guaranteed_leading_0s= redAndBlackGuarLeadingZeros; - else conj3->guaranteed_leading_0s=conj1->guaranteed_leading_0s; - - conj3->possible_leading_0s=min((unsigned)conj1->possible_leading_0s, - (unsigned)conj2->possible_leading_0s); - if (conj3->possible_leading_0s < redAndBlackGuarLeadingZeros) - feasable = 0; - else if (conj3->guaranteed_leading_0s == -1 - || conj3->possible_leading_0s > redAndBlackGuarLeadingZeros) - conj3->leading_dir = 0; - else { - if (conj1->guaranteed_leading_0s == conj2->guaranteed_leading_0s) - if (!conj1->leading_dir_valid_and_known()) - conj3->leading_dir = conj2->leading_dir; - else if (!conj2->leading_dir_valid_and_known()) - conj3->leading_dir = conj1->leading_dir; - else if (conj1->leading_dir * conj2->leading_dir > 0) - conj3->leading_dir = conj1->leading_dir; // 1,2 same dir - else - feasable = 0; // 1 and 2 go in opposite directions - else if (conj3->possible_leading_0s != conj3->guaranteed_leading_0s) - conj3->leading_dir = 0; - else if (conj1->guaranteed_leading_0s<conj2->guaranteed_leading_0s) { - assert(!conj1->leading_dir_valid_and_known()); - conj3->leading_dir = conj2->leading_dir; - } - else { - assert(!conj2->leading_dir_valid_and_known()); - conj3->leading_dir = conj1->leading_dir; - } - } - - if (!feasable) { - if(pres_debug>=2) - fprintf(DebugFile, ">>> Merge conjuncts: quick check proves FALSE.\n"); - - // return 0 = 1 - - int e = p3->newEQ(); - p3->EQs[e].color = EQ_BLACK; - p3->EQs[e].touched = 1; - p3->EQs[e].key = 0; - p3->EQs[e].coef[0] = 1; - - // Make sure these don't blow later assertions - conj3->possible_leading_0s = conj3->guaranteed_leading_0s = -1; - conj3->leading_dir = 0; - - return conj3; - } - } - else { // provided "body" argument but not composing, leading 0s meaningless - conj3->guaranteed_leading_0s = conj3->possible_leading_0s = -1; - conj3->leading_dir = 0; - } - - // initialize omega stuff - - for(i=0; i<p1->nGEQs+p2->nGEQs; i++) { - int e = p3->newGEQ(); - assert(e == i); - p3->GEQs[e].color = EQ_BLACK; - p3->GEQs[e].touched = 1; - p3->GEQs[e].key = 0; - } - for(i=0; i<p1->nEQs+p2->nEQs; i++) { - int e = p3->newEQ(); - assert(e == i); - p3->EQs[e].color = EQ_BLACK; - p3->EQs[e].touched = 1; - p3->EQs[e].key = 0; - } - - assert(p3->nGEQs == p1->nGEQs + p2->nGEQs); - assert(p3->nEQs == p1->nEQs + p2->nEQs); - - // flag constraints from second constraint as red, if necessary - if (action == MERGE_GIST) { - for(i=0; i<p2->nEQs; i++) { - p3->EQs[i+p1->nEQs].color = EQ_RED; - } - for(i=0; i<p2->nGEQs; i++) { - p3->GEQs[i+p1->nGEQs].color = EQ_RED; - } - } - - // copy constant column - copy_column(p3, 0, p1, 0, 0, 0); - copy_column(p3, 0, p2, 0, p1->nEQs, p1->nGEQs); - - // copy protected variables column from conj1 - int new_col = 1; - Variable_Iterator VI(conj1->mappedVars); - for(i=1; VI; VI++, i++) { - Variable_ID v = *VI; - if(v->kind() != Wildcard_Var) { - conj3->mappedVars.append(v); - int fr_ix = i; - copy_column(p3, new_col, p1, fr_ix, 0, 0); - zero_column(p3, new_col, p1->nEQs, p1->nGEQs, - p2->nEQs, p2->nGEQs); - new_col++; - } - } - - // copy protected variables column from conj2, - // checking if conj3 already has this variable from conj1 - for(i=1; i <= conj2->mappedVars.size(); i++) { - Variable_ID v = conj2->mappedVars[i]; - if(v->kind() != Wildcard_Var) { - int to_ix = conj3->mappedVars.index(v); - int fr_ix = i; - if(to_ix > 0) { - // use old column - copy_column(p3, to_ix, p2, fr_ix, p1->nEQs, p1->nGEQs); - } - else { - // create new column - conj3->mappedVars.append(v); - zero_column(p3, new_col, 0, 0, p1->nEQs, p1->nGEQs); - copy_column(p3, new_col, p2, fr_ix, p1->nEQs, p1->nGEQs); - new_col++; - } - } - } - - p3->safeVars = new_col-1; - - // copy wildcards from conj1 - for(i=1; i <= conj1->mappedVars.size(); i++) { - Variable_ID v = conj1->mappedVars[i]; - if(v->kind() == Wildcard_Var) { - Variable_ID nv = conj3->declare(v); - conj3->mappedVars.append(nv); - int fr_ix = i; - copy_column(p3, new_col, p1, fr_ix, 0, 0); - zero_column(p3, new_col, p1->nEQs, p1->nGEQs, - p2->nEQs, p2->nGEQs); - new_col++; - } - } - - // copy wildcards from conj2 - for(i=1; i <= conj2->mappedVars.size(); i++) { - Variable_ID v = conj2->mappedVars[i]; - if(v->kind() == Wildcard_Var) { - Variable_ID nv = conj3->declare(v); - conj3->mappedVars.append(nv); - int fr_ix = i; - zero_column(p3, new_col, 0, 0, p1->nEQs, p1->nGEQs); - copy_column(p3, new_col, p2, fr_ix, p1->nEQs, p1->nGEQs); - new_col++; - } - } - - p3->nVars = new_col-1; - checkVars(p3->nVars); - p3->variablesInitialized = 1; - for(i=1; i<=p3->nVars; i++) - p3->var[i] = p3->forwardingAddress[i] = i; - - conj3->cols_ordered = true; - conj3->simplified = false; - conj3->verified = false; - - if(pres_debug>=2) { - use_ugly_names++; - fprintf(DebugFile, ">>> Merge conjuncts: result is:\n"); - conj3->prefix_print(DebugFile); - fprintf(DebugFile, "\n"); - use_ugly_names--; - } - - conj3->assert_leading_info(); - - return conj3; -} - - - - -// -// Reorder variables by swapping. -// cols_ordered is just a hint that thorough check needs to be done. -// Sets _safeVars. -// -void Conjunct::reorder() { - if(!cols_ordered) { - int var_no = mappedVars.size(); - int first_wild = 1; - int last_prot = var_no; - while(first_wild < last_prot) { - for(; first_wild<=var_no && mappedVars[first_wild]->kind()!=Wildcard_Var; - first_wild++) ; - for(; last_prot>=1 && mappedVars[last_prot]->kind()==Wildcard_Var; - last_prot--) ; - if(first_wild < last_prot) { - problem->swapVars(first_wild, last_prot); - problem->variablesInitialized = false; - Var_Decl *t = mappedVars[first_wild]; - mappedVars[first_wild] = mappedVars[last_prot]; - mappedVars[last_prot] = t; - if(pres_debug) { - fprintf(DebugFile, "<<<OrderConjCols>>>: swapped var-s %d and %d\n", first_wild, last_prot); - } - } - } - - int safe_vars; - for(safe_vars=0; - safe_vars<var_no && mappedVars[safe_vars+1]->kind()!=Wildcard_Var; - safe_vars++) ; - -#if ! defined NDEBUG - for(int s = safe_vars ; s<var_no ; s++ ) { - assert(mappedVars[s+1]->kind() == Wildcard_Var); - } -#endif - - problem->safeVars = safe_vars; - cols_ordered = true; - } -} - - - -// Wherever possible, move function symbols to input tuple. -// This ensures that if in == out, red F(in) = x is redundant -// with black F(out) = x - -void Conjunct::move_UFS_to_input() { - if (guaranteed_leading_0s > 0) { - std::set<Global_Var_ID> already_done; - int remapped = 0; - skip_finalization_check++; - Rel_Body *body = relation(); - - assert(body); - - for (Variable_ID_Iterator func(*body->global_decls()); func; func++) { - Global_Var_ID f = (*func)->get_global_var(); - if (f->arity() <= guaranteed_leading_0s) - if (already_done.find(f) == already_done.end() && - body->has_local(f, Input_Tuple) && - body->has_local(f, Output_Tuple)) { - already_done.insert(f); - - // equatE f(in) = f(out) - Variable_ID f_in = body->get_local(f, Input_Tuple); - Variable_ID f_out = body->get_local(f, Output_Tuple); - if (f_in != f_out) { - EQ_Handle e = add_EQ(1); - - e.update_coef_during_simplify(f_in, -1); - e.update_coef_during_simplify(f_out, 1); - - f_out->remap = f_in; - remapped = 1; - } - } - } - - if (remapped) { - remap(); - combine_columns(); - reset_remap_field(*body->global_decls()); - remapped = 0; - } - - skip_finalization_check--; - } -} - - - - - -// -// Simplify CONJ. -// Return TRUE if there are solutions, FALSE -- no solutions. -// -int simplify_conj(Conjunct* conj, int ver_sim, int simplificationEffort, int color) { - if (conj->verified - && simplificationEffort <= conj->r_constrs - && (conj->simplified || simplificationEffort < 0) - && !color) { - if(pres_debug) { - fprintf(DebugFile, "$$$ Redundant simplify_conj ignored (%d,%d,%d)\n",ver_sim,simplificationEffort,color); - conj->prefix_print(DebugFile); - } - return 1; - } - - if (simplificationEffort < 0) simplificationEffort = 0; - conj->move_UFS_to_input(); - conj->reorder(); - - Problem *p = conj->problem; - - use_ugly_names++; - - int i; - for(i=0; i<p->nGEQs; i++) { - p->GEQs[i].touched = 1; - } - for(i=0; i<p->nEQs; i++) { - p->EQs[i].touched = 1; - } - - if(pres_debug) { - fprintf(DebugFile, "$$$ simplify_conj (%d,%d,%d)[\n",ver_sim,simplificationEffort,color); - conj->prefix_print(DebugFile); - } - - assert(conj->cols_ordered); - - int ret_code; - assert(p == conj->problem); - if(!color) { - ret_code = conj->simplifyProblem(ver_sim && ! conj->verified,0,simplificationEffort); - } - else { - ret_code = conj->redSimplifyProblem(simplificationEffort,1); - ret_code = (ret_code==redFalse ? 0 : 1); - } - assert(p->nSUBs==0); - - if(ret_code == 0) { - if(pres_debug) - fprintf(DebugFile, "] $$$ simplify_conj : false\n\n"); - delete conj; - use_ugly_names--; - return(false); - } - - - // - // mappedVars is mapping from columns to Variable_IDs. - // Recompute mappedVars for problem returned from ip.c - // - Variable_ID_Tuple new_mapped(0); // This is expanded by "append" - for (i=1; i<=p->safeVars; i++) { - // what is now in column i used to be in column p->var[i] - Variable_ID v = conj->mappedVars[p->var[i]]; - assert(v->kind() != Wildcard_Var); - new_mapped.append(v); - } - - /* Redeclare all wildcards that weren't eliminated. */ - free_var_decls(conj->myLocals); conj->myLocals.clear(); - - conj->mappedVars = new_mapped; - for (i = p->safeVars+1; i<=p->nVars; i++) { - Variable_ID v = conj->declare(); - conj->mappedVars.append(v); - } - - // reset var and forwarding address if desired. - p->variablesInitialized = 1; - for(i=1; i<=conj->problem->nVars; i++) - conj->problem->var[i] = conj->problem->forwardingAddress[i] = i; - - if(pres_debug) { - fprintf(DebugFile, "] $$$ simplify_conj\n"); - conj->prefix_print(DebugFile); - fprintf(DebugFile, "\n"); - } - - - use_ugly_names--; - conj->simplified = true; - conj->setup_anonymous_wildcard_names(); - - return(true); -} - - -int Conjunct::rank() { - Conjunct *C = this->copy_conj_same_relation(); - C->reorder(); - C->ordered_elimination(C->relation()->global_decls()->size()); - int C_rank = 0; - for(Variable_Iterator vi = C->mappedVars; vi; vi++) - if(C->find_column(*vi) > 0) C_rank++; - delete C; - return C_rank; - -} - - -void Conjunct::query_difference(Variable_ID v1, Variable_ID v2, coef_t &lowerBound, coef_t &upperBound, bool &guaranteed) { - int c1 = get_column(v1); - int c2 = get_column(v2); - assert(c1 && c2); - problem->query_difference(c1, c2, lowerBound, upperBound, guaranteed); -} - - -void Conjunct::query_variable_bounds(Variable_ID v, coef_t &lowerBound, coef_t &upperBound) { - int c = get_column(v); - assert (c); - problem->query_variable_bounds(c, &lowerBound, &upperBound); -} - -coef_t Conjunct::query_variable_mod(Variable_ID v, coef_t factor) { - int c = get_column(v); - assert(c); - return problem->query_variable_mod(c, factor); -} - -bool Conjunct::query_variable_used(Variable_ID v) { - for (GEQ_Iterator g = GEQs(); g.live(); g.next()) { - if ((*g).get_coef(v)) return true; - } - for (EQ_Iterator e = EQs(); e.live(); e.next()) { - if ((*e).get_coef(v)) return true; - } - return false; -} - - -int Conjunct::simplifyProblem(int verify, int subs, int redundantElimination) { - if (verified) verify = 0; - int result = problem->simplifyProblem(verify, subs, redundantElimination); - if (result == false && !exact) - exact=true; - assert(!(verified && verify && result == false)); - if (verify && result) verified = true; - else if (!result) verified = false; - return result; -} - - -// not as confident about this one as the previous: -int Conjunct::redSimplifyProblem(int effort, int computeGist) { - redCheck result = problem->redSimplifyProblem(effort, computeGist); - if (result == redFalse && !exact) - exact=true; - return result; -} - - -// -// Add given list of wildcards S to this Conjunct. -// Clears argument. (That's very important, otherwise those var_id's get freed) -// Push_exists takes responsibility for reusing or deleting Var_ID's; -// here we reuse them. Must also empty out the Tuple when finished (joins). -void Conjunct::push_exists(Variable_ID_Tuple &S) { - for(Tuple_Iterator<Variable_ID> VI(S); VI; VI++) { - (*VI)->var_kind = Wildcard_Var; - } - myLocals.join(S); // Sets S to be empty. - cols_ordered = false; - simplified = false; -} - - -Conjunct *Formula::add_conjunct() { - assert_not_finalized(); - assert(can_add_child()); - Conjunct *f = new Conjunct(this, myRelation); - myChildren.append(f); - return f; -} - -// Compress/uncompress functions - -bool Conjunct::is_compressed() { - if(problem!=NULL && comp_problem==NULL) { - return false; - } - else if(problem==NULL && comp_problem!=NULL) { - return true; - } - else { - assert(0 && "Conjunct::is_compressed: bad conjunct"); - return false; - } -} - - -void Conjunct::compress() { - if(!is_compressed()) { // compress - comp_problem = new Comp_Problem(problem); - delete problem; - problem = NULL; - } -} - - -void Conjunct::uncompress() { - if(is_compressed()) { - problem = comp_problem->UncompressProblem(); - delete comp_problem; - comp_problem = NULL; - } -} - - -Comp_Problem::Comp_Problem(Problem *problem) : - _nVars(problem->nVars), - _safeVars(problem->safeVars), - _get_var_name(problem->get_var_name), - _getVarNameArgs(problem->getVarNameArgs), - eqs(&problem->EQs[0],problem->nEQs,problem->nVars), - geqs(&problem->GEQs[0],problem->nGEQs,problem->nVars) { -} - -Comp_Constraints::Comp_Constraints(eqn *constrs, int no_constrs, int no_vars) : - n_constrs(no_constrs), - n_vars(no_vars) { - coefs = new coef_t[(n_vars+1)*n_constrs]; - int e, v; - for(e=0; e<n_constrs; e++) { - for(v=0; v<=n_vars; v++) { - coefs[coef_index(e,v)] = constrs[e].coef[v]; - } - } -} - - -Comp_Constraints::~Comp_Constraints() { - delete coefs; -} - - -Problem *Comp_Problem::UncompressProblem() { - Problem *p = new Problem(eqs.n_constraints(), geqs.n_constraints()); - p->get_var_name = get_var_name; - p->getVarNameArgs = _getVarNameArgs; - p->nVars = _nVars; - p->safeVars = _safeVars; - for(int i=1; i<=p->nVars; i++) { - p->forwardingAddress[i] = i; - p->var[i] = i; - } - eqs.UncompressConstr(&p->EQs[0], p->nEQs); - geqs.UncompressConstr(&p->GEQs[0], p->nGEQs); - return p; -} - -void Comp_Constraints::UncompressConstr(eqn *constrs, short &pn_constrs) { - int e, v; - for(e=0; e<n_constrs; e++) { - eqnnzero(&constrs[e], 0); - for(v=0; v<=n_vars; v++) { - constrs[e].coef[v] = coefs[coef_index(e,v)]; - } - constrs[e].touched = 1; - } - pn_constrs = n_constrs; -} - - -void Conjunct::convertEQstoGEQs(bool excludeStrides) { - simplify_conj(this,true,1,EQ_BLACK); // don't remember why I want to comment this statement out with reason "will cause inconsistency between Conjunct::mappedVars and Problem::nVars", 06/09/2009 by chun - problem->convertEQstoGEQs(excludeStrides); -} - - -void Conjunct::calculate_dimensions(Relation &R, int &ndim_all, int &ndim_domain) { - - Conjunct * c = this; - Relation rc=Relation(R, c); - - if(relation_debug) { - fprintf(DebugFile,"{{{\nIn Conjunct::calculate_dimensions:\n"); - rc.prefix_print(DebugFile); - } - - rc=Approximate(rc); - Relation rd=rc; - - if(relation_debug) { - fprintf(DebugFile,"Conjunct::calculate_dimensions: Approximated as:\n"); - rc.prefix_print(DebugFile); - } - - // skip_set_checks++; - - Conjunct * rc_conj=rc.single_conjunct(); - ndim_all=rc.n_inp()+rc.n_out(); - ndim_all-=rc_conj->n_EQs(); - - rc = Project_On_Sym(rc); - rc.simplify(); - - if(relation_debug) { - fprintf(DebugFile, "Conjunct::calculate_dimensions: after project_on_sym\n"); - rc.prefix_print(DebugFile); - } - - int n_eq_sym = 1000; - for (DNF_Iterator s(rc.query_DNF()); s.live(); s.next()) - n_eq_sym = min(n_eq_sym, s.curr()->n_EQs()); - ndim_all+=n_eq_sym; - // skip_set_checks--; - - if (R.is_set()) - ndim_domain = ndim_all; - else { - /* get dimensions for the domain (broadcasting) */ - - rd=Domain(rd); - rd.simplify(); - - if(relation_debug) { - fprintf(DebugFile,"Domain is:\n"); - rd.prefix_print(DebugFile); - } - - rc_conj=rd.single_conjunct(); - ndim_domain=rd.n_set()-rc_conj->n_EQs()+n_eq_sym; - } - - if(relation_debug) { - fprintf(DebugFile,"n_eq_sym=%d \n",n_eq_sym); - fprintf(DebugFile,"Dimensions: all=%d domain=%d\n}}}\n", ndim_all,ndim_domain); - } -} - -} // namespace diff --git a/omegalib/omega/src/pres_decl.cc b/omegalib/omega/src/pres_decl.cc deleted file mode 100644 index f5ac312..0000000 --- a/omegalib/omega/src/pres_decl.cc +++ /dev/null @@ -1,71 +0,0 @@ -#include <omega/pres_decl.h> -#include <omega/omega_i.h> - -namespace omega { - -// -// Declare functions. -// -Variable_ID F_Declaration::do_declare(Const_String s, Var_Kind var_type) { - Variable_ID v; - assert(var_type != Global_Var); - if(!s.null()) { - v = new Var_Decl(s, var_type, 0); - } - else { - v = new Var_Decl(var_type, 0); - } - myLocals.append(v); - return v; -} - -Variable_ID F_Declaration::declare(Const_String) { - assert(0); // must be declared in forall, exists, or conjunct - return(NULL); -} - -Section<Variable_ID> F_Declaration::declare_tuple(int n) { - int first = myLocals.size()+1; - - for (int i=1 ; i<=n; i++) - declare(); - - return Section<Variable_ID>(&myLocals, first, n); -} - - -void F_Declaration::finalize() { - assert(n_children() == 1); - Formula::finalize(); -} - -bool F_Declaration::can_add_child() { - return n_children() < 1; -} - - -F_Declaration::F_Declaration(Formula *p, Rel_Body *r): - Formula(p,r), myLocals(0) { -} - -F_Declaration::F_Declaration(Formula *p, Rel_Body *r, Variable_ID_Tuple &S): - Formula(p,r), myLocals(S) { -} - -// -// Destruct declarative node. -// Delete variableID's themselves if they are not global. -// -F_Declaration::~F_Declaration() { - free_var_decls(myLocals); -} - -//Setup names for printing -void F_Declaration::setup_anonymous_wildcard_names() { - for(Tuple_Iterator<Variable_ID> VI(myLocals); VI; VI++) { - Variable_ID v = *VI; - if (v->base_name.null()) v->instance = wildCardInstanceNumber++; - } -} - -} // namespace diff --git a/omegalib/omega/src/pres_dnf.cc b/omegalib/omega/src/pres_dnf.cc deleted file mode 100644 index c9fd7e6..0000000 --- a/omegalib/omega/src/pres_dnf.cc +++ /dev/null @@ -1,1416 +0,0 @@ -/***************************************************************************** - Copyright (C) 1994-2000 the Omega Project Team - Copyright (C) 2005-2011 Chun Chen - All Rights Reserved. - - Purpose: - Functions for disjunctive normal form. - - Notes: - - History: -*****************************************************************************/ - -#include <basic/Bag.h> -#include <omega/pres_dnf.h> -#include <omega/pres_conj.h> -#include <omega/pres_tree.h> /* all DNFize functions are here */ -#include <omega/Relation.h> -#include <omega/omega_i.h> - -namespace omega { - -void DNF::remap() { - for(DNF_Iterator DI(this); DI.live(); DI.next()) { - Conjunct *C = DI.curr(); - C->remap(); - } -} - - -// -// DNF1 & DNF2 -> DNF. -// Free arguments. -// -DNF* DNF_and_DNF(DNF* dnf1, DNF* dnf2) { - DNF* new_dnf = new DNF; - for(DNF_Iterator p(dnf2); p.live(); p.next()) { - new_dnf->join_DNF(DNF_and_conj(dnf1, p.curr())); - } - delete dnf1; - delete dnf2; - if(new_dnf->length() > 1) { - new_dnf->simplify(); - } - - if(pres_debug) { - fprintf(DebugFile, "+++ DNF_and_DNF OUT +++\n"); - new_dnf->prefix_print(DebugFile); - } - return(new_dnf); -} - - -/* - * Remove redundant conjuncts from given DNF. - * If (C1 => C2), remove C1. - * C1 => C2 is TRUE: when problem where C1 is Black and C2 is Red - * Blk Red : has no red constraints. - * It means that C1 is a subset of C2 and therefore C1 is redundant. - * - * Exception: C1 => UNKNOWN - leave them as they are - */ -void DNF::rm_redundant_conjs(int effort) { - if(is_definitely_false() || has_single_conjunct()) - return; - - use_ugly_names++; - // skip_set_checks++; - - int count = 0; - for(DNF_Iterator p(this); p.live(); p.next()) count++; - - if(pres_debug) { - int i = 0; - fprintf(DebugFile, "@@@ rm_redundant_conjs IN @@@[\n"); - prefix_print(DebugFile); - for(DNF_Iterator p(this); p.live(); p.next()) - fprintf(DebugFile, "#%d = %p\n", ++i, p.curr()); - } - - DNF_Iterator pdnext; - DNF_Iterator pdel(this); - for(; pdel.live(); pdel=pdnext) { - pdnext = pdel; - pdnext.next(); - Conjunct *cdel = pdel.curr(); - int del_min_leading_zeros = cdel->query_guaranteed_leading_0s(); - int del_max_leading_zeros = cdel->query_possible_leading_0s(); - - for(DNF_Iterator p(this); p.live(); p.next()) { - Conjunct *c = p.curr(); - if(c != cdel) { - int c_min_leading_zeros = cdel->query_guaranteed_leading_0s(); - int c_max_leading_zeros = cdel->query_possible_leading_0s(); - if(pres_debug) - fprintf(DebugFile, "@@@ rm_redundant_conjs @%p => @%p[\n", cdel, c); - - if (c->is_inexact() && cdel->is_exact()) { - if (pres_debug) - fprintf(DebugFile, "]@@@ rm_redundant_conjs @@@ Exact Conj => Inexact Conj is not tested\n"); - } - else if (del_min_leading_zeros >=0 && c_min_leading_zeros >= 0 - && c_max_leading_zeros >= 0 && del_max_leading_zeros >=0 - && (del_min_leading_zeros > c_max_leading_zeros - || c_min_leading_zeros > del_max_leading_zeros)) { - if (1 || pres_debug) - fprintf(DebugFile, "]@@@ not redundant due to leading zero info\n"); - } - else { - Conjunct *cgist = merge_conjs(cdel, c, MERGE_GIST); - - if (!cgist->redSimplifyProblem(effort,0)) { - if(pres_debug) { - fprintf(DebugFile, "]@@@ rm_redundant_conjs @@@ IMPLICATION TRUE @%p\n", cdel); - cdel->prefix_print (DebugFile); - fprintf(DebugFile, "=>\n"); - c->prefix_print (DebugFile); - } - rm_conjunct(cdel); - delete cdel; - delete cgist; - break; - } - else { - if(pres_debug) { - fprintf(DebugFile, "]@@@ rm_redundant_conjs @@@ IMPLICATION FALSE @%p\n", cdel); - if(pres_debug > 1) - cgist->prefix_print(DebugFile); - } - delete cgist; - } - } - } - } - } - - if(pres_debug) { - fprintf(DebugFile, "]@@@ rm_redundant_conjs OUT @@@\n"); - prefix_print(DebugFile); - } - // skip_set_checks--; - use_ugly_names--; -} - - -/* Remove inexact conjuncts from given DNF if it contains UNKNOWN - * conjunct - */ - -void DNF::rm_redundant_inexact_conjs() { - if (is_definitely_false() || has_single_conjunct()) - return; - - bool has_unknown=false; - bool has_inexact=false; - - Conjunct * c_unknown = 0; // make compiler shut up - for (DNF_Iterator p(this); p.live(); p.next()) { - assert (p.curr()->problem!=NULL); - if (p.curr()->is_inexact()) { - if (p.curr()->is_unknown()) { - has_unknown=true; - c_unknown = p.curr(); - } - else - has_inexact=true; - } - } - - if (! has_unknown || ! has_inexact) - return; - - use_ugly_names++; - // skip_set_checks++; - - DNF_Iterator pdnext; - DNF_Iterator pdel(this); - - for (; pdel.live(); pdel=pdnext) { - pdnext = pdel; - pdnext.next(); - Conjunct * cdel=pdel.curr(); - if (cdel->is_inexact() && cdel!=c_unknown) { - rm_conjunct(cdel); - delete cdel; - } - } - - use_ugly_names--; - // skip_set_checks--; -} - - - -// -// DNF properties. -// -bool DNF::is_definitely_false() const { - return(conjList.empty()); -} - -bool DNF::is_definitely_true() const { - return(has_single_conjunct() && single_conjunct()->is_true()); -} - -int DNF::length() const { - return conjList.length(); -} - -Conjunct *DNF::single_conjunct() const { - assert(conjList.length()==1); - return(conjList.front()); -} - -bool DNF::has_single_conjunct() const { - return (conjList.length()==1); -} - -Conjunct *DNF::rm_first_conjunct() { - if(conjList.empty()) { - return NULL; - } - else { - return conjList.remove_front(); - } -} - - -// -// Convert DNF to Formula and add it root. -// Free this DNF. -// -void DNF::DNF_to_formula(Formula* root) { - Formula *new_or; - if (conjList.length()!=1) { - skip_finalization_check++; - new_or = root->add_or(); - skip_finalization_check--; - } - else { - new_or = root; - } - while(!conjList.empty()) { - Conjunct *conj = conjList.remove_front(); - new_or->add_child(conj); - } - delete this; -} - - -// -// DNF functions. -// -DNF::DNF() : conjList() { -} - -DNF::~DNF() { - // for(DNF_Iterator p(this); p.live(); p.next()) { - // if(p.curr() != NULL) - // delete p.curr(); - // } - for(List_Iterator<Conjunct *> i(conjList); i.live(); i.next()) - delete *i; -} - -// -// Copy DNF -// -DNF* DNF::copy(Rel_Body *rel_body) { - DNF *new_dnf = new DNF; - for(DNF_Iterator pd(this); pd.live(); pd.next()) { - Conjunct *conj = pd.curr(); - if(conj) - new_dnf->add_conjunct(conj->copy_conj_diff_relation(rel_body,rel_body)); - } - return(new_dnf); -} - -// -// Add Conjunct to DNF -// -void DNF::add_conjunct(Conjunct* conj) { - conjList.append(conj); -} - -// -// Add DNF to DNF. -// The second DNF is reused. -// -void DNF::join_DNF(DNF* dnf) { - conjList.join(dnf->conjList); - delete dnf; -} - -// -// Remove conjunct from DNF. -// Conjunct itself is not deleted. -// -void DNF::rm_conjunct(Conjunct *c) { - if(conjList.front() == c) { - conjList.remove_front(); - } - else { - List_Iterator<Conjunct*> p, pp; - for(p=List_Iterator<Conjunct*> (conjList); p; p++) { - if((*p)==c) { - conjList.del_after(pp); - return; - } - pp = p; - } - assert(0 && "DNF::rm_conjunct: no such conjunct"); - } -} - - -// remove (but don't delete) all conjuncts - -void DNF::clear() { - conjList.clear(); -} - - -// -// DNF & CONJ -> new DNF. -// Don't touch arguments. -// -DNF* DNF_and_conj(DNF* dnf, Conjunct* conj) { - DNF* new_dnf = new DNF; - for(DNF_Iterator p(dnf); p.live(); p.next()) { - Conjunct* new_conj = merge_conjs(p.curr(), conj, MERGE_REGULAR); - new_dnf->add_conjunct(new_conj); - } - if(new_dnf->length() > 1) { - new_dnf->simplify(); - } - return(new_dnf); -} - -// -// Compute C0 and not (C1 or C2 or ... CN). -// Reuse/delete its arguments. -// -DNF* conj_and_not_dnf(Conjunct *positive_conjunct, DNF *neg_conjs, bool weak) { - DNF *ret_dnf = new DNF; - int recursive = 0; - use_ugly_names++; - - if(pres_debug) { - fprintf(DebugFile, "conj_and_not_dnf [\n"); - fprintf(DebugFile, "positive_conjunct:\n"); - positive_conjunct->prefix_print(DebugFile); - fprintf(DebugFile, "neg_conjs:\n"); - neg_conjs->prefix_print(DebugFile); - fprintf(DebugFile, "\n\n"); - } - - if (simplify_conj(positive_conjunct, true, false, EQ_BLACK) == false) { - positive_conjunct = NULL; - goto ReturnDNF; - } - - /* Compute gists of negative conjuncts given positive conjunct */ - - - int c0_updated; - c0_updated = true; - while(c0_updated) { - c0_updated = false; - for(DNF_Iterator p(neg_conjs); p.live(); p.next()) { - Conjunct *neg_conj = p.curr(); - if(neg_conj==NULL) continue; - if (!positive_conjunct->is_exact() - && !neg_conj->is_exact()) { - // C1 and unknown & ~(C2 and unknown) = C1 and unknown - delete neg_conj; - p.curr_set(NULL); - continue; - } - Conjunct *cgist = merge_conjs(positive_conjunct, neg_conj, MERGE_GIST); - if(simplify_conj(cgist, false, true, EQ_RED) == false) { - // C1 & ~FALSE = C1 - delete neg_conj; - p.curr_set(NULL); - } - else { - cgist->rm_color_constrs(); - if(cgist->is_true()) { - // C1 & ~TRUE = FALSE - delete cgist; - goto ReturnDNF; - } - else { - if(cgist->cost()==1) { // single inequality - DNF *neg_dnf = negate_conj(cgist); - delete cgist; - Conjunct *conj = - merge_conjs(positive_conjunct, neg_dnf->single_conjunct(), MERGE_REGULAR); - delete positive_conjunct; - delete neg_dnf; - positive_conjunct = conj; - delete neg_conj; - p.curr_set(NULL); - if(!simplify_conj(positive_conjunct, false, false, EQ_BLACK)) { - positive_conjunct = NULL; - goto ReturnDNF; - } - c0_updated = true; - } - else { - delete neg_conj; - p.curr_set(cgist); - } - } - } - } - } - - if(pres_debug) { - fprintf(DebugFile, "--- conj_and_not_dnf positive_conjunct NEW:\n"); - positive_conjunct->prefix_print(DebugFile); - fprintf(DebugFile, "--- conj_and_not_dnf neg_conjs GISTS:\n"); - neg_conjs->prefix_print(DebugFile); - fprintf(DebugFile, "--- conj_and_not_dnf ---\n\n"); - } - - /* Find minimal negative conjunct */ - { - Conjunct *min_conj = NULL; - int min_cost = INT_MAX; - DNF_Iterator min_p; - int live_count = 0; - for(DNF_Iterator q(neg_conjs); q.live(); q.next()) { - Conjunct *neg_conj = q.curr(); - if(neg_conj!=NULL) { - live_count++; - if(neg_conj->cost() < min_cost) { - min_conj = neg_conj; - min_cost = neg_conj->cost(); - min_p = q; - } - } - } - - /* Negate minimal conjunct, AND result with positive conjunct */ - if(weak || min_conj==NULL) { - ret_dnf->add_conjunct(positive_conjunct); - positive_conjunct = NULL; - } - else if (min_cost == CantBeNegated) { - static int OMEGA_WHINGE = -1; - if (OMEGA_WHINGE < 0) { - OMEGA_WHINGE = getenv("OMEGA_WHINGE") ? atoi(getenv("OMEGA_WHINGE")) : 0; - } - if (OMEGA_WHINGE) { - fprintf(stderr, "Ignoring negative clause that can't be negated and generating inexact result\n"); - if (!pres_debug) fprintf(DebugFile, "Ignoring negative clause that can't be negated and generating inexact result\n"); - } - - positive_conjunct->make_inexact(); - ret_dnf->add_conjunct(positive_conjunct); - positive_conjunct = NULL; - if(pres_debug) - fprintf(DebugFile, "Ignoring negative clause that can't be negated and generating inexact upper bound\n"); - } - else { - DNF *neg_dnf = negate_conj(min_conj); - delete min_conj; - min_p.curr_set(NULL); - DNF *new_pos = DNF_and_conj(neg_dnf, positive_conjunct); - delete neg_dnf; - delete positive_conjunct; - positive_conjunct = NULL; - // new_dnf->rm_redundant_conjs(2); - if(live_count>1) { - recursive = 1; - for(DNF_Iterator pd(new_pos); pd.live(); pd.next()) { - Conjunct *conj = pd.curr(); - ret_dnf->join_DNF(conj_and_not_dnf(conj, neg_conjs->copy(conj->relation()))); - pd.curr_set(NULL); - } - delete new_pos; - } - else { - ret_dnf->join_DNF(new_pos); - } - } - } - -ReturnDNF:; - delete positive_conjunct; - delete neg_conjs; - - //if (recursive) ret_dnf->rm_redundant_conjs(1); - - if(pres_debug) { - fprintf(DebugFile, "] conj_and_not_dnf RETURN:\n"); - ret_dnf->prefix_print(DebugFile); - fprintf(DebugFile, "\n\n"); - } - use_ugly_names--; - return ret_dnf; -} - -/* first some functions for manipulating oc "problems" */ - -static void EqnnZero(eqn *e, int s) { -// memset((char*)e, 0, (headerWords+1+s)*sizeof(int)); - e->key = 0; - e->touched = 0; - e->color = EQ_BLACK; - e->essential = 0; - e->varCount = 0; - for (int i = 0; i <= s; i++) - e->coef[i] = 0; -} - -/* - * Make a new black equation in a given problem - */ -static int NewEquation(Problem *p) { - int e = p->newEQ(); - EqnnZero(&p->EQs[e], p->nVars); - return e; -} - -/* - * Make a new black inequality in a given problem - */ -static int NewInequality(Problem *p) { - int g = p->newGEQ(); - EqnnZero(&p->GEQs[g], p->nVars); - return g; -} - -// -// ~CONJ -> DNF -// -DNF* negate_conj(Conjunct* conj) { - if(pres_debug) { - fprintf(DebugFile, "%%%%%% negate_conj IN %%%%%%\n"); - conj->prefix_print(DebugFile); - fprintf(DebugFile, "\n"); - } - - DNF* new_dnf = new DNF; - Problem *p = conj->problem; - int i, j,k; - - if (!conj->is_exact()) new_dnf->add_conjunct(conj->copy_conj_same_relation()); - - Conjunct* true_part = new Conjunct(NULL, conj->relation()); - Problem *tp = true_part->problem; - copy_conj_header(true_part, conj); - true_part->invalidate_leading_info(); - int *wildCard = new int[p->nGEQs]; - int *handleIt = new int[p->nVars+1]; - for(j=1; j<=p->nVars; j++) handleIt[j] = false; - - for(i=0; i<p->nGEQs; i++) { - wildCard[i] = 0; - for(j=1; j<=p->nVars; j++) { - Variable_ID v = conj->mappedVars[j]; - if(v->kind()==Wildcard_Var && p->GEQs[i].coef[j]!=0) { - assert(wildCard[i] == 0); - handleIt[j] = true; - if (p->GEQs[i].coef[j] > 0) wildCard[i] = j; - else wildCard[i] = -j; - } - } - } - - for(i=0; i<p->nGEQs; i++) if (wildCard[i] == 0) { - /* ~(ax + by + c >= 0) = (-ax -by -c-1 >= 0) */ - Conjunct* new_conj = true_part->copy_conj_same_relation(); - Problem *np = new_conj->problem; - new_conj->exact=true; - int n_e = NewInequality(np); - int t_e = NewInequality(tp); - np->GEQs[n_e].coef[0] = -p->GEQs[i].coef[0]-1; - tp->GEQs[t_e].coef[0] = p->GEQs[i].coef[0]; - for(j=1; j<=p->nVars; j++) { - Variable_ID v = conj->mappedVars[j]; - if(v->kind()==Wildcard_Var && p->GEQs[i].coef[j]!=0) { - assert(0 && "negate_conj: wildcard in inequality"); - } - np->GEQs[n_e].coef[j] = -p->GEQs[i].coef[j]; - tp->GEQs[t_e].coef[j] = p->GEQs[i].coef[j]; - - } - assert(j-1 == p->nVars); - assert(j-1 == conj->mappedVars.size()); - new_dnf->add_conjunct(new_conj); - } - - - for(i=0; i<p->nEQs; i++) { - int wc_no = 0; - int wc_j = 0; // make complier shut up - for(j=1; j<=p->nVars; j++) { - Variable_ID v = conj->mappedVars[j]; - if(v->kind()==Wildcard_Var && p->EQs[i].coef[j]!=0) { - wc_no++; - wc_j = j; - } - } - - if(wc_no!=0) { -#if ! defined NDEBUG - int i2; - assert(!handleIt[wc_j]); - for(i2=0; i2<p->nEQs; i2++) - if(i != i2 && p->EQs[i2].coef[wc_j] != 0) break; - assert(i2 >= p->nEQs); -#endif - assert(wc_no == 1 && "negate_conj: more than 1 wildcard in equality"); - - // === Negating equality with a wildcard for K>0 === - // ~(exists v st expr + K v + C = 0) = - // (exists v st 1 <= - expr - K v - C <= K-1) - - Conjunct *nc = true_part->copy_conj_same_relation(); - Problem *np = nc->problem; - nc->exact=true; - - // -K alpha = expr <==> K alpha = expr - if(p->EQs[i].coef[wc_j]<0) - p->EQs[i].coef[wc_j] = -p->EQs[i].coef[wc_j]; - - if(p->EQs[i].coef[wc_j]==2) { - // ~(exists v st expr +2v +C = 0) = - // (exists v st -expr -2v -C = 1) - // That is (expr +2v +C+1 = 0) - int e = NewEquation(np); - np->EQs[e].coef[0] = p->EQs[i].coef[0] +1; - for(j=1; j<=p->nVars; j++) { - np->EQs[e].coef[j] = p->EQs[i].coef[j]; - } - } - else { - // -expr -Kv -C-1 >= 0 - int e = NewInequality(np); - np->GEQs[e].coef[0] = -p->EQs[i].coef[0] -1; - for(j=1; j<=p->nVars; j++) { - np->GEQs[e].coef[j] = -p->EQs[i].coef[j]; - } - - // +expr +Kv +C+K-1 >= 0 - e = NewInequality(np); - np->GEQs[e].coef[0] = p->EQs[i].coef[0] +p->EQs[i].coef[wc_j] -1; - for(j=1; j<=p->nVars; j++) { - np->GEQs[e].coef[j] = p->EQs[i].coef[j]; - } - } - - new_dnf->add_conjunct(nc); - - } - else { - /* ~(ax + by + c = 0) = (-ax -by -c-1 >= 0) Or (ax + by + c -1 >= 0) */ - Conjunct *nc1 = true_part->copy_conj_same_relation(); - Conjunct *nc2 = true_part->copy_conj_same_relation(); - Problem* np1 = nc1->problem; - Problem* np2 = nc2->problem; - nc1->invalidate_leading_info(); - nc2->invalidate_leading_info(); - nc1->exact=true; - nc2->exact=true; - int n_e1 = NewInequality(np1); - int n_e2 = NewInequality(np2); - np1->GEQs[n_e1].coef[0] = -p->EQs[i].coef[0]-1; - np2->GEQs[n_e2].coef[0] = p->EQs[i].coef[0]-1; - for(j=1; j<=p->nVars; j++) { - coef_t coef = p->EQs[i].coef[j]; - np1->GEQs[n_e1].coef[j] = -coef; - np2->GEQs[n_e2].coef[j] = coef; - } - new_dnf->add_conjunct(nc1); - new_dnf->add_conjunct(nc2); - } - { - int e = NewEquation(tp); - tp->EQs[e].coef[0] = p->EQs[i].coef[0]; - for(j=1; j<=p->nVars; j++) - tp->EQs[e].coef[j] = p->EQs[i].coef[j]; - } - } - - for(j=1; j<=p->nVars; j++) - if (handleIt[j]) { - for(i=0; i<p->nGEQs; i++) - if (wildCard[i] == j) - for(k=0; k<p->nGEQs; k++) if (wildCard[k] == -j){ - // E_i <= c_i alpha - // c_k alpha <= E_k - // c_k E_i <= c_i c_k alpha <= c_i E_k - // c_k E_i <= c_i c_k floor (c_i E_k / c_i c_k) - // negating: - // c_k E_i > c_i c_k floor (c_i E_k / c_i c_k) - // c_k E_i > c_i c_k beta > c_i E_k - c_i c_k - // c_k E_i - 1 >= c_i c_k beta >= c_i E_k - c_i c_k + 1 - Conjunct* new_conj = true_part->copy_conj_same_relation(); - Problem *np = new_conj->problem; - coef_t c_k = - p->GEQs[k].coef[j]; - coef_t c_i = p->GEQs[i].coef[j]; - assert(c_k > 0); - assert(c_i > 0); - new_conj->exact=true; - int n_e = NewInequality(np); - // c_k E_i - 1 >= c_i c_k beta - int v; - for(v=0; v<=p->nVars; v++) { - np->GEQs[n_e].coef[v] = - c_k * p->GEQs[i].coef[v]; - } - np->GEQs[n_e].coef[j] = -c_i * c_k; - np->GEQs[n_e].coef[0]--; - - n_e = NewInequality(np); - // c_i c_k beta >= c_i E_k - c_i c_k + 1 - // c_i c_k beta + c_i c_k -1 >= c_i E_k - for(v=0; v<=p->nVars; v++) { - np->GEQs[n_e].coef[v] = - c_i * p->GEQs[k].coef[v]; - } - np->GEQs[n_e].coef[j] = c_i * c_k; - np->GEQs[n_e].coef[0] += c_i * c_k -1; - - new_dnf->add_conjunct(new_conj); - } - } - - if(pres_debug) { - fprintf(DebugFile, "%%%%%% negate_conj OUT %%%%%%\n"); - new_dnf->prefix_print(DebugFile); - } - delete true_part; - delete[] wildCard; - delete[] handleIt; - return(new_dnf); -} - - - - -/////////////////////////////////////////////////////// -// DNFize formula -- this is the real simplification // -// It also destroys the formula it simplifies // -/////////////////////////////////////////////////////// - - - -// -// Try to separate positive and negative clauses below the AND, -// letting us use the techniques described in Pugh & Wonnacott: -// "An Exact Method for Value-Based Dependence Analysis" -// - - -DNF* F_And::DNFize() { - Conjunct *positive_conjunct = NULL; - DNF *neg_conjs = new DNF; - List<DNF*> pos_dnfs; - List_Iterator<DNF*> pos_dnf_i; - DNF *new_dnf = new DNF; - int JustReturnDNF = 0; - - use_ugly_names++; - - if(pres_debug) { - fprintf(DebugFile, "\nF_And:: DNFize [\n"); - prefix_print(DebugFile); - } - - if(children().empty()) { - Conjunct * c=new Conjunct(NULL, relation()); - new_dnf->add_conjunct(c); - } - else { - while(!children().empty()) { - Formula* carg = children().remove_front(); - if(carg->node_type()==Op_Not) { - // DNF1 & ~DNF2 -> DNF - DNF *dnf = carg->children().remove_front()->DNFize(); - delete carg; - neg_conjs->join_DNF(dnf); // negative conjunct - } - else { - // DNF1 & DNF2 -> DNF - DNF *dnf = carg->DNFize(); - int dl = dnf->length(); - if(dl==0) { - // DNF & false -> false - delete this; - JustReturnDNF = 1; - break; - } - else if(dl==1) { - // positive conjunct - Conjunct *conj = dnf->rm_first_conjunct(); - delete dnf; - if(positive_conjunct==NULL) { - positive_conjunct = conj; - } - else { - Conjunct *new_conj = merge_conjs(positive_conjunct, conj, MERGE_REGULAR); - delete conj; - delete positive_conjunct; - positive_conjunct = new_conj; - } - } - else { - // positive DNF - pos_dnfs.append(dnf); - } - } - } - - if (!JustReturnDNF) { - Rel_Body * my_relation = relation(); - delete this; - - // If we have a positive_conjunct, it can serve as the 1st arg to - // conj_and_not_dnf. Otherwise, if pos_dnfs has one DNF, - // use each conjunct there for this purpose. - // Only pass "true" here if there is nothing else to try, - // as long as TRY_TO_AVOID_TRUE_AND_NOT_DNF is set. - // - // Perhaps we should even try to and multiple DNF's? - - if (!positive_conjunct && pos_dnfs.length() == 1) { - if(pres_debug) { - fprintf(DebugFile, "--- F_AND::DNFize() Single pos_dnf:\n"); - pos_dnfs[1]->prefix_print(DebugFile); - fprintf(DebugFile, "--- F_AND::DNFize() vs neg_conjs:\n"); - neg_conjs->prefix_print(DebugFile); - } - - DNF *real_neg_conjs = new DNF; - for (DNF_Iterator nc(neg_conjs); nc; nc++) { - if (simplify_conj((*nc), true, false, EQ_BLACK) != false) - real_neg_conjs->add_conjunct(*nc); - (*nc) = 0; - } - delete neg_conjs; - neg_conjs = real_neg_conjs; - - for(DNF_Iterator pc(pos_dnfs[1]); pc; pc++) { - new_dnf->join_DNF(conj_and_not_dnf((*pc), neg_conjs->copy((*pc)->relation()))); - (*pc) = 0; - } - } - else if(positive_conjunct==NULL && neg_conjs->is_definitely_false()) { - pos_dnf_i = List_Iterator<DNF*>(pos_dnfs); - delete new_dnf; - new_dnf = *pos_dnf_i; - *pos_dnf_i = NULL; - pos_dnf_i++; - for ( ; pos_dnf_i; pos_dnf_i++) { - DNF *pos_dnf = *pos_dnf_i; - new_dnf = DNF_and_DNF(new_dnf, pos_dnf); - *pos_dnf_i = NULL; - } - } - else { - if(positive_conjunct==NULL) { - static int OMEGA_WHINGE = -1; - if (OMEGA_WHINGE < 0) { - OMEGA_WHINGE = getenv("OMEGA_WHINGE") ? atoi(getenv("OMEGA_WHINGE")) : 0; - } - - if (pres_debug || OMEGA_WHINGE) { - fprintf(DebugFile, "Uh-oh: F_AND::DNFize() resorting to TRUE and not DNF\n"); - fprintf(DebugFile, "--- F_AND::DNFize() neg_conjs\n"); - neg_conjs->prefix_print(DebugFile); - fprintf(DebugFile, "--- F_AND::DNFize() pos_dnfs:\n"); - for (pos_dnf_i=List_Iterator<DNF*>(pos_dnfs); pos_dnf_i; pos_dnf_i++) { - (*pos_dnf_i)->prefix_print(DebugFile); - fprintf(DebugFile,"---- --\n"); - } - } - if (OMEGA_WHINGE) { - fprintf(stderr, "Uh-oh: F_AND::DNFize() resorting to TRUE and not DNF\n"); - fprintf(stderr, "--- F_AND::DNFize() neg_conjs\n"); - neg_conjs->prefix_print(stderr); - fprintf(stderr, "--- F_AND::DNFize() pos_dnfs:\n"); - for (pos_dnf_i=List_Iterator<DNF*>(pos_dnfs); pos_dnf_i; pos_dnf_i++) { - (*pos_dnf_i)->prefix_print(stderr); - fprintf(stderr,"---- --\n"); - } - } - positive_conjunct = new Conjunct(NULL, my_relation); - } - - if(!neg_conjs->is_definitely_false()) { - new_dnf->join_DNF(conj_and_not_dnf(positive_conjunct, neg_conjs)); - neg_conjs = NULL; - } - else { - new_dnf->add_conjunct(positive_conjunct); - } - positive_conjunct = NULL; - - // - // AND it with positive DNFs - // - if(pres_debug) { - fprintf(DebugFile, "--- F_AND::DNFize() pos_dnfs:\n"); - for (pos_dnf_i=List_Iterator<DNF*>(pos_dnfs); pos_dnf_i; pos_dnf_i++) - (*pos_dnf_i)->prefix_print(DebugFile); - } - for (pos_dnf_i = List_Iterator<DNF*>(pos_dnfs); pos_dnf_i; pos_dnf_i++) { - DNF *pos_dnf = *pos_dnf_i; - new_dnf = DNF_and_DNF(new_dnf, pos_dnf); - *pos_dnf_i = NULL; - } - } - } - } - - delete positive_conjunct; - delete neg_conjs; - for (pos_dnf_i = List_Iterator<DNF*>(pos_dnfs); pos_dnf_i; pos_dnf_i++) - delete *pos_dnf_i; - - if(pres_debug) { - fprintf(DebugFile, "] F_AND::DNFize() OUT \n"); - new_dnf->prefix_print(DebugFile); - } - - use_ugly_names--; - - return new_dnf; -} - -// -// ~ dnf = true ^ ~ dnf, so just call conj_and_not_dnf -// - -DNF* F_Not::DNFize() { - Conjunct *positive_conjunct = new Conjunct(NULL, relation()); - DNF *neg_conjs = children().remove_front()->DNFize(); - delete this; - DNF *new_dnf = conj_and_not_dnf(positive_conjunct, neg_conjs); - - if(pres_debug) { - fprintf(DebugFile, "=== F_NOT::DNFize() OUT ===\n"); - new_dnf->prefix_print(DebugFile); - } - return new_dnf; -} - - -// -// or is almost in DNF already: -// - -DNF* F_Or::DNFize() { - DNF* new_dnf = new DNF; - bool empty_or=true; - - while(!children().empty()) { - DNF* c_dnf = children().remove_front()->DNFize(); - new_dnf->join_DNF(c_dnf); - empty_or=false; - } - - - delete this; - - if(pres_debug) { - fprintf(DebugFile, "=== F_OR::DNFize() OUT ===\n"); - new_dnf->prefix_print(DebugFile); - } - return(new_dnf); -} - - -// -// exists x : (c1 v c2 v ...) --> (exists x : c1) v (exists x : c2) v ... -// - -DNF* F_Exists::DNFize() { - DNF *dnf = children().remove_front()->DNFize(); - - for (DNF_Iterator pd(dnf); pd.live(); pd.next()) { - Conjunct *conj = pd.curr(); - - // can simply call localize_vars for DNF with a single conjunct - Variable_ID_Tuple locals_copy(myLocals.size()); - copy_var_decls(locals_copy, myLocals); - conj->push_exists(locals_copy); - conj->remap(); - reset_remap_field(myLocals); - - conj->r_constrs = 0; - conj->simplified = false; // who knows - conj->cols_ordered = false; - } - delete this; - - if(pres_debug) { - fprintf(DebugFile, "=== F_EXISTS::DNFize() OUT ===\n"); - dnf->prefix_print(DebugFile); - } - return(dnf); -} - - -// -// Single conjunct is already in DNF. -// - -DNF* Conjunct::DNFize() { - assert(!is_compressed()); - DNF *results = new DNF; - - if (is_true()) { - simplified = true; - verified = true; - results->add_conjunct(this); - } - else { - results->add_conjunct(this); - } - - return results; -} - - -// -// Foralls should have been removed before we get to DNFize -// - -DNF* F_Forall::DNFize() { - assert(0); - return(NULL); -} - -void DNF::count_leading_0s() { - if (conjList.empty()) - return; - - for (DNF_Iterator conj(this); conj; conj++) { - (*conj)->count_leading_0s(); - } -} - - -// return x s.t. forall conjuncts c, c has >= x leading 0s -// if set, always returns -1; arg tells you if it's a set or relation. - -int DNF::query_guaranteed_leading_0s(int what_to_return_for_empty_dnf) { - count_leading_0s(); - int result = what_to_return_for_empty_dnf; // if set, -1; if rel, 0 - bool first = true; - - for (DNF_Iterator conj(this); conj; conj++) { - int tmp = (*conj)->query_guaranteed_leading_0s(); - assert(tmp >= 0 || ((*conj)->relation()->is_set() && tmp == -1)); - if (first || tmp < result) result = tmp; - first = false; - } - - return result; -} - -// return x s.t. forall conjuncts c, c has <= x leading 0s -// if no conjuncts, return the argument - -int DNF::query_possible_leading_0s(int n_input_and_output) { - count_leading_0s(); - int result = n_input_and_output; - bool first = true; - - for (DNF_Iterator conj(this); conj; conj++) { - int tmp = (*conj)->query_possible_leading_0s(); - assert(tmp >= 0 || (tmp == -1 && (*conj)->relation()->is_set())); - if (first || tmp > result) result = tmp; - first = false; - } - - return result; -} - - -// return 0 if we don't know, or +-1 if we do - -int DNF::query_leading_dir() { - count_leading_0s(); - int result = 0; - bool first = true; - - for (DNF_Iterator conj(this); conj; conj++) { - int glz = (*conj)->query_guaranteed_leading_0s(); - int plz = (*conj)->query_possible_leading_0s(); - int rlz = 0; // shut the compiler up - if (glz != plz) - return 0; - - if (first) { - rlz = glz; - result = (*conj)->query_leading_dir(); - first = false; - } - else - if (glz != rlz || result != (*conj)->query_leading_dir()) - return 0; - } - - return result; -} - -void Conjunct::count_leading_0s() { - Rel_Body *body = relation(); - int max_depth = min(body->n_inp(), body->n_out()); - if(body->is_set()) { - assert(guaranteed_leading_0s == -1 && possible_leading_0s == -1); -// guaranteed_leading_0s = possible_leading_0s = -1; - leading_dir = 0; - return; - } - - -#if ! defined NDEBUG - assert_leading_info(); -#endif - if (guaranteed_leading_0s < 0) { - int L; - for (L=1; L <= max_depth; L++) { - Variable_ID in = body->input_var(L), out = body->output_var(L); - coef_t min, max; - bool guaranteed; - - query_difference(out, in, min, max, guaranteed); - if (min < 0 || max > 0) { - if (min > 0 || max < 0) { // we know guaranteed & possible - guaranteed_leading_0s = possible_leading_0s = L-1; - if (min > 0) // We know its 0,..,0,+ - leading_dir = 1; - else // We know its 0,..,0,- - leading_dir = -1; - return; - } - break; - } - } - guaranteed_leading_0s = L-1; - for ( ; L <= max_depth; L++) { - Variable_ID in = body->input_var(L), - out = body->output_var(L); - coef_t min, max; - bool guaranteed; - - query_difference(out, in, min, max, guaranteed); - - if (min > 0 || max < 0) break; - } - possible_leading_0s = L-1; - } -#if ! defined NDEBUG - assert_leading_info(); -#endif -} - -// -// add level-carried DNF form out to level "level" -// - - -void DNF::make_level_carried_to(int level) { - count_leading_0s(); - Rel_Body *body = 0; // make compiler shut up - if (length() > 0 && !(body = conjList.front()->relation())->is_set()) { - // LCDNF makes no sense otherwise - Relation tmp; -#ifndef NDEBUG - tmp = Relation(*body,42); -#endif - - DNF *newstuff = new DNF; - int shared_depth = min(body->n_inp(), body->n_out()); - int split_to = level >= 0 ? min(shared_depth,level) : shared_depth; - - skip_finalization_check++; - EQ_Handle e; - - for (DNF_Iterator conj(this); conj; conj++) { - assert(body = (*conj)->relation()); - int leading_eqs; - - bool is_guaranteed = (*conj)->verified; - - for (leading_eqs=1; leading_eqs <= split_to; leading_eqs++) { - Variable_ID in = body->input_var(leading_eqs), - out = body->output_var(leading_eqs); - coef_t min, max; - bool guaranteed; - - if (leading_eqs > (*conj)->possible_leading_0s && - (*conj)->leading_dir_valid_and_known()) { - leading_eqs--; - break; - } - - if (leading_eqs > (*conj)->guaranteed_leading_0s) { - (*conj)->query_difference(out, in, min, max, guaranteed); - if (min > 0 || max < 0) guaranteed = true; -// fprintf(DebugFile,"Make level carried, %d <= diff%d <= %d (%d):\n", -// min,leading_eqs,max,guaranteed); -// use_ugly_names++; -// (*conj)->prefix_print(DebugFile); -// use_ugly_names--; - if (!guaranteed) is_guaranteed = false; - bool generateLTClause = min < 0; - bool generateGTClause = max > 0; - bool retainEQClause = (leading_eqs <= (*conj)->possible_leading_0s && - min <= 0 && max >= 0); - if (!(generateLTClause || generateGTClause || retainEQClause)) { - // conjunct is infeasible - if (pres_debug) { - fprintf(DebugFile, "Conjunct discovered to be infeasible during make_level_carried_to(%d):\n", level); - (*conj)->prefix_print(DebugFile); - } -#if ! defined NDEBUG - Conjunct *cpy = (*conj)->copy_conj_same_relation(); - assert(!simplify_conj(cpy, true, 32767, 0)); -#endif - } - - if (generateLTClause) { - Conjunct *lt; - if (!generateGTClause && !retainEQClause) - lt = *conj; - else - lt = (*conj)->copy_conj_same_relation(); - if (max >= 0) { - GEQ_Handle l = lt->add_GEQ(); // out<in ==> in-out-1>=0 - l.update_coef_during_simplify(in, 1); - l.update_coef_during_simplify(out, -1); - l.update_const_during_simplify(-1); - } - lt->guaranteed_leading_0s - = lt->possible_leading_0s = leading_eqs-1; - lt->leading_dir = -1; - if (is_guaranteed) { - /* - fprintf(DebugFile,"Promising solutions to: %d <= diff%d <= %d (%d):\n", - min,leading_eqs,max,guaranteed); - use_ugly_names++; - lt->prefix_print(DebugFile); - use_ugly_names--; - */ - lt->promise_that_ub_solutions_exist(tmp); - } - else if (0) { - fprintf(DebugFile,"Can't guaranteed solutions to:\n"); - use_ugly_names++; - lt->prefix_print(DebugFile); - use_ugly_names--; - } - if (generateGTClause || retainEQClause) - newstuff->add_conjunct(lt); - } - - if (generateGTClause) { - Conjunct *gt; - if (retainEQClause) gt = (*conj)->copy_conj_same_relation(); - else gt = *conj; - if (min <= 0) { - GEQ_Handle g = gt->add_GEQ(); // out>in ==> out-in-1>=0 - g.update_coef_during_simplify(in, -1); - g.update_coef_during_simplify(out, 1); - g.update_const_during_simplify(-1); - } - gt->guaranteed_leading_0s = - gt->possible_leading_0s = leading_eqs-1; - gt->leading_dir = 1; - if (is_guaranteed) { - /* - fprintf(DebugFile,"Promising solutions to: %d <= diff%d <= %d (%d):\n", - min,leading_eqs,max,guaranteed); - use_ugly_names++; - gt->prefix_print(DebugFile); - use_ugly_names--; - */ - gt->promise_that_ub_solutions_exist(tmp); - } - else if (0) { - fprintf(DebugFile,"Can't guaranteed solutions to:\n"); - use_ugly_names++; - gt->prefix_print(DebugFile); - use_ugly_names--; - } - if (retainEQClause) newstuff->add_conjunct(gt); - } - - if (retainEQClause) { - assert(min <= 0 && 0 <= max); - - if (min < 0 || max > 0) { - e = (*conj)->add_EQ(1); - e.update_coef_during_simplify(in, -1); - e.update_coef_during_simplify(out, 1); - } - - assert((*conj)->guaranteed_leading_0s == -1 - || leading_eqs > (*conj)->guaranteed_leading_0s); - assert((*conj)->possible_leading_0s == -1 - || leading_eqs <= (*conj)->possible_leading_0s); - - (*conj)->guaranteed_leading_0s = leading_eqs; - } - else break; - } - - { - Set<Global_Var_ID> already_done; - int remapped = 0; - - assert((*conj)->guaranteed_leading_0s == -1 - || leading_eqs <= (*conj)->guaranteed_leading_0s); - - for (Variable_ID_Iterator func(*body->global_decls()); func; func++) { - Global_Var_ID f = (*func)->get_global_var(); - if (!already_done.contains(f) && - body->has_local(f, Input_Tuple) && - body->has_local(f, Output_Tuple) && - f->arity() == leading_eqs) { - already_done.insert(f); - - // add f(in) = f(out), project one away - e = (*conj)->add_EQ(1); - Variable_ID f_in =body->get_local(f,Input_Tuple); - Variable_ID f_out =body->get_local(f,Output_Tuple); - - e.update_coef_during_simplify(f_in, -1); - e.update_coef_during_simplify(f_out, 1); - - f_out->remap = f_in; - remapped = 1; - is_guaranteed = false; - } - } - - if (remapped) { - (*conj)->remap(); - (*conj)->combine_columns(); - reset_remap_field(*body->global_decls()); - remapped = 0; - } - } - } - if (is_guaranteed) - (*conj)->promise_that_ub_solutions_exist(tmp); - else if (0) { - fprintf(DebugFile,"Can't guaranteed solutions to:\n"); - use_ugly_names++; - (*conj)->prefix_print(DebugFile); - use_ugly_names--; - } - } - - skip_finalization_check--; - join_DNF(newstuff); - } - -#if ! defined NDEBUG - for (DNF_Iterator c(this); c; c++) - (*c)->assert_leading_info(); -#endif - - simplify(); -} - -void DNF::remove_inexact_conj() { - bool found_inexact=false; - - do { - bool first=true; - found_inexact=false; - DNF_Iterator c_prev; - for (DNF_Iterator c(this); c; c++) { - if (!(*c)->is_exact()) { // remove it from the list - found_inexact=true; - delete (*c); - if (first) - conjList.del_front(); - else - conjList.del_after(c_prev); - break; - } - else { - first=false; - c_prev=c; - } - } - } - while (found_inexact); -} - - -int s_rdt_constrs; - -// -// Simplify all conjuncts in a DNF -// -void DNF::simplify() { - for (DNF_Iterator pd(this); pd.live(); ) { - Conjunct *conj = pd.curr(); - pd.next(); - if(s_rdt_constrs >= 0 && !simplify_conj(conj, true, s_rdt_constrs, EQ_BLACK)) { - rm_conjunct(conj); - } - } -} - -} // namespace diff --git a/omegalib/omega/src/pres_form.cc b/omegalib/omega/src/pres_form.cc deleted file mode 100644 index 82b710b..0000000 --- a/omegalib/omega/src/pres_form.cc +++ /dev/null @@ -1,147 +0,0 @@ -#include <omega/pres_form.h> -#include <omega/pres_tree.h> -#include <omega/pres_conj.h> -#include <omega/Relation.h> -#include <omega/omega_i.h> - -namespace omega { - -// -// Children and parents. -// -void Formula::remove_child(Formula *kid) { - assert(&kid->parent() == this); - if (myChildren.front() == kid) - myChildren.del_front(); - else { - List_Iterator<Formula*> j,k; - for(j=List_Iterator<Formula*>(myChildren); *j != kid && j; k=j, j++) - ; - - if (k) - myChildren.del_after(k); - else - assert(0 && "Child to be removed not found in child list"); - } -} - - -void Formula::add_child(Formula *kid) { - assert(can_add_child()); - myChildren.append(kid); - kid->myParent = this; - kid->myRelation = this->relation(); -} - -void Formula::replace_child(Formula *child, Formula* new_child) { - assert(&child->parent() == this); - for(List_Iterator<Formula *> LI(myChildren); LI; LI++) - if(*LI == child) { - *LI = new_child; - new_child->myParent = this; - new_child->myRelation = this->relation(); - break; - } -} - -void Formula::set_parent(Formula *parent, Rel_Body *reln) { - myParent = parent; - myRelation = reln; - for(List_Iterator<Formula*> c(myChildren); c; c++) - (*c)->set_parent(this,reln); -} - -// -// Function that sets myRelation pointers in a tree. -// -void Formula::set_relation(Rel_Body *r) { - myRelation = r; - for(List_Iterator<Formula *> FI(myChildren); FI; FI++) - (*FI)->set_relation(r); -} - - -// -// Function that descends to conjuncts to merge columns -// -void Formula::combine_columns() { - foreach(child,Formula *,myChildren,child->combine_columns()); -} - - -void Formula::finalize() { - for(List_Iterator<Formula*> c(children()); c; c++) - (*c)->finalize(); -} - -bool Formula::can_add_child() { - return true; -} - - - -Conjunct *Formula::really_conjunct() { - assert(0 && "really_conjunct() called on something that wasn't"); - return NULL; -} - -Formula::Formula(Formula *p, Rel_Body *r): myParent(p), myRelation(r) { -} - - -void Formula::verify_tree() { // should be const -#if ! defined NDEBUG - Any_Iterator<Formula*> c = myChildren.any_iterator(); - for (; c; c++) { - assert((*c)->myParent==this); - assert((*c)->myRelation==this->myRelation); - (*c)->verify_tree(); - } -#endif -} - -Formula *Formula::copy(Formula *, Rel_Body *) { - assert(0); - return NULL; -} - -Formula::~Formula() { - for(List_Iterator<Formula*> c(myChildren); c; c++) { - delete *c; - } - myChildren.clear(); -} - -void Formula::assert_not_finalized() { - if (!skip_finalization_check) { - assert(! relation()->is_finalized()); - assert(! relation()->is_shared()); - } -} - -void Formula::reverse_leading_dir_info() { - for(List_Iterator<Formula*> c(myChildren); c; c++) - (*c)->reverse_leading_dir_info(); -} - -void Formula::invalidate_leading_info(int changed) { - for(List_Iterator<Formula*> c(myChildren); c; c++) - (*c)->invalidate_leading_info(changed); -} - -void Formula::enforce_leading_info(int guaranteed, int possible, int dir) { - for(List_Iterator<Formula*> c(myChildren); c; c++) - (*c)->enforce_leading_info(guaranteed, possible, dir); -} - -// -// Push_exists functions. -// Push exists takes responsibility for the Variable_ID's in the Tuple. -// It should: -// * Re-use them, or -// * Delete them. -void Formula::push_exists(Variable_ID_Tuple &) { - assert(0); -} - -} // namespace diff --git a/omegalib/omega/src/pres_gen.cc b/omegalib/omega/src/pres_gen.cc deleted file mode 100644 index 0f05d40..0000000 --- a/omegalib/omega/src/pres_gen.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include <omega/pres_gen.h> - -namespace omega { - -int skip_finalization_check=0; -// int skip_set_checks=0; - -int pres_debug=0 ; -FILE *DebugFile=stderr; // This is the default; it's best to set it yourself. - -negation_control pres_legal_negations = any_negation; - -// -// I/O utility functions. -// -// void PresErrAssert(const char *t) { -// fprintf(stdout, "\nERROR: %s\n", t); -// if(pres_debug) { -// fprintf(DebugFile, "\nERROR: %s\n", t); -// } -// exit(1); -// } - - - -// -// Needed for gprof -// -#if defined PROFILE_MALLOCS -void* operator new(size_t n) { - void *result = malloc (n < 1 ? 1 : n); - if (result) - return result; - else { - write(2,"Virtual memory exceeded in new\n",32); - return 0; - } -} - -void operator delete (void* f) { - if (f) free(f); -} -#endif - -} // namespace diff --git a/omegalib/omega/src/pres_logic.cc b/omegalib/omega/src/pres_logic.cc deleted file mode 100644 index 8ee90f1..0000000 --- a/omegalib/omega/src/pres_logic.cc +++ /dev/null @@ -1,226 +0,0 @@ -#include <omega/pres_logic.h> -#include <omega/pres_conj.h> -#include <omega/pres_quant.h> -#include <omega/omega_i.h> - -namespace omega { - -GEQ_Handle F_And::add_GEQ(int preserves_level) { - assert_not_finalized(); - if (pos_conj == NULL || pos_conj->problem->nGEQs >= maxGEQs) { - pos_conj = NULL; - for(List_Iterator<Formula*> c(children()); c; c++) { - if ((*c)->node_type()==Op_Conjunct && - ((*c)->really_conjunct())->problem->nGEQs < maxGEQs) { - pos_conj = (*c)->really_conjunct(); - break; - } - } - if(!pos_conj) pos_conj = add_conjunct();// FERD -- set level if preserved? - } - return pos_conj->add_GEQ(preserves_level); -} - - -EQ_Handle F_And::add_EQ(int preserves_level) { - assert_not_finalized(); - if (pos_conj == NULL || pos_conj->problem->nEQs >= maxEQs) { - pos_conj = NULL; - for(List_Iterator<Formula*> c(children()); c; c++) { - if ((*c)->node_type()==Op_Conjunct && - ((*c)->really_conjunct())->problem->nEQs < maxEQs) { - pos_conj = (*c)->really_conjunct(); - break; - } - } - if(!pos_conj) pos_conj = add_conjunct();//FERD-set level info if preserved? - } - return pos_conj->add_EQ(preserves_level); -} - -Stride_Handle F_And::add_stride(int step, int preserves_level) { - assert_not_finalized(); - if (pos_conj == NULL || pos_conj->problem->nEQs >= maxEQs) { - pos_conj = NULL; - for(List_Iterator<Formula*> c(children()); c; c++) { - if ((*c)->node_type()==Op_Conjunct && - ((*c)->really_conjunct())->problem->nEQs < maxEQs) { - pos_conj = (*c)->really_conjunct(); - break; - } - } - if(!pos_conj) pos_conj = add_conjunct(); // FERD -set level if preserved? - } - return pos_conj->add_stride(step, preserves_level); -} - -GEQ_Handle F_And::add_GEQ(const Constraint_Handle &constraint, int preserves_level) { - assert_not_finalized(); - if (pos_conj == NULL || pos_conj->problem->nGEQs >= maxGEQs) { - pos_conj = NULL; - for(List_Iterator<Formula*> c(children()); c; c++) { - if ((*c)->node_type()==Op_Conjunct && - ((*c)->really_conjunct())->problem->nGEQs < maxGEQs) { - pos_conj = (*c)->really_conjunct(); - break; - } - } - if(!pos_conj) pos_conj = add_conjunct();// FERD -- set level if preserved? - } - return pos_conj->add_GEQ(constraint, preserves_level); -} - - -EQ_Handle F_And::add_EQ(const Constraint_Handle &constraint, int preserves_level) { - assert_not_finalized(); - if (pos_conj == NULL || pos_conj->problem->nEQs >= maxEQs) { - pos_conj = NULL; - for(List_Iterator<Formula*> c(children()); c; c++) { - if ((*c)->node_type()==Op_Conjunct && - ((*c)->really_conjunct())->problem->nEQs < maxEQs) { - pos_conj = (*c)->really_conjunct(); - break; - } - } - if(!pos_conj) pos_conj = add_conjunct();//FERD-set level info if preserved? - } - return pos_conj->add_EQ(constraint,preserves_level); -} - - -void F_And::add_unknown() { - assert_not_finalized(); - if (pos_conj == NULL) { - for (List_Iterator<Formula*> c(children()); c; c++) { - if ((*c)->node_type()==Op_Conjunct) { - pos_conj = (*c)->really_conjunct(); - break; - } - } - if(!pos_conj) pos_conj = add_conjunct(); // FERD - set level if preseved? - } - pos_conj->make_inexact(); -} - -Conjunct *F_Or::find_available_conjunct() { - return 0; -} - -Conjunct *F_Not::find_available_conjunct() { - return 0; -} - -Conjunct *F_And::find_available_conjunct() { - for(List_Iterator<Formula*> child(children()); child; child++) { - Conjunct *c = (*child)->find_available_conjunct(); - if (c) return c; - } - return 0; -} - - -void F_Not::finalize() { - assert(n_children() == 1); - Formula::finalize(); -} - -bool F_Not::can_add_child() { - return n_children() < 1; -} - -F_And *F_And::and_with() { - assert_not_finalized(); - assert(can_add_child()); - return this; -} - -F_And::F_And(Formula *p, Rel_Body *r): Formula(p,r), pos_conj(NULL) { -} - -F_Or::F_Or(Formula *p, Rel_Body *r): Formula(p,r){ -} - -F_Not::F_Not(Formula *p, Rel_Body *r): Formula(p,r){ -} - -Formula *F_And::copy(Formula *parent, Rel_Body *reln) { - F_And *f = new F_And(parent, reln); - for(List_Iterator<Formula*> c(children()); c; c++) - f->children().append((*c)->copy(f,reln)); - return f; -} - -Formula *F_Or::copy(Formula *parent, Rel_Body *reln) { - F_Or *f = new F_Or(parent, reln); - for(List_Iterator<Formula*> c(children()); c; c++) - f->children().append((*c)->copy(f,reln)); - return f; -} - -Formula *F_Not::copy(Formula *parent, Rel_Body *reln) { - F_Not *f = new F_Not(parent, reln); - for(List_Iterator<Formula*> c(children()); c; c++) - f->children().append((*c)->copy(f,reln)); - return f; -} - -// -// Create F_Exists nodes below this F_Or. -// Copy list S to each of the created nodes. -// Push_exists takes responsibility for reusing or deleting Var_ID's; -// here we delete them. Must also empty out the Tuple when finished. -void F_Or::push_exists(Variable_ID_Tuple &S) { - List<Formula*> mc; - mc.join(children()); - - while(!mc.empty()) { - Formula *f = mc.remove_front(); - F_Exists *e = add_exists(); - - copy_var_decls(e->myLocals, S); - f->remap(); - reset_remap_field(S); - - e->add_child(f); - } - // Since these are not reused, they have to be deleted - for(Tuple_Iterator<Variable_ID> VI(S); VI; VI++) { - assert((*VI)->kind() == Exists_Var); - delete *VI; - } - S.clear(); -} - -void F_Exists::push_exists(Variable_ID_Tuple &S) { - myLocals.join(S); -} - -F_Not *Formula::add_not() { - assert_not_finalized(); - assert(can_add_child()); - F_Not *f = new F_Not(this, myRelation); - myChildren.append(f); - return f; -} - -F_And *Formula::add_and() { - assert_not_finalized(); - assert(can_add_child()); - F_And *f = new F_And(this, myRelation); - myChildren.append(f); - return f; -} - -F_And *Formula::and_with() { - return add_and(); -} - -F_Or *Formula::add_or() { - assert_not_finalized(); - assert(can_add_child()); - F_Or *f = new F_Or(this, myRelation); - myChildren.append(f); - return f; -} - -} // namespace diff --git a/omegalib/omega/src/pres_print.cc b/omegalib/omega/src/pres_print.cc deleted file mode 100644 index 4f2cd0d..0000000 --- a/omegalib/omega/src/pres_print.cc +++ /dev/null @@ -1,908 +0,0 @@ -#include <omega/pres_gen.h> -#include <omega/pres_var.h> -#include <omega/pres_tree.h> -#include <omega/pres_conj.h> -#include <omega/Relation.h> -#include <basic/Bag.h> -#include <omega/omega_i.h> -#include <omega/omega_core/oc.h> - -namespace omega { - -//////////////////////////////////////// -// // -// Print functions. // -// // -//////////////////////////////////////// - -void Conjunct::reorder_for_print(bool reverseOrder, int first_pass_input, int first_pass_output, bool sort) { - Conjunct *C2 = copy_conj_same_relation(); - Variable_ID_Tuple newpos(0),wcvars(0),gvars(0); - -// We reorder the original Variable_ID's into the newpos list; later, we -// copy from their original column (using find_column) to the new one. - int n = mappedVars.size(); - int i; - // there may be more inp/outp vars than maxVars; must do dynamically - // skip_set_checks++; - Tuple<bool> input_used(myRelation->n_inp()); - Tuple<bool> output_used(myRelation->n_out()); - for(i=1; i<=myRelation->n_inp();i++) input_used[i] = false; - for(i=1; i<=myRelation->n_out();i++) output_used[i] = false; - for(i=1; i<=n;i++) { - if (mappedVars[i]->kind() == Input_Var) - input_used[mappedVars[i]->get_position()] = true; - else if (mappedVars[i]->kind() == Output_Var) - output_used[mappedVars[i]->get_position()] = true; - else if(mappedVars[i]->kind() == Global_Var) - gvars.append(mappedVars[i]); - } - - - if(sort) - for(i=1; i<=gvars.size();i++) - for(int j=1; j <= gvars.size(); j++) - if(gvars[j]->get_global_var()->base_name() - < gvars[j+1]->get_global_var()->base_name()) { - Variable_ID t = gvars[j]; gvars[j] = gvars[j+1]; gvars[j+1] = t; - } - - newpos.join(gvars); - - if(!reverseOrder) { - for(i=1; i<=min(myRelation->n_inp(),first_pass_input);i++) - if (input_used[i]) newpos.append(input_vars[i]); - for(i=1; i<=min(myRelation->n_out(),first_pass_output);i++) - if (output_used[i]) newpos.append(output_vars[i]); - for(i=max(1,first_pass_input+1); i<=myRelation->n_inp();i++) - if (input_used[i]) newpos.append(input_vars[i]); - for(i=max(1,first_pass_output+1); i<=myRelation->n_out();i++) - if (output_used[i]) newpos.append(output_vars[i]); - } - else { - for(i=1; i<=min(myRelation->n_out(),first_pass_output);i++) - if (output_used[i]) newpos.append(output_vars[i]); - for(i=1; i<=min(myRelation->n_inp(),first_pass_input);i++) - if (input_used[i]) newpos.append(input_vars[i]); - for(i=max(1,first_pass_output+1); i<=myRelation->n_out();i++) - if (output_used[i]) newpos.append(output_vars[i]); - for(i=max(1,first_pass_input+1); i<=myRelation->n_inp();i++) - if (input_used[i]) newpos.append(input_vars[i]); - } - - - for(i=1; i<=n;i++) - if (mappedVars[i]->kind() == Wildcard_Var) - wcvars.append(mappedVars[i]); - - if(sort) - for(i=1; i<=gvars.size();i++) - for(int j=1; j <= gvars.size(); j++) - if(gvars[j]->name() < gvars[j+1]->name()) { - Variable_ID t = gvars[j]; gvars[j] = gvars[j+1]; gvars[j+1] = t; - } - - newpos.join(wcvars); - - assert(problem->nVars == newpos.size()); // i.e. no other variable types - - // Copy coef columns into new order. Constant column is unchanged. - for(int e=0; e<problem->nGEQs; e++) problem->GEQs[e].touched = 1; - - for(i=1; i<=problem->nVars; i++) { - int col = find_column(newpos[i]); // Find column in original conj. - assert(col != 0); - copy_column(problem, i, // Copy it from orig. column in the copy. - C2->problem, col, 0, 0); - problem->var[i] = i; - } - for(i=1; i<=problem->nVars; i++) - problem->forwardingAddress[i] = i; - - mappedVars = newpos; - delete C2; - // skip_set_checks--; -} - -void Rel_Body::print_with_subs(FILE *output_file, bool printSym, bool newline) { - std::string s = this->print_with_subs_to_string(printSym, newline); - fprintf(output_file, "%s", s.c_str()); -} - -void Rel_Body::print_with_subs() { - this->print_with_subs(stdout, 0, 1); -} - -static std::string tryToPrintVarToStringWithDiv(Conjunct *C, Variable_ID v) { - std::string s; - bool seen = false; -// This assumes that there is one EQ involving v, that v cannot be -// substituted and hence has a non-unit coefficient. - for(EQ_Iterator e(C); e; e++) { - if ((*e).get_coef(v) != 0) { - assert(!seen); // This asserts just one EQ with v - coef_t v_coef = (*e).get_coef(v); - int v_sign = v_coef > 0 ? 1 : -1; - v_coef *= v_sign; - int sign_adj = -v_sign; - - s += "intDiv("; - bool first=true; - for(Constr_Vars_Iter i(*e,false); i; i++) { - if ((*i).var != v && (*i).coef != 0) { - coef_t this_coef = sign_adj*(*i).coef; - if(!first && this_coef > 0) - s+= "+"; - if (this_coef == 1) - s += (*i).var->name(); - else if (this_coef == -1) { - s += "-"; s += (*i).var->name(); - } - else { - s += to_string(this_coef) + "*" + (*i).var->name(); - } - first = false; - } - } - coef_t the_const = (*e).get_const()* sign_adj; - if (the_const > 0 && !first) - s+= "+"; - if (the_const != 0) - s += to_string(the_const); - s += "," + to_string(v_coef) + ")"; - seen = true; - } - } - return s; -} - - -// This function prints the output tuple of a relation with each one as a -// function of the input variables. -// This will fail or look goofy if the outputs are not affine functions of -// the inputs. -// BIG WARNING: Call this only from the codegen stuff, since it assumes things -// about coefficients -std::string Rel_Body::print_outputs_with_subs_to_string() { - // Rel_Body S(this),Q(this); - Rel_Body *S = this->clone(); - Rel_Body *Q = this->clone(); - S->setup_names(); - Conjunct *C = S->single_conjunct(); - Conjunct *D = Q->single_conjunct(); // ordered_elimination futzes with conj - std::string s; // = "["; - C->reorder_for_print(); - C->ordered_elimination(S->global_decls()->length()); - // Print output names with substitutions in them - for(int i=1; i<=S->n_out(); i++) { - std::string t; - int col = C->find_column(output_vars[i]); - if (col != 0) - t = C->print_sub_to_string(col); - if (col == 0 || t == output_vars[i]->name()) // no sub found - // Assume you can't get a unit coefficient on v, must use div - t = tryToPrintVarToStringWithDiv(D, output_vars[i]); - s += t; - if (i < S->n_out()) s += ","; - } - // s += "] "; - delete S; - delete Q; - return s; -} - -std::string Rel_Body::print_outputs_with_subs_to_string(int i) { - // Rel_Body S(this),Q(this); - Rel_Body *S = this->clone(); - Rel_Body *Q = this->clone(); - S->setup_names(); - Conjunct *C = S->single_conjunct(); - Conjunct *D = Q->single_conjunct(); // ordered_elimination futzes with conj - std::string s; - C->reorder_for_print(); - C->ordered_elimination(S->global_decls()->length()); - // Print output names with substitutions in them - { - std::string t; - int col = C->find_column(output_vars[i]); - if (col != 0) - t = C->print_sub_to_string(col); - if (col == 0 || t == output_vars[i]->name()) // no sub found? - t = tryToPrintVarToStringWithDiv(D, output_vars[i]); - // should check for failure - s += t; - } - delete S; - delete Q; - return s; -} - -std::string Rel_Body::print_with_subs_to_string(bool printSym, bool newline) { - std::string s=""; - - if (pres_debug) { - fprintf(DebugFile,"print_with_subs_to_string:\n"); - prefix_print(DebugFile); - } - - int anythingPrinted = 0; - - if (this->is_null()) { - s = "NULL Rel_Body\n"; - return s; - } - - // Rel_Body R(this); - Rel_Body *R = this->clone(); - bool firstRelation = true; - - for(DNF_Iterator DI(R->query_DNF()); DI.live(); DI.next()) { - Rel_Body S(R, DI.curr()); - Conjunct *C = S.single_conjunct(); - if(!simplify_conj(C, true, 4, EQ_BLACK)) continue; - - S.setup_names(); - - if(! firstRelation) { - s += " union"; - if (newline) s += "\n "; - } - else - firstRelation = false; - - anythingPrinted = 1; - - C->reorder_for_print(false,C->max_ufs_arity_of_in(), - C->max_ufs_arity_of_out()); - C->ordered_elimination(S.Symbolic.length() - +C->max_ufs_arity_of_in() - +C->max_ufs_arity_of_out()); -// assert(C->problem->variablesInitialized); - - if (pres_debug) S.prefix_print(DebugFile); - - /* Do actual printing of Conjunct C as a relation */ - s += "{"; - - if (!Symbolic.empty()) { - if (printSym) s += "Sym=["; - for (Variable_ID_Iterator Sym_I = S.Symbolic; Sym_I;) - { - if (printSym) - s += (*Sym_I)->name(); - Sym_I++; - if (printSym && Sym_I) s+= ","; - } - if (printSym) s += "] "; - } - - int i, col; - - if (S.number_input != 0) { - s += "["; - // Print input names with substitutions in them - for(i=1; i<=S.number_input; i++) { - col = C->find_column(input_vars[i]); - if (col != 0) - s += C->problem->print_sub_to_string(col); - else - s += input_vars[i]->name(); - if (i<S.number_input) s += ","; - } - s += "]"; - } - - if (! S.is_set()) - s += " -> "; - - if (S.number_output != 0) { - s += "["; - - // Print output names with substitutions in them - for(i=1; i<=S.number_output; i++) { - col = C->find_column(output_vars[i]); - if (col != 0) - s += C->problem->print_sub_to_string(col); - else - s += output_vars[i]->name(); - if (i < S.number_output) s += ","; - } - s += "] "; - } - - if (C->is_unknown()) { - if (S.number_input != 0 || S.number_output != 0) - s += ":"; - s += " UNKNOWN"; - } - else { - // Empty conj means TRUE, so don't print colon - if (C->problem->nEQs != 0 || C->problem->nGEQs != 0) { - C->problem->clearSubs(); - if (S.number_input != 0 || S.number_output != 0) - s += ":"; - s += " "; - s += C->print_to_string(false); - } - else { - if (S.number_input == 0 && S.number_output == 0) - s += " TRUE "; - } - } - - s += "}"; - } - - if (!anythingPrinted) { - R->setup_names(); - s = "{"; - s += R->print_variables_to_string(printSym); - if (R->number_input != 0 || R->number_output != 0) - s += " :"; - s += " FALSE }"; - if (newline) s += "\n"; - - delete R; - return s; - } - - if (newline) s += "\n"; - - delete R; - return s; -} - - -void print_var_addrs(std::string &s, Variable_ID v) { - if(pres_debug>=2) { - char ss[20]; - sprintf(ss, "(%p,%p)", v, v->remap); - s += ss; - } -} - -std::string Rel_Body::print_variables_to_string(bool printSym) { - std::string s=""; - - if (! Symbolic.empty()) { - if (printSym) s += " Sym=["; - for (Variable_ID_Iterator Sym_I(Symbolic); Sym_I; ) { - if (printSym) s += (*Sym_I)->name(); - print_var_addrs(s, *Sym_I); - Sym_I++; - if (printSym && Sym_I) s += ","; - } - if (printSym) s += "] "; - } - int i; - - if (number_input) { - s += "["; - for (i=1;i<=number_input;i++) { - s += input_vars[i]->name(); - print_var_addrs(s, input_vars[i]); - if(i < number_input) s += ","; - } - s += "] "; - } - - if (number_output) { - s += "-> ["; - for (i=1;i<=number_output;i++) { - s += output_vars[i]->name(); - print_var_addrs(s, output_vars[i]); - if(i < number_output) s += ","; - } - s += "] "; - } - - return s; -} - - -int F_Declaration::priority() { - return 3; -} - -int Formula::priority () { - return 0; -} - -int F_Or::priority() { - return 0; -} - -int F_And::priority() { - return 1; -} - -int Conjunct::priority() { - return 1; -} - -int F_Not::priority() { - return 2; -} - - -// -// print() functions -// -void Formula::print(FILE *output_file) { - if(myChildren.empty()) { - if(node_type()==Op_Relation || node_type()==Op_Or) - fprintf(output_file, "FALSE"); - else if(node_type()==Op_And) - fprintf(output_file, "TRUE"); - else { - assert(0); - } - } - - for(List_Iterator<Formula*> c(myChildren); c;) { - if (node_type() == Op_Exists || node_type() == Op_Forall - || (*c)->priority() < priority()) - fprintf(output_file, "( "); - (*c)->print(output_file); - if (node_type() == Op_Exists || node_type() == Op_Forall - || (*c)->priority() < priority()) - fprintf(output_file, " )"); - c++; - if(c.live()) - print_separator(output_file); - } -} - -std::string Rel_Body::print_formula_to_string() { - std::string s; - setup_names(); - for(DNF_Iterator DI(query_DNF()); DI.live();) { - - s += (*DI)->print_to_string(1); - DI.next(); - if (DI.live()) s += " && "; - if (pres_debug) fprintf(DebugFile,"Partial print to string: %s\n", - s.c_str()); - } - return s; -} - -void Rel_Body::print(FILE *output_file, bool printSym) { - if (this->is_null()) { - fprintf(output_file, "NULL Rel_Body\n"); - return; - } - - setup_names(); - - fprintf(output_file, "{"); - - std::string s = print_variables_to_string(printSym); - fprintf(output_file, "%s", s.c_str()); - - fprintf(output_file, ": "); - - if(simplified_DNF==NULL) { - Formula::print(output_file); - } - else { - assert(children().empty()); - simplified_DNF->print(output_file); - } - - fprintf(output_file, " }\n"); -} - -void Rel_Body::print() { - this->print(stdout); -} - -void F_Not::print(FILE *output_file) { - fprintf(output_file, " not "); - Formula::print(output_file); -} - -void F_And::print_separator(FILE *output_file) { - fprintf(output_file, " and "); -} - -void Conjunct::print(FILE *output_file) { - std::string s = print_to_string(true); - fprintf(output_file, "%s", s.c_str()); -} - -std::string Conjunct::print_to_string(int true_printed) { - std::string s=""; - - int num = myLocals.size(); - if(num) { - s += "exists ( "; - int i; - for (i = 1; i <= num; i++) { - Variable_ID v = myLocals[i]; - s += v->char_name(); - if(i < num) s += ","; - } - if (true_printed || !(is_true())) s += " : "; - } - - if(is_true()) { - s += true_printed ? "TRUE" : ""; - } - else { - if (is_unknown()) - s += "UNKNOWN"; - else { - s += problem->prettyPrintProblemToString(); - if (!exact) - s += " && UNKNOWN"; - } - } - - - if (num) s += ")"; - return s; -} - -void F_Or::print_separator(FILE *output_file) { - fprintf(output_file, " or "); -} - -void F_Declaration::print(FILE *output_file) { - std::string s=""; - for(Variable_ID_Iterator VI(myLocals); VI; ) { - s += (*VI)->name(); - VI++; - if(VI) s += ","; - } - fprintf(output_file, "( %s : ", s.c_str()); - Formula::print(output_file); - fprintf(output_file, ")"); -} - -void F_Forall::print(FILE *output_file) { - fprintf(output_file, "forall "); - F_Declaration::print(output_file); -} - -void F_Exists::print(FILE *output_file) { - fprintf(output_file, "exists "); - F_Declaration::print(output_file); -} - -void Formula::print_separator(FILE *) { - assert(0); // should never be called, it's only for derived classes -} - -// -// Setup names in formula. -// - -typedef Set<Global_Var_ID> g_set; -void Rel_Body::setup_names() { - int i; - - - if (use_ugly_names) return; - - if (pres_debug>=2) - fprintf(DebugFile,"Setting up names for 0x%p\n", this); - - for(i=1; i<=number_input; i++) { - input_vars[i]->base_name = In_Names[i]; - } - for(i=1; i<=number_output; i++) { - output_vars[i]->base_name = Out_Names[i]; - } - - g_set gbls; - - wildCardInstanceNumber = 0; - - for(i=1; i<= Symbolic.size(); i++) { - gbls.insert(Symbolic[i]->get_global_var()); - } - - foreach(g,Global_Var_ID,gbls, - g->instance = g->base_name()++); - - for(i=1; i<=number_input; i++) { - if (!input_vars[i]->base_name.null()) - input_vars[i]->instance = input_vars[i]->base_name++; - } - for(i=1; i<=number_output; i++) { - if (!output_vars[i]->base_name.null()) - output_vars[i]->instance = output_vars[i]->base_name++; - } - - if (simplified_DNF != NULL) // It is simplified - simplified_DNF->setup_names(); - else // not simplified - Formula::setup_names(); - - for(i=1; i<=number_output; i++) { - if (!output_vars[i]->base_name.null()) - output_vars[i]->base_name--; - } - for(i=1; i<=number_input; i++) { - if (!input_vars[i]->base_name.null()) - input_vars[i]->base_name--; - } - foreach(g,Global_Var_ID,gbls, g->base_name()--); -} - -void Formula::setup_names() { - if (pres_debug>=2) - fprintf(DebugFile,"Setting up names for formula 0x%p\n", this); - - for(List_Iterator<Formula*> c(myChildren); c; c++) - (*c)->setup_names(); -} - -void DNF::setup_names() { - if (pres_debug>=2) - fprintf(DebugFile,"Setting up names for DNF 0x%p\n", this); - - for(DNF_Iterator DI(this); DI.live(); DI.next()) - DI.curr()->setup_names(); -} - - -void F_Declaration::setup_names() { - if (pres_debug>=2) - fprintf(DebugFile,"Setting up names for Declaration 0x%p\n", this); - - // Allow re-use of wc names in other scopes - int savedWildCardInstanceNumber = wildCardInstanceNumber; - - for(Tuple_Iterator<Variable_ID> VI(myLocals); VI; VI++) { - Variable_ID v = *VI; - if (!v->base_name.null()) v->instance = v->base_name++; - else v->instance = wildCardInstanceNumber++; - } - - for(List_Iterator<Formula*> c(children()); c; c++) - (*c)->setup_names(); - - for(Tuple_Iterator<Variable_ID> VI2(myLocals); VI2; VI2++) { - Variable_ID v = *VI2; - if (!v->base_name.null()) v->base_name--; - } - wildCardInstanceNumber = savedWildCardInstanceNumber; -} - - -// -// Prefix_print functions. -// Print Formula Tree, used in debugging. -// -static int level = 0; - -void Formula::prefix_print(FILE *output_file, int debug) { - for(List_Iterator<Formula*> c(children()); c; c++) - (*c)->prefix_print(output_file, debug); - level--; -} - - -void Rel_Body::prefix_print() { - this->prefix_print(stdout, 1); -} - -void Rel_Body::prefix_print(FILE *output_file, int debug) { - int old_use_ugly_names = use_ugly_names; - use_ugly_names = 0; - - setup_names(); - - level = 0; - if(pres_debug>=2) fprintf(output_file, "(@%p)", this); - fprintf(output_file, is_set() ? "SET: " : "RELATION: "); - std::string s = print_variables_to_string(true); - fprintf(output_file, "%s\n", s.c_str()); - - if(simplified_DNF==NULL) { - Formula::prefix_print(output_file, debug); - } else { - assert(children().empty()); - simplified_DNF->prefix_print(output_file, debug, true); - } - fprintf(output_file, "\n"); - use_ugly_names = old_use_ugly_names; -} - - -void F_Forall::prefix_print(FILE *output_file, int debug) { - Formula::print_head(output_file); - fprintf(output_file, "forall ["); - F_Declaration::prefix_print(output_file, debug); - for (Variable_ID_Iterator VI(myLocals); VI; VI++) - assert((*VI)->kind() == Forall_Var); - -} - -void F_Exists::prefix_print(FILE *output_file, int debug) { - Formula::print_head(output_file); - if(pres_debug>=2) fprintf(output_file, "(@%p)", this); - fprintf(output_file, "exists ["); - F_Declaration::prefix_print(output_file, debug); - for (Variable_ID_Iterator VI(myLocals); VI; VI++) - assert((*VI)->kind() == Exists_Var); -} - -void F_Declaration::prefix_print(FILE *output_file, int debug) { - std::string s = ""; - for (Variable_ID_Iterator VI(myLocals); VI; ) { - s += (*VI)->name(); - print_var_addrs(s, *VI); - VI++; - if(VI) s += ","; - } - s += "]\n"; - fprintf(output_file, "%s", s.c_str()); - Formula::prefix_print(output_file, debug); -} - -void F_Or::prefix_print(FILE *output_file, int debug) { - Formula::print_head(output_file); - fprintf(output_file, "or\n"); - Formula::prefix_print(output_file, debug); -} - -void F_And::prefix_print(FILE *output_file, int debug) { - Formula::print_head(output_file); - fprintf(output_file, "and\n"); - Formula::prefix_print(output_file, debug); -} - -void F_Not::prefix_print(FILE *output_file, int debug) { - Formula::print_head(output_file); - fprintf(output_file, "not\n"); - Formula::prefix_print(output_file, debug); -} - -void Conjunct::prefix_print(FILE *output_file, int debug) { - static char dir_glyphs[] = { '-', '?', '+' }; - - if (debug) { - Formula::print_head(output_file); - if(pres_debug>=2) fprintf(output_file, "(@%p)", this); - fprintf(output_file, "%s CONJUNCT, ", exact ? "EXACT" : "INEXACT"); - if (simplified) fprintf(output_file, "simplified, "); - if (verified) fprintf(output_file, "verified, "); - if (possible_leading_0s != -1 && guaranteed_leading_0s != -1) - assert (guaranteed_leading_0s <= possible_leading_0s); - if (guaranteed_leading_0s != -1 && guaranteed_leading_0s == possible_leading_0s) - fprintf(output_file,"# leading 0's = %d,", possible_leading_0s); - else if (possible_leading_0s != -1 || guaranteed_leading_0s != -1) { - if (guaranteed_leading_0s != -1) - fprintf(output_file,"%d <= ",guaranteed_leading_0s); - fprintf(output_file,"#O's"); - if (possible_leading_0s != -1) - fprintf(output_file," <= %d",possible_leading_0s); - fprintf(output_file,", "); - } - if (dir_glyphs[leading_dir+1] != '?') - fprintf(output_file," first = %c, ", dir_glyphs[leading_dir+1]); - fprintf(output_file,"myLocals=["); - std::string s=""; - for (Variable_ID_Iterator VI(myLocals); VI; ) { - assert( (*VI)->kind() == Wildcard_Var); - s += (*VI)->name(); - print_var_addrs(s, *VI); - VI++; - if(VI) s += ","; - } - s += "] mappedVars=["; - for(Variable_ID_Iterator MVI(mappedVars); MVI; ) { - s += (*MVI)->name(); - print_var_addrs(s, *MVI); - MVI++; - if(MVI) s += ","; - } - fprintf(output_file, "%s]\n", s.c_str()); - } - else - level++; - - setOutputFile(output_file); - setPrintLevel(level+1); - problem->printProblem(debug); - setPrintLevel(0); - Formula::prefix_print(output_file, debug); -} - -void Formula::print_head(FILE *output_file) { - level++; - int i; - for(i=0; i<level; i++) { - fprintf(output_file, ". "); - } -} - -// -// Print DNF. -// -void DNF::print(FILE *out_file) { - DNF_Iterator p(this); - if (!p.live()) - fprintf(out_file, "FALSE"); - else - for(; p.live(); ) { - p.curr()->print(out_file); - p.next(); - if(p.live()) - fprintf(out_file, " or "); - } -} - -void DNF::prefix_print(FILE *out_file, int debug, bool parent_names_setup) { - wildCardInstanceNumber = 0; - Variable_ID_Tuple all_vars; - if(!use_ugly_names && !parent_names_setup) { - // We need to manually set up all of the input,output, and symbolic - // variables, since during simplification, a dnf's conjuncts may not - // be listed as part of a relation, or perhaps as part of different - // relations (?) (grr). - for(DNF_Iterator p0(this); p0.live(); p0.next()) { - for(Variable_Iterator vi((*p0)->mappedVars); vi; vi++) - if((*vi)->kind() != Wildcard_Var && all_vars.index(*vi) == 0) - all_vars.append(*vi); - (*p0)->setup_names(); - } - foreach(v,Variable_ID,all_vars, - if (!v->base_name.null()) v->instance = v->base_name++; - else v->instance = wildCardInstanceNumber++; - ); - } - - int i = 1; - level = 0; - for(DNF_Iterator p(this); p.live(); p.next(), i++) { - fprintf(out_file, "#%d ", i); - if(*p == NULL) - fprintf(out_file, "(NULL)\n"); - else - (*p)->prefix_print(out_file, debug); - } - - foreach(v,Variable_ID,all_vars,if (!v->base_name.null()) v->base_name--); - - fprintf(out_file, "\n"); -} - -std::string Constraint_Handle::print_to_string() const { - assert(0); - return "FOO"; -} - -std::string EQ_Handle::print_to_string() const { - relation()->setup_names(); - std::string s = c->print_EQ_to_string(e); - return s; -} - -std::string GEQ_Handle::print_to_string() const { - relation()->setup_names(); - std::string s = c->print_GEQ_to_string(e); - return s; -} - -std::string Constraint_Handle::print_term_to_string() const { - assert(0); - return "FOO"; -} - -std::string EQ_Handle::print_term_to_string() const { - relation()->setup_names(); - std::string s = c->print_EQ_term_to_string(e); - return s; -} - -std::string GEQ_Handle::print_term_to_string() const { - relation()->setup_names(); - std::string s = c->print_GEQ_term_to_string(e); - return s; -} - -} diff --git a/omegalib/omega/src/pres_quant.cc b/omegalib/omega/src/pres_quant.cc deleted file mode 100644 index 5483bad..0000000 --- a/omegalib/omega/src/pres_quant.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include <omega/pres_quant.h> -#include <omega/omega_i.h> - -namespace omega { - -F_Forall::F_Forall(Formula *p, Rel_Body *r): F_Declaration(p,r) { -} - -F_Exists::F_Exists(Formula *p, Rel_Body *r): F_Declaration(p,r) { -} - -F_Exists::F_Exists(Formula *p, Rel_Body *r, Variable_ID_Tuple &S): F_Declaration(p,r,S) { -} - - -Formula *F_Forall::copy(Formula *parent, Rel_Body *reln) { - F_Forall *f = new F_Forall(parent, reln); - copy_var_decls(f->myLocals, myLocals); - for(List_Iterator<Formula*> c(children()); c; c++) - f->children().append((*c)->copy(f,reln)); - reset_remap_field(myLocals); - return f; -} - -Formula *F_Exists::copy(Formula *parent, Rel_Body *reln) { - F_Exists *f = new F_Exists(parent, reln); - copy_var_decls(f->myLocals, myLocals); - for(List_Iterator<Formula*> c(children()); c; c++) - f->children().append((*c)->copy(f,reln)); - reset_remap_field(myLocals); - return f; -} - -Variable_ID F_Forall::declare(Const_String s) { - return do_declare(s, Forall_Var); -} - -Variable_ID F_Forall::declare() { - return do_declare(Const_String(), Forall_Var); -} - -Variable_ID F_Forall::declare(Variable_ID v) { - return do_declare(v->base_name, Forall_Var); -} - - -Variable_ID F_Exists::declare(Const_String s) { - return do_declare(s, Exists_Var); -} - -Variable_ID F_Exists::declare() { - return do_declare(Const_String(), Exists_Var); -} - -Variable_ID F_Exists::declare(Variable_ID v) { - return do_declare(v->base_name, Exists_Var); -} - -Conjunct *F_Forall::find_available_conjunct() { - return 0; -} - -Conjunct *F_Exists::find_available_conjunct() { - assert(children().length() == 1 || children().length() == 0); - if (children().length() == 0) - return 0; - else - return children().front()->find_available_conjunct(); -} - -F_Exists *Formula::add_exists() { - assert_not_finalized(); - assert(can_add_child()); - F_Exists *f = new F_Exists(this, myRelation); - myChildren.append(f); - return f; -} - -F_Exists *Formula::add_exists(Variable_ID_Tuple &S) { - assert_not_finalized(); - assert(can_add_child()); - F_Exists *f = new F_Exists(this, myRelation, S); - myChildren.append(f); - return f; -} - -F_Forall *Formula::add_forall() { - assert_not_finalized(); - assert(can_add_child()); - F_Forall *f = new F_Forall(this, myRelation); - myChildren.append(f); - return f; -} - -} // namespace diff --git a/omegalib/omega/src/pres_rear.cc b/omegalib/omega/src/pres_rear.cc deleted file mode 100644 index 508959d..0000000 --- a/omegalib/omega/src/pres_rear.cc +++ /dev/null @@ -1,131 +0,0 @@ -#include <omega/pres_tree.h> -#include <omega/pres_conj.h> -#include <omega/Relation.h> -#include <omega/omega_i.h> - -namespace omega { - -///////////////////////// -// // -// Rearrange functions // -// // -///////////////////////// - -// -// Rules: -// ~ (f1 | f2 | ... | fn) = ~f1 & ~f2 & ... & fn -// ~ ~ f = f -// Forall v: f = ~ (Exists v: ~ f) -// Exists v: (f1 | ... | fn) = (Exists v: f1) | ... | (Exists v: fn) -// - -void Rel_Body::rearrange() { - assert(children().length()==1); - - skip_finalization_check++; - formula()->rearrange(); - skip_finalization_check--; - - if(pres_debug) { - fprintf(DebugFile, "\n=== Rearranged TREE ===\n"); - prefix_print(DebugFile); - } -} - -void Formula::rearrange() { - // copy list of children, as they may be removed as we work - List<Formula*> kiddies = myChildren; - - for(List_Iterator<Formula*> c(kiddies); c; c++) - (*c)->rearrange(); -} - -// -// Push nots down the tree until quantifier or conjunct, rearrange kids -// -void F_Not::rearrange() { - Formula *child = children().front(); - Formula *new_child, *f; - - switch(child->node_type()) { - case Op_Or: - parent().remove_child(this); - new_child = parent().add_and(); - while(!child->children().empty()) { - f = child->children().remove_front(); - F_Not *new_not = new_child->add_not(); - new_not->add_child(f); - } - delete this; - break; -//case Op_And: -// parent().remove_child(this); -// new_child = parent().add_or(); -// while(!child->myChildren.empty()) { -// f = child->myChildren.remove_front(); -// F_Not *new_not = new_child->add_not(); -// new_not->add_child(f); -// } -// delete this; -// break; - case Op_Not: - parent().remove_child(this); - f = child->children().remove_front(); - parent().add_child(f); - delete this; - f->rearrange(); - return; - default: - new_child = child; - break; - } - - new_child->rearrange(); -} - -// -// Convert a universal quantifier to "not exists not". -// Forall v: f = ~ (Exists v: ~ f) -// -void F_Forall::rearrange() { - Formula &p = parent(); - p.remove_child(this); - - F_Not *topnot = p.add_not(); - F_Exists *exist = topnot->add_exists(); - for (Variable_ID_Iterator VI(myLocals); VI; VI++) - (*VI)->set_kind(Exists_Var); - exist->myLocals.join(myLocals); - - F_Not *botnot = exist->add_not(); - Formula *f = children().remove_front(); - botnot->add_child(f); - - delete this; - - botnot->rearrange(); -} - -// -// Exists v: (f1 | ... | fn) = (Exists v: f1) | ... | (Exists v: fn) -// -void F_Exists::rearrange() { - Formula* child = children().front(); - switch(child->node_type()) { - case Op_Or: - case Op_Conjunct: - case Op_Exists: - child->push_exists(myLocals); - parent().remove_child(this); - parent().add_child(child); - children().remove_front(); - delete this; - break; - default: - break; - } - - child->rearrange(); -} - -} // namespace diff --git a/omegalib/omega/src/pres_subs.cc b/omegalib/omega/src/pres_subs.cc deleted file mode 100644 index 9854b09..0000000 --- a/omegalib/omega/src/pres_subs.cc +++ /dev/null @@ -1,131 +0,0 @@ -#include <omega/pres_subs.h> - -namespace omega { - -Substitutions::Substitutions(Relation &input_R, Conjunct *input_c) { - int i; - r = new Relation(input_R,input_c); - c = r->single_conjunct(); - c->reorder_for_print(); - c->ordered_elimination(r->global_decls()->length()); - int num_subs = c->problem->nSUBs; - subs = new eqn[num_subs]; - for(i = 0; i < num_subs; i++) - subs[i] = SUBs[i]; - subbed_vars.reallocate(num_subs); - /* Go through and categorize variables as: - 1) substituted, 2) not substituted, 3) wildcard - Safevars number of variables were not able to be substituted. - nVars number of total variables, including wildcards. - nSUBs is the number of substitutions. - nSUBs + nVars == the number of variables that went in. - Then reset var and forwardingAddress arrays in the problem, - so that they will correctly refer to the reconstructed - mappedVars. */ - Variable_ID_Tuple unsubbed_vars(c->problem->safeVars); - for(i = 1; i <= c->mappedVars.size(); i++) - if(c->mappedVars[i]->kind() != Wildcard_Var) { - int addr = c->problem->forwardingAddress[i]; - assert(addr == c->find_column(c->mappedVars[i]) && addr != 0); - if(addr < 0) { - assert(-addr <= subbed_vars.size()); - subbed_vars[-addr] = c->mappedVars[i]; - } - else { - assert(addr <= unsubbed_vars.size()); - unsubbed_vars[addr] = c->mappedVars[i]; - } - } - else { - // Here we don't redeclare wildcards, just re-use them. - unsubbed_vars.append(c->mappedVars[i]); - } - assert(unsubbed_vars.size() + subbed_vars.size() == c->mappedVars.size()); - c->mappedVars = unsubbed_vars; /* These are the variables that remain */ - - for(int col = 1; col <= c->problem->nVars; col++) { - c->problem->var[col] = col; - c->problem->forwardingAddress[col] = col; - } -} - -Substitutions::~Substitutions() { - delete [] subs; - delete r; -} - -bool Substitutions::substituted(Variable_ID v) { - return (subbed_vars.index(v) > 0); -} - -Sub_Handle Substitutions::get_sub(Variable_ID v) { - assert(substituted(v) && "No substitution for variable"); - return Sub_Handle(this,subbed_vars.index(v)-1,v); -} - -bool Substitutions::sub_involves(Variable_ID v, Var_Kind kind) { - assert(substituted(v)); - for(Constr_Vars_Iter i = get_sub(v); i; i++) - if ((*i).var->kind() == kind) - return true; - return false; -} - - -//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - - -int Sub_Iterator::live() const { - return current <= last; -} - -void Sub_Iterator::operator++() { this->operator++(0); } - -void Sub_Iterator::operator++(int) { - current++; -} - -Sub_Handle Sub_Iterator::operator*() { - assert(s && current <= last && "Sub_Iterator::operator*: bad call"); - return Sub_Handle(s,current,s->subbed_vars[current+1]); -} - -Sub_Handle Sub_Iterator::operator*() const { - assert(s && current <= last && "Sub_Iterator::operator*: bad call"); - return Sub_Handle(s,current,s->subbed_vars[current+1]); -} - - -//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - - - -Sub_Handle::Sub_Handle(Substitutions *_s, int _e, Variable_ID _v) : -Constraint_Handle(_s->c,&(_s->subs),_e), v(_v) {} - -std::string Sub_Handle::print_to_string() const { - relation()->setup_names(); - return v->name() + " = " + this->print_term_to_string(); -} - -std::string Sub_Handle::print_term_to_string() const { - /* The horrible truth is that print_term_to_string is a member - function of Conjunct, (and then Problem below it) but uses - nothing from there but the names, so you can pass it a pointer to - an equation that isn't even part of the conjunct. */ - relation()->setup_names(); - return c->print_term_to_string(&((*eqns)[e])); -} - - -/* - String Sub_Handle::print_to_string() const { - return c->problem->print_EQ_to_string(&((*eqns)[e])); - } - - String Sub_Handle::print_term_to_string() const { - return c->print_term_to_string(&(*eqns[e])); - } -*/ - -} // namespace diff --git a/omegalib/omega/src/pres_var.cc b/omegalib/omega/src/pres_var.cc deleted file mode 100644 index 0ec406f..0000000 --- a/omegalib/omega/src/pres_var.cc +++ /dev/null @@ -1,459 +0,0 @@ -#include <omega/pres_var.h> -#include <omega/pres_tree.h> -#include <omega/pres_conj.h> -#include <omega/omega_i.h> - -namespace omega { - -int wildCardInstanceNumber; - -const int Global_Input_Output_Tuple::initial_allocation = 10; - -// Declare named Variable -Var_Decl::Var_Decl(Const_String name, Var_Kind vkind, int pos): - base_name(name), - instance(999), - remap(this), - var_kind(vkind), - position(pos), - global_var(NULL), - of((Argument_Tuple) 0) { - assert(((vkind==Input_Var || vkind==Output_Var) && pos>0) || pos==0); -} - -// Declare unnamed variable -Var_Decl::Var_Decl(Var_Kind vkind, int pos): - instance(999), - remap(this), - var_kind(vkind), - position(pos), - global_var(NULL), - of((Argument_Tuple) 0) { - assert(((vkind==Input_Var || vkind==Output_Var) && pos>0) || pos==0); -} - -// Copy variable declaration -Var_Decl::Var_Decl(Variable_ID v): - base_name(v->base_name), - instance(v->instance), - remap(this), - var_kind(v->var_kind), - position(v->position), - global_var(v->global_var), - of(v->of) { -} - -Var_Decl::Var_Decl(Const_String name, Global_Var_ID v): - base_name(name), - instance(999), - remap(this), - var_kind(Global_Var), - position(0), - global_var(v), - of((Argument_Tuple) 0) { - assert(v->arity() == 0); -} - -Var_Decl::Var_Decl(Const_String name, Global_Var_ID v, Argument_Tuple function_of): - base_name(name), - instance(999), - remap(this), - var_kind(Global_Var), - position(0), - global_var(v), - of(function_of) { -} - -int Var_Decl::get_position() { - assert((var_kind == Input_Var || var_kind == Output_Var) && "Var_Decl::get_position: bad var_kind"); - return(position); -} - -Global_Var_ID Var_Decl::get_global_var() { - assert(var_kind == Global_Var && "Var_Decl::get_global_var: bad var_kind"); - return(global_var); -} - -Argument_Tuple Var_Decl::function_of() { - assert(var_kind == Global_Var); - return(of); -} - - -Omega_Var *Global_Var_Decl::really_omega_var() { - assert(0); - return(NULL); -} - -Coef_Var_Decl *Global_Var_Decl::really_coef_var() { - assert(0); - return(NULL); -} - -// -// Variable name. -// - -const int N_greek_letters = 19; - -char greek_letters[19][10] = { - "alpha" , "beta" , "gamma" , "delta" , "tau" , "sigma" , "chi" , - "omega" , "pi" , "ni" , "Alpha" , "Beta" , "Gamma" , "Delta" , - "Tau" , "Sigma" , "Chi" , "Omega" , "Pi" -}; - -const int numBuffers = 50; -const int bufferSize = 90; -char nameBuffers[numBuffers][bufferSize]; -int nextBuffer = 0; - -int use_ugly_names = 0; - -const char *Var_Decl::char_name() { - char *s = nameBuffers[nextBuffer++]; - char *start = s; - if (nextBuffer >= numBuffers) nextBuffer = 0; - int primes; - - if (use_ugly_names) - primes = 0; - else - primes = instance; - - switch(var_kind) { - case Input_Var: - if (!use_ugly_names && !base_name.null()) - sprintf(s,"%s",(const char *)base_name); - else { - primes = 0; - sprintf(s,"In_%d",position); - } - break; - case Output_Var: - if (!use_ugly_names && !base_name.null()) - sprintf(s,"%s",(const char *)base_name); - else { - primes = 0; - sprintf(s,"Out_%d",position); - } - break; - case Global_Var: - assert(!base_name.null()); - if (use_ugly_names) - sprintf(s,"%s@%p",(const char *)base_name, this); - else { - sprintf(s,"%s",(const char *)base_name); - primes = get_global_var()->instance; - } - break; - default: - if (use_ugly_names) { - if (!base_name.null()) - sprintf(s,"%s@%p",(const char *)base_name, this); - else - sprintf(s,"?@%p", this); - } - else if (!base_name.null()) sprintf(s,"%s",(const char *)base_name); - else { - assert(instance < 999); - sprintf(s,"%s", - greek_letters[instance % N_greek_letters]); - primes = instance/N_greek_letters; - } - break; - } - - while (*s) s++; - int i; - assert(primes < 999); - for(i=1; i<= primes; i++) *s++ = '\''; - *s = '\0'; - if (var_kind == Global_Var) { - int a = get_global_var()->arity(); - if (a) { - if (use_ugly_names) { - static const char *arg_names[4] = { "???", "In", "Out", "In == Out" }; - sprintf(s, "(%s[1#%d])", arg_names[function_of()], a); - } - else { - int f_of = function_of(); - assert(f_of == Input_Tuple || f_of == Output_Tuple); - *s++ = '('; - for(i = 1;i<=a;i++) { - if (f_of == Input_Tuple) - sprintf(s,"%s",(const char *)input_vars[i]->char_name()); - else - sprintf(s,"%s",(const char *)output_vars[i]->char_name()); - while (*s) s++; - if (i<a) *s++ = ','; - } - *s++ = ')'; - *s++ = 0; - } - } - } - - assert(s < start+bufferSize); - return start; -} - -std::string Var_Decl::name() { - return char_name(); -} - -// -// Copy variable declarations. -// -void copy_var_decls(Variable_ID_Tuple &new_vl, Variable_ID_Tuple &vl) { - if (new_vl.size() < vl.size()) { - new_vl.reallocate(vl.size()); - } - for(int p=1; p<=vl.size(); p++) { - Variable_ID v = vl[p]; - if(v->kind()==Global_Var) { - new_vl[p] = v; - v->remap = v; - } - else { - new_vl[p] = new Var_Decl(vl[p]); - v->remap = new_vl[p]; - } - } -} - -// -// Name a variable. -// -void Var_Decl::name_variable(char *newname) { - base_name = newname; -} - - -static Const_String coef_var_name(int i, int v) { - char s[100]; - sprintf(s, "c_%d_%d", i, v); - return Const_String(s); -} - - -// -// Global variables stuff. -// -Global_Var_Decl::Global_Var_Decl(Const_String baseName): - loc_rep1(baseName, this, Input_Tuple), - loc_rep2(baseName, this, Output_Tuple) { -} - -Global_Kind Global_Var_Decl::kind() const { - assert(0); - return Coef_Var; -} - -Coef_Var_Decl::Coef_Var_Decl(int id, int var): - Global_Var_Decl(coef_var_name(id, var)) { - i = id; - v = var; -} - -Coef_Var_Decl *Coef_Var_Decl::really_coef_var() { - return this; -} - -int Coef_Var_Decl::stmt() const { - return i; -} - -int Coef_Var_Decl::var() const { - return v; -} - -Global_Kind Coef_Var_Decl::kind() const { - return Coef_Var; -} - -Free_Var_Decl::Free_Var_Decl(Const_String name): - Global_Var_Decl(name), _arity(0) { -} - -Free_Var_Decl::Free_Var_Decl(Const_String name, int arity): - Global_Var_Decl(name), _arity(arity) { -} - -int Free_Var_Decl::arity() const { - return _arity; -} - -Global_Kind Free_Var_Decl::kind() const { - return Free_Var; -} - - -// -// Delete variable from variable list. Does not preserve order -// -bool rm_variable(Variable_ID_Tuple &vl, Variable_ID v) { - int n = vl.size(); - int i; - for(i = 1; i<n; i++) if (vl[i] == v) break; - if (i>n) return 0; - vl[i] = vl[n]; - vl.delete_last(); - return 1; -} - - -// -// Destroy variable declarations. -// -void free_var_decls(Variable_ID_Tuple &c) { - for(Variable_ID_Iterator p = c; p; p++) { - Variable_ID v = *p; - if(v->kind()!=Global_Var) { - delete v; - } - } -} - - -Variable_ID input_var(int nth) { - assert(1 <= nth && nth <= input_vars.size()); - return input_vars[nth]; -} - -Variable_ID output_var(int nth) { - assert(1<= nth && nth <= output_vars.size()); - return output_vars[nth]; -} - -Variable_ID set_var(int nth) { - assert(1 <= nth && set_vars.size()); - return input_vars[nth]; -} - - -// -// Remap mappedVars in all conjuncts of formula. -// Uses the remap field of the Var_Decl. -// -void Formula::remap() { - for(List_Iterator<Formula*> c(children()); c; c++) - (*c)->remap(); -} - -void Conjunct::remap() { - for(Variable_Iterator VI(mappedVars); VI; VI++) { - Variable_ID v = *VI; - *VI = v->remap; - } - cols_ordered = false; -} - -// Function to reset the remap field of a Variable_ID -void reset_remap_field(Variable_ID v) { - v->remap = v; -} - -// Function to reset the remap fields of a Variable_ID_Seq -void reset_remap_field(Sequence<Variable_ID> &T) { - for(Any_Iterator<Variable_ID> VI(T.any_iterator()); VI; VI++) { - Variable_ID v = *VI; - v->remap = v; - } -} - -// Function to reset the remap fields of a Variable_ID_Tuple, -// more efficiently -void reset_remap_field(Variable_ID_Tuple &T) { - for(Variable_Iterator VI(T); VI; VI++) { - Variable_ID v = *VI; - v->remap = v; - } -} - -void reset_remap_field(Sequence<Variable_ID> &T, int var_no) { - int i=1; - for(Any_Iterator<Variable_ID> VI(T.any_iterator()); i <= var_no && VI; VI++) { - Variable_ID v = *VI; - v->remap = v; - i++; - } -} - -void reset_remap_field(Variable_ID_Tuple &T, int var_no) { - int i=1; - for(Variable_Iterator VI(T); i <= var_no && VI; VI++) { - Variable_ID v = *VI; - v->remap = v; - i++; - } -} - - -// Global input and output variable tuples. -// These Tuples must be initialized as more in/out vars are needed. -//Variable_ID_Tuple input_vars(0); -//Variable_ID_Tuple output_vars(0); -//Variable_ID_Tuple& set_vars = input_vars; -Global_Input_Output_Tuple input_vars(Input_Var); -Global_Input_Output_Tuple output_vars(Output_Var); -Global_Input_Output_Tuple &set_vars = input_vars; - -//////////////////////////////////////// -// // -// Variable and Declaration functions // -// // -//////////////////////////////////////// - -// -// Constructors and properties. -// - - -// Allocate ten variables initially. Most applications won't require more. -Global_Input_Output_Tuple::Global_Input_Output_Tuple(Var_Kind in_my_kind, int init): - my_kind(in_my_kind) { - for (int i=1; i<=(init == -1? initial_allocation: max(0,init)); i++) - this->append(new Var_Decl(Const_String(), my_kind, i)); -} - -Global_Input_Output_Tuple::~Global_Input_Output_Tuple() { - for (int i=1; i<=size(); i++) - delete data[i-1]; -} - -Variable_ID & Global_Input_Output_Tuple::operator[](int index) { - assert(index > 0); - while(size() < index) - this->append(new Var_Decl(Const_String(), my_kind, size()+1)); - return data[index-1]; -} - -const Variable_ID & Global_Input_Output_Tuple::operator[](int index) const { - assert(index > 0); - Global_Input_Output_Tuple *unconst_this = (Global_Input_Output_Tuple *) this; - while(size() < index) - unconst_this->append(new Var_Decl(Const_String(), my_kind, size()+1)); - return data[index-1]; -} - -Variable_ID Var_Decl::UF_owner() { - Variable_ID v = this; - while (v->remap != v) v = v->remap; - return v; -} - -void Var_Decl::UF_union(Variable_ID b) { - Variable_ID a = this; - while (a->remap != a) { - Variable_ID tmp = a->remap; - a->remap = tmp->remap; - a = tmp; - } - while (b->remap != a) { - Variable_ID tmp = b->remap; - b->remap = a; - b = tmp; - } -} - -} // namespace diff --git a/omegalib/omega/src/reach.cc b/omegalib/omega/src/reach.cc deleted file mode 100644 index 6569edb..0000000 --- a/omegalib/omega/src/reach.cc +++ /dev/null @@ -1,211 +0,0 @@ -#include <omega.h> -#include <omega/Relations.h> -#include <basic/DynamicArray.h> -#include <omega/reach.h> - -namespace omega { - -typedef DynamicArray1<Relation> Rel_Array1; -typedef DynamicArray2<Relation> Rel_Array2; - -// This is from parallelism.c, modified - -static void closure_rel(Rel_Array2 &trans, int i, int k, int j) { - Relation tik; - - if (trans[k][k].is_upper_bound_satisfiable()) { - Relation tkk = TransitiveClosure(copy(trans[k][k])); - tkk.simplify(2,4); - tik = Composition(tkk, copy(trans[i][k])); - tik.simplify(2,4); - tik = Union(copy(trans[i][k]), tik); - tik.simplify(2,4); - } - else { - tik = trans[i][k]; - } - Relation fresh; - Relation tkj = trans[k][j]; - fresh = Composition(tkj, tik); - fresh.simplify(2,4); - trans[i][j] = Union(trans[i][j], fresh); - trans[i][j].simplify(2,4); - -#if 0 - fprintf(DebugFile, "%d -> %d -> %d\n", i, k, j); - trans[i][j].print_with_subs(DebugFile); -#endif -} - - -static void close_rels(Rel_Array2 &trans,int n_nodes) { - for (int k=1; k<=n_nodes; k++) - for (int i=1; i<=n_nodes; i++) - if (trans[i][k].is_upper_bound_satisfiable()) - for (int j=1; j<=n_nodes; j++) - if (trans[k][j].is_upper_bound_satisfiable()) - closure_rel(trans, i, k, j); -} - - -void dump_rels(Rel_Array2 &a, reachable_information *reachable_info) { - int i,j; - int n_nodes = reachable_info->node_names.size(); - for(i = 1; i <= n_nodes; i++) - for(j = 1; j <= n_nodes; j++) { - fprintf(stderr,"t[%s][%s] = ", - (reachable_info->node_names[i]).c_str(), - (reachable_info->node_names[j]).c_str()); - a[i][j].print_with_subs(stderr); - } -} - - -void dump_sets(Rel_Array1 &a, reachable_information *reachable_info) { - int i; - int n_nodes = reachable_info->node_names.size(); - for(i = 1; i <= n_nodes; i++) { - fprintf(stderr,"r[%s] = ", (reachable_info->node_names[i]).c_str()); - a[i].print_with_subs(stderr); - } -} - - - -Rel_Array1 *Reachable_Nodes(reachable_information *reachable_info) { - Tuple<std::string> &node_names = reachable_info->node_names; - Tuple<int> &arity = reachable_info->node_arity; - Rel_Array2 &transitions = reachable_info->transitions; - Rel_Array1 &start_nodes = reachable_info->start_nodes; - - int n_nodes = node_names.size(),i,j; - -#define DUMP_INITIAL 1 -#define DUMP_CLOSED 1 - - if(DUMP_INITIAL && relation_debug){ - fprintf(stderr,"Initially:\n"); - dump_rels(transitions, reachable_info); - } - - close_rels(transitions,n_nodes); - - if(DUMP_CLOSED && relation_debug) { - fprintf(stderr,"Closed:\n"); - dump_rels(transitions, reachable_info); - } - - Rel_Array1 *finalp = - new Rel_Array1("node"); - Rel_Array1 &final = *finalp; - final.resize(n_nodes+1); - for (i=1; i<=n_nodes; i++) - final[i] = Relation::False(arity[i]); - - for(i = 1; i <= n_nodes; i++) - for(j = 1; j <= n_nodes; j++) - if(start_nodes[i].is_upper_bound_satisfiable()) - final[j] = Union(final[j], - Composition(copy(transitions[i][j]), - copy(start_nodes[i]))); - return finalp; -} - -static void compute_initially_reachable(Rel_Array1 &r, - Rel_Array1 &start_nodes, - Rel_Array2 &, - Rel_Array2 &closed, - Rel_Array1 &end_nodes, - int n_nodes, Tuple<int> &arity){ - for(int n = 1; n <= n_nodes; n++) - r[n] = Relation::False(arity[n]); - - for(int i = 1; i <= n_nodes; i++) - for(int j = 1; j <= n_nodes; j++) - r[i] = Union(r[i], - Range(Restrict_Domain( - Restrict_Range(copy(closed[j][i]), - copy(end_nodes[i])), - copy(start_nodes[j])))); -} - - -static bool iterate(Rel_Array1 &r, Rel_Array2 &, Rel_Array2 &closed, - Rel_Array1 &, int n_nodes) { - bool changed; - - changed = false; - for(int j = 1; j <= n_nodes; j++) { - for(int i = 1; i <= n_nodes; i++) { - /* look for additional steps from interesting states */ - Relation new_rj = Range(Restrict_Domain(copy(closed[i][j]), - copy(r[i]))); - if(!Must_Be_Subset(copy(new_rj),copy(r[j]))) { - r[j] = Union(r[j],new_rj); - r[j].simplify(2,2); - changed = true; - } - } - } - return changed; -} - - - - -Rel_Array1 *I_Reachable_Nodes(reachable_information *reachable_info) { - bool changed; - - Tuple<std::string> &node_names = reachable_info->node_names; - int n_nodes = node_names.size(); - Tuple<int> &arity = reachable_info->node_arity; - Rel_Array2 &transitions = reachable_info->transitions; - Rel_Array1 &start_nodes = reachable_info->start_nodes; - Rel_Array2 closed("node number","node number"); - closed.resize(n_nodes+1,n_nodes+1); // abuse of dynamic arrays - Rel_Array1 *rp = new Rel_Array1("node number"); - Rel_Array1 &r = *rp; - r.resize(n_nodes+1); // abuse of dynamic arrays - - int i,j; - - Rel_Array1 end_nodes("Hi!"); - end_nodes.resize(n_nodes+1); // for future use - for(int n = 1; n <= n_nodes; n++) end_nodes[n] = Relation::True(arity[n]); - - for(j = 1; j <= n_nodes; j++) { - closed[j][j] = TransitiveClosure(copy(transitions[j][j])); - for(i = 1; i <= n_nodes; i++) - if (i != j) - closed[i][j] = transitions[i][j]; - } - - compute_initially_reachable(r,start_nodes,transitions,closed,end_nodes, - n_nodes,arity); - -#define DUMP_INITIAL 1 -#define DUMP_CLOSED 1 - - if(DUMP_INITIAL && relation_debug > 1) { - fprintf(stderr,"Closed:\n"); - dump_rels(closed, reachable_info); - } - if(DUMP_INITIAL && relation_debug) { - fprintf(stderr,"start nodes:\n"); - dump_sets(start_nodes, reachable_info); - fprintf(stderr,"Initially reachable:\n"); - dump_sets(r, reachable_info); - } - - changed = true; - int iterations = 0, max_iterations = 1000; - while(changed && iterations < max_iterations) { - changed = iterate(r,transitions,closed,start_nodes,n_nodes); - iterations++; - } - if(relation_debug) - fprintf(stdout,"[Iterations to convergence: %d]\n",iterations); - return rp; -} - -} // namespace |