[cohomcalg] 02/12: Remove (again) .exe and polylib files from git.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Mon Jan 16 06:03:39 UTC 2017
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to branch master
in repository cohomcalg.
commit 1002c708b350f2b1e58a2260b886a872130d3cf0
Author: Doug Torrance <dtorrance at piedmont.edu>
Date: Mon Jan 16 00:01:46 2017 -0500
Remove (again) .exe and polylib files from git.
---
GPLv3 License.txt | 675 ----
bin/cohomcalg.exe | Bin 622080 -> 0 bytes
bin/cohomcalg32.exe | Bin 515584 -> 0 bytes
manual-031.pdf | Bin 971163 -> 0 bytes
source/polylib_mod/COPYING | 675 ----
source/polylib_mod/Lattice.c | 1759 --------
source/polylib_mod/Matop.c | 453 ---
source/polylib_mod/NormalForms.c | 719 ----
source/polylib_mod/SolveDio.c | 314 --
source/polylib_mod/Zpolyhedron.c | 1052 -----
source/polylib_mod/alpha.c | 665 ---
source/polylib_mod/arithmetic_errors.h | 138 -
source/polylib_mod/arithmetique.h | 757 ----
source/polylib_mod/compress_parms.c | 1029 -----
source/polylib_mod/ehrhart.c | 2775 -------------
source/polylib_mod/errormsg.c | 61 -
source/polylib_mod/errors.c | 391 --
source/polylib_mod/eval_ehrhart.c | 201 -
source/polylib_mod/ext_ehrhart.c | 995 -----
source/polylib_mod/homogenization.c | 181 -
source/polylib_mod/matrix.c | 1041 -----
source/polylib_mod/matrix_addon.c | 416 --
source/polylib_mod/matrix_permutations.c | 281 --
source/polylib_mod/param.c | 86 -
source/polylib_mod/polyhedron.c | 4721 ----------------------
source/polylib_mod/polylib/Lattice.h | 56 -
source/polylib_mod/polylib/Matop.h | 50 -
source/polylib_mod/polylib/NormalForms.h | 27 -
source/polylib_mod/polylib/SolveDio.h | 31 -
source/polylib_mod/polylib/Zpolyhedron.h | 48 -
source/polylib_mod/polylib/alpha.h | 37 -
source/polylib_mod/polylib/arithmetic_errors.h | 138 -
source/polylib_mod/polylib/arithmetique.h | 757 ----
source/polylib_mod/polylib/compress_parms.h | 135 -
source/polylib_mod/polylib/ehrhart.h | 59 -
source/polylib_mod/polylib/errormsg.h | 31 -
source/polylib_mod/polylib/eval_ehrhart.h | 36 -
source/polylib_mod/polylib/ext_ehrhart.h | 26 -
source/polylib_mod/polylib/homogenization.h | 31 -
source/polylib_mod/polylib/matrix.h | 46 -
source/polylib_mod/polylib/matrix_addon.h | 128 -
source/polylib_mod/polylib/matrix_permutations.h | 93 -
source/polylib_mod/polylib/param.h | 32 -
source/polylib_mod/polylib/polyhedron.h | 111 -
source/polylib_mod/polylib/polylib.h | 53 -
source/polylib_mod/polylib/polylib.h.in | 52 -
source/polylib_mod/polylib/polylib32.h | 20 -
source/polylib_mod/polylib/polylib64.h | 20 -
source/polylib_mod/polylib/polylibgmp.h | 21 -
source/polylib_mod/polylib/polyparam.h | 56 -
source/polylib_mod/polylib/ranking.h | 80 -
source/polylib_mod/polylib/types.h | 251 --
source/polylib_mod/polylib/vector.h | 72 -
source/polylib_mod/polyparam.c | 1957 ---------
source/polylib_mod/ranking.c | 227 --
source/polylib_mod/vector.c | 822 ----
56 files changed, 24888 deletions(-)
diff --git a/GPLv3 License.txt b/GPLv3 License.txt
deleted file mode 100644
index 10926e8..0000000
--- a/GPLv3 License.txt
+++ /dev/null
@@ -1,675 +0,0 @@
- 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>.
-
diff --git a/bin/cohomcalg.exe b/bin/cohomcalg.exe
deleted file mode 100644
index e47ff02..0000000
Binary files a/bin/cohomcalg.exe and /dev/null differ
diff --git a/bin/cohomcalg32.exe b/bin/cohomcalg32.exe
deleted file mode 100644
index d767f77..0000000
Binary files a/bin/cohomcalg32.exe and /dev/null differ
diff --git a/manual-031.pdf b/manual-031.pdf
deleted file mode 100644
index af9ad11..0000000
Binary files a/manual-031.pdf and /dev/null differ
diff --git a/source/polylib_mod/COPYING b/source/polylib_mod/COPYING
deleted file mode 100644
index 10926e8..0000000
--- a/source/polylib_mod/COPYING
+++ /dev/null
@@ -1,675 +0,0 @@
- 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>.
-
diff --git a/source/polylib_mod/Lattice.c b/source/polylib_mod/Lattice.c
deleted file mode 100644
index eba0733..0000000
--- a/source/polylib_mod/Lattice.c
+++ /dev/null
@@ -1,1759 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <polylib/polylib.h>
-
-
-typedef struct {
- int count;
- int *fac;
-} factor;
-
-static factor allfactors (int num);
-
-/*
- * Print the contents of a list of Lattices 'Head'
- */
-void PrintLatticeUnion(FILE *fp, char *format, LatticeUnion *Head) {
-
- LatticeUnion *temp;
-
- for(temp = Head; temp != NULL; temp = temp->next)
- Matrix_Print(fp,format,(Matrix *)temp->M);
- return;
-} /* PrintLatticeUnion */
-
-/*
- * Free the memory allocated to a list of lattices 'Head'
- */
-void LatticeUnion_Free(LatticeUnion *Head) {
-
- LatticeUnion *temp;
-
- while (Head != NULL) {
- temp = Head;
- Head = temp->next;
- Matrix_Free(temp->M);
- free(temp);
- }
- return;
-} /* LatticeUnion_Free */
-
-/*
- * Allocate a heads for a list of Lattices
- */
-LatticeUnion *LatticeUnion_Alloc(void) {
-
- LatticeUnion *temp;
-
- temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
- temp->M=NULL;
- temp->next=NULL;
- return temp;
-} /* LatticeUnion_Alloc */
-
-/*
- * Given two Lattices 'A' and 'B', return True if they have the same affine
- * part (the last column) otherwise return 'False'.
- */
-Bool sameAffinepart (Lattice *A, Lattice *B) {
-
- int i;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug","a");
- fprintf(fp,"\nEntered SAMEAFFINEPART \n");
- fclose(fp);
-#endif
-
- for (i = 0; i < A->NbRows; i ++)
- if (value_ne(A->p[i][A->NbColumns-1],B->p[i][B->NbColumns-1]))
- return False;
- return True;
-} /* sameAffinepart */
-
-/*
- * Return an empty lattice of dimension 'dimension-1'. An empty lattice is
- * represented as [[0 0 ... 0] .... [0 ... 0][0 0.....0 1]].
- */
-Lattice *EmptyLattice(int dimension) {
-
- Lattice *result;
- int i,j;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen ("_debug", "a");
- fprintf (fp, "\nEntered NULLATTICE \n");
- fclose (fp);
-#endif
-
- result = (Lattice *) Matrix_Alloc(dimension, dimension);
- for (i = 0; i < dimension; i ++)
- for (j = 0; j < dimension; j ++)
- value_set_si(result->p[i][j],0);
- value_set_si(result->p[i-1][i-1],1);
- return result;
-} /* EmptyLattice */
-
-/*
- * Return True if Lattice 'A' is empty, otherwise return False.
- */
-Bool isEmptyLattice (Lattice *A) {
-
- int i,j;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered ISNULLATTICE \n");
- fclose(fp);
-#endif
-
- for (i = 0; i < A->NbRows-1; i ++)
- for (j = 0; j < A->NbColumns-1; j ++)
- if(value_notzero_p(A->p[i][j])) {
- return False;
- }
- if (value_one_p(A->p[i][A->NbColumns-1])) {
- return True ;
- }
- return False ;
-} /* isEmptyLaattice */
-
-/*
- * Given a Lattice 'A', check whether it is linear or not, i.e. whether the
- * affine part is NULL or not. If affine part is empty, it returns True other-
- * wise it returns False.
- */
-Bool isLinear(Lattice *A) {
-
- int i;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen ("_debug", "a");
- fprintf (fp, "\nEntered ISLINEAR \n");
- fclose (fp);
-#endif
-
- for (i = 0; i < A->NbRows-1; i ++)
- if (value_notzero_p(A->p[i][A->NbColumns-1])) {
- return False;
- }
- return True;
-} /* isLinear */
-
-/*
- * Return the affine Hermite normal form of the affine lattice 'A'. The unique
- * affine Hermite form if a lattice is stored in 'H' and the unimodular matrix
- * corresponding to 'A = H*U' is stored in the matrix 'U'.
- * Algorithm :
- * 1) Check if the Lattice is Linear or not.
- * 2) If it is not Linear, then Homogenise the Lattice.
- * 3) Call Hermite.
- * 4) If the Lattice was Homogenised, the HNF H must be
- * Dehomogenised and also corresponding changes must
- * be made to the Unimodular Matrix U.
- * 5) Return.
- */
-void AffineHermite (Lattice *A, Lattice **H, Matrix **U) {
-
- Lattice *temp;
- Bool flag = True;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen ("_debug", "a");
- fprintf (fp, "\nEntered AFFINEHERMITE \n");
- fclose (fp);
-#endif
-
- if (isLinear(A) == False)
- temp = Homogenise(A,True);
- else {
- flag = False ;
- temp = (Lattice *)Matrix_Copy(A);
- }
- Hermite((Matrix *)temp,(Matrix **) H, U);
- if (flag == True) {
- Matrix_Free ((Matrix *) temp);
- temp = Homogenise(H[0],False);
- Matrix_Free((Matrix *) H[0]);
- H[0] = (Lattice *)Matrix_Copy(temp);
- Matrix_Free((Matrix *) temp);
- temp = Homogenise(U[0],False);
- Matrix_Free ((Matrix *) U[0]);
- U[0] = (Matrix *)Matrix_Copy(temp);
- }
- Matrix_Free((Matrix *) temp);
- return;
-} /* AffineHermite */
-
-/*
- * Given a Polylib matrix 'A' that rerepresents an affine function, return the
- * affine Smith normal form 'Delta' of 'A' and unimodular matrices 'U' and 'V'
- * such that 'A = U*Delta*V'.
- * Algorithm:
- * (1) Homogenise the Lattice.
- * (2) Call Smith
- * (3) The Smith Normal Form Delta must be Dehomogenised and also
- * corresponding changes must be made to the Unimodular Matrices
- * U and V.
- * 4) Bring Delta into AffineSmith Form.
- */
-void AffineSmith(Lattice *A, Lattice **U, Lattice **V, Lattice **Diag) {
-
- Lattice *temp;
- Lattice *Uinv;
- int i,j;
- Value sum, quo, rem;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered AFFINESMITH \n");
- fclose(fp);
-#endif
-
- value_init(sum);
- value_init(quo); value_init(rem);
- temp = Homogenise(A,True);
- Smith((Matrix *)temp, (Matrix **)U, (Matrix **)V, (Matrix **)Diag);
- Matrix_Free((Matrix *)temp);
-
- temp = Homogenise (*U, False);
- Matrix_Free ((Matrix *) *U);
- *U = (Lattice *)Matrix_Copy ((Matrix *)temp);
- Matrix_Free ((Matrix *)temp);
-
- temp = Homogenise (*V, False);
- Matrix_Free ((Matrix *)*V);
- *V = (Lattice *) Matrix_Copy ((Matrix *)temp);
- Matrix_Free ((Matrix *)temp);
-
- temp = Homogenise (*Diag, False);
- Matrix_Free ((Matrix *)*Diag);
- *Diag = (Lattice *)Matrix_Copy ((Matrix *)temp);
- Matrix_Free ((Matrix *)temp);
-
- temp = (Lattice *) Matrix_Copy ((Matrix *) *U);
- Uinv = (Lattice *) Matrix_Alloc (U[0]->NbRows, U[0]->NbColumns);
- Matrix_Inverse( (Matrix *) temp, (Matrix *) Uinv);
- Matrix_Free ((Matrix *) temp);
-
- for (i = 0; i < U[0]->NbRows-1; i ++) {
- value_set_si(sum,0);
- for(j = 0; j < U[0]->NbColumns-1; j ++) {
- value_addmul(sum, Uinv->p[i][j], U[0]->p[j][U[0]->NbColumns-1]);
- }
- value_assign(Diag[0]->p[i][j],sum);
- }
- Matrix_Free((Matrix *) Uinv);
- for(i = 0; i < U[0]->NbRows-1; i ++)
- value_set_si(U[0]->p[i][U[0]->NbColumns-1],0);
- for(i = 0; i < Diag[0]->NbRows-1; i ++) {
- value_division(quo,Diag[0]->p[i][Diag[0]->NbColumns-1],Diag[0]->p[i][i]);
- value_modulus(rem,Diag[0]->p[i][Diag[0]->NbColumns-1],Diag[0]->p[i][i]);
-
- fprintf(stdout," pourcent ");
- value_print(stdout,VALUE_FMT,rem);
- fprintf(stdout," quotient ");
- value_print(stdout,VALUE_FMT,quo);
- fprintf(stdout," \n");
-
- /* Apparently the % operator is strange when sign are different */
- if(value_neg_p(rem)) {
- value_addto(rem,rem,Diag[0]->p[i][i]);
- value_decrement(quo,quo);
- };
- fprintf(stdout,"apres pourcent ");
- value_print(stdout,VALUE_FMT,rem);
- fprintf(stdout," quotient ");
- value_print(stdout,VALUE_FMT,quo);
- fprintf(stdout," \n");
- value_assign( Diag[0]->p[i][Diag[0]->NbColumns-1],rem);
- value_assign(V[0]->p[i][V[0]->NbColumns-1],quo);
- }
- value_clear(sum);
- value_clear(quo); value_clear(rem);
- return;
-} /* AffineSmith */
-
-/*
- * Given a lattice 'A' and a boolean variable 'Forward', homogenise the lattice
- * if 'Forward' is True, otherwise if 'Forward' is False, dehomogenise the
- * lattice 'A'.
- * Algorithm:
- * (1) If Forward == True
- * Put the last row first.
- * Put the last columns first.
- * (2) Else
- * Put the first row last.
- * Put the first column last.
- * (3) Return the result.
- */
-Lattice *Homogenise(Lattice *A, Bool Forward) {
-
- Lattice *result;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug","a");
- fprintf(fp,"\nEntered HOMOGENISE \n");
- fclose(fp);
-#endif
-
- result = (Lattice *)Matrix_Copy(A);
- if (Forward == True ) {
- PutColumnFirst((Matrix *)result, A->NbColumns-1);
- PutRowFirst((Matrix *)result, result->NbRows-1);
- }
- else {
- PutColumnLast((Matrix *)result,0);
- PutRowLast((Matrix *)result,0);
- }
- return result;
-} /* Homogenise */
-
-/*
- * Given two lattices 'A' and 'B', verify if lattice 'A' is included in 'B' or
- * not. If 'A' is included in 'B' the 'A' intersection 'B', will be 'A'. So,
- * compute 'A' intersection 'B' and check if it is the same as 'A'.
- */
-Bool LatticeIncludes(Lattice *A, Lattice *B) {
-
- Lattice *temp, *UA, *HA;
- Bool flag = False;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered LATTICE INCLUDES \n");
- fclose(fp);
-#endif
-
- AffineHermite(A,&HA,&UA);
- temp = LatticeIntersection(B,HA);
- if (sameLattice(temp, HA) == True)
- flag = True;
-
- Matrix_Free((Matrix *)temp);
- Matrix_Free((Matrix *)UA);
- Matrix_Free((Matrix *)HA);
- return flag;
-} /* LatticeIncludes */
-
-/*
- * Given two lattices 'A' and 'B', verify if 'A' and 'B' are the same lattice.
- * Algorithm:
- * The Affine Hermite form of two full dimensional matrices are
- * unique. So, take the Affine Hermite form of both 'A' and 'B' and compare the
- * matrices. If they are equal, the function returns True, else it returns
- * False.
- */
-Bool sameLattice(Lattice *A, Lattice *B) {
-
- Lattice *HA, *HB, *UA, *UB;
- int i,j;
- Bool result = True;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered SAME LATTICE \n");
- fclose(fp);
-#endif
-
- AffineHermite(A, &HA, &UA);
- AffineHermite(B, &HB, &UB);
-
- for (i = 0 ; i < A->NbRows; i ++)
- for (j = 0; j < A->NbColumns; j ++)
- if (value_ne(HA->p[i][j],HB->p[i][j])) {
- result = False;
- break;
- }
-
- Matrix_Free ((Matrix *) HA);
- Matrix_Free ((Matrix *) HB);
- Matrix_Free ((Matrix *) UA);
- Matrix_Free ((Matrix *) UB);
-
- return result;
-} /* sameLattice */
-
-/*
- * Given a matrix 'A' and an integer 'dimension', do the following:
- * If dimension < A->dimension), output a (dimension * dimension) submatrix of
- * A. Otherwise the output matrix is [A 0][0 ID]. The order if the identity
- * matrix is (dimension - A->dimension). The input matrix is not necessarily
- * a Polylib matrix but the output is a polylib matrix.
- */
-Lattice *ChangeLatticeDimension(Lattice *A, int dimension) {
-
- int i, j;
- Lattice *Result ;
-
- Result = Matrix_Alloc(dimension, dimension);
- if(dimension <= A->NbRows) {
- for (i = 0; i < dimension; i ++)
- for (j = 0; j < dimension; j ++)
- value_assign(Result->p[i][j],A->p[i][j]);
- return Result;
- }
- for (i = 0; i < A->NbRows; i ++)
- for (j = 0; j < A->NbRows; j ++)
- value_assign(Result->p[i][j],A->p[i][j]);
-
- for (i = A->NbRows; i < dimension; i ++)
- for (j = 0; j < dimension; j ++) {
- value_set_si(Result->p[i][j],0);
- value_set_si(Result->p[j][i],0);
- }
- for (i = A->NbRows; i < dimension; i ++)
- value_set_si(Result->p[i][i],1);
- return Result;
-} /* ChangeLatticeDimension */
-
-/*
- * Given an affine lattice 'A', return a matrix of the linear part of the
- * lattice.
- */
-Lattice *ExtractLinearPart(Lattice *A) {
-
- Lattice *Result;
- int i, j;
- Result = (Lattice *) Matrix_Alloc(A->NbRows-1, A->NbColumns-1);
- for (i = 0; i < A->NbRows-1; i ++)
- for (j = 0; j < A->NbColumns-1; j ++)
- value_assign(Result->p[i][j],A->p[i][j]);
- return Result;
-} /* ExtractLinearPart */
-
-static Matrix *MakeDioEqforInter(Matrix *A, Matrix *B);
-
-/*
- * Given two lattices 'A' and 'B', return the intersection of the two lattcies.
- * The dimension of 'A' and 'B' should be the same.
- * Algorithm:
- * (1) Verify if the lattcies 'A' and 'B' have the same affine part.
- * If they have same affine part, then only their Linear parts
- * need to be intersected. If they don't have the same affine
- * part then the affine part has to be taken into consideration.
- * For this, homogenise the lattices to get their Hermite Forms
- * and then find their intersection.
- *
- * (2) Step(2) involves, solving the Diophantine Equations in order
- * to extract the intersection of the Lattices. The Diophantine
- * equations are formed taking into consideration whether the
- * affine part has to be included or not.
- *
- * (3) Solve the Diophantine equations.
- *
- * (4) Extract the necessary information from the result.
- *
- * (5) If the lattices have different affine parts and they were
- * homogenised, the result is dehomogenised.
- */
-Lattice *LatticeIntersection(Lattice *X, Lattice *Y) {
-
- int i, j, exist;
- Lattice *result = NULL, *U = NULL ;
- Lattice *A = NULL, *B = NULL, *H = NULL;
- Matrix *fordio;
- Vector *X1 = NULL;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered LATTICEINTERSECTION \n");
- fclose(fp);
-#endif
-
- if (X->NbRows != X->NbColumns) {
- fprintf(stderr, "\nIn LatticeIntersection : The Input Matrix X is a not a well defined Lattice\n");
- return EmptyLattice(X->NbRows);
- }
-
- if (Y->NbRows != Y->NbColumns) {
- fprintf (stderr, "\nIn LatticeIntersection : The Input Matrix Y is a not a well defined Lattice\n");
- return EmptyLattice(X->NbRows);
- }
-
- if (Y->NbRows != X->NbRows) {
- fprintf (stderr, "\nIn LatticeIntersection : the input lattices X and Y are of incompatible dimensions\n");
- return EmptyLattice(X->NbRows);
- }
-
- if (isinHnf(X))
- A = (Lattice *) Matrix_Copy(X);
- else {
- AffineHermite(X, &H, &U);
- A = (Lattice *)Matrix_Copy (H);
- Matrix_Free((Matrix *) H);
- Matrix_Free((Matrix *) U);
- }
-
- if (isinHnf(Y))
- B = (Lattice *)Matrix_Copy(Y);
- else {
- AffineHermite(Y, &H, &U);
- B = (Lattice *)Matrix_Copy (H);
- Matrix_Free((Matrix *) H);
- Matrix_Free((Matrix *) U);
- }
-
- if ((isEmptyLattice(A)) || (isEmptyLattice (B))) {
- result = EmptyLattice(X->NbRows);
- Matrix_Free ((Matrix *) A);
- Matrix_Free ((Matrix *) B);
- return result;
- }
- fordio = MakeDioEqforInter (A, B);
- Matrix_Free (A);
- Matrix_Free (B);
- exist = SolveDiophantine(fordio,(Matrix **) &U, &X1);
- if (exist < 0) { /* Intersection is NULL */
- result = (EmptyLattice(X->NbRows));
- return result;
- }
-
- result = (Lattice *)Matrix_Alloc(X->NbRows, X->NbColumns);
- for (i = 0; i < result->NbRows-1; i ++)
- for (j = 0; j < result->NbColumns-1; j ++)
- value_assign(result->p[i][j],U->p[i][j]);
-
- for (i = 0; i < result->NbRows-1; i ++)
- value_assign(result->p[i][result->NbColumns-1],X1->p[i]);
- for (i = 0; i < result->NbColumns-1; i ++)
- value_set_si(result->p[result->NbRows-1][i],0);
- value_set_si(result->p[result->NbRows-1][result->NbColumns-1],1);
-
- Matrix_Free((Matrix *) U);
- Vector_Free(X1);
- Matrix_Free(fordio);
-
- AffineHermite(result,&H,&U);
- Matrix_Free((Matrix *)result);
- result = (Lattice *)Matrix_Copy(H);
-
- Matrix_Free((Matrix *) H);
- Matrix_Free((Matrix *) U);
-
- /* Check whether the Lattice is NULL or not */
-
- if (isEmptyLattice (result)) {
- Matrix_Free ((Matrix *)result);
- return (EmptyLattice (X->NbRows));
- }
- return result;
-} /* LatticeIntersection */
-
-static Matrix * MakeDioEqforInter (Lattice *A, Lattice *B) {
-
- Matrix *Dio ;
- int i,j;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered MAKEDIOEQFORINTER \n");
- fclose(fp);
-#endif
-
- Dio = Matrix_Alloc(2*(A->NbRows-1) + 1, 3 * (A->NbColumns-1)+1);
-
- for (i = 0; i < Dio->NbRows; i ++)
- for (j = 0; j < Dio->NbColumns; j ++)
- value_set_si(Dio->p[i][j],0);
-
- for (i = 0; i < A->NbRows-1; i++) {
- value_set_si(Dio->p[i][i],1);
- value_set_si(Dio->p[i+A->NbRows-1][i],1);
- }
- for (i = 0; i < A->NbRows-1 ; i ++)
- for (j = 0; j < A->NbRows-1; j ++) {
- value_oppose(Dio->p[i][j+A->NbRows-1],A->p[i][j]);
- value_oppose(Dio->p[i+(A->NbRows-1)][j+2*(A->NbRows-1)],B->p[i][j]);
- }
-
- /* Adding the affine part */
-
- for (i = 0; i < A->NbColumns-1; i++) {
- value_oppose(Dio->p[i][Dio->NbColumns-1],A->p[i][A->NbColumns-1]);
- value_oppose(Dio->p[i+A->NbRows-1][Dio->NbColumns-1],B->p[i][A->NbColumns-1]) ;
- }
- value_set_si(Dio->p[Dio->NbRows-1][Dio->NbColumns-1],1);
- return Dio;
-} /* MakeDioEqforInter */
-
-static void AddLattice(LatticeUnion *,Matrix *, Matrix *, int , int);
-LatticeUnion *SplitLattice(Matrix *, Matrix *, Matrix *);
-
-
-
-/*
- * The function is transforming a lattice X in a union of lattices based on a starting lattice Y.
- * Note1: If the intersection of X and Y lattices is empty the result is identic with the first argument (X) because no operation can be made.
- *Note2: The function is availabe only for simple Lattices and not for a union of Lattices.
-
- * Step 1: Find Intersection = LatticeIntersection (A, B).
- * Step 2: Extract the Linear Parts of the Lattices A and Intersection.
- * (while dealing with Basis we only deal with the Linear Parts)
- * Step 3: Let M1 = Basis of A and M2 = Basis of B.
- * Let B1 and B2 be the Basis of A and B respectively,
- * corresponding to the above Theorem.
- * Then we Have B1 = M1 * U1 {a unimodular Matrix }
- * and B2 = M2 * U2. M1 and M2 we know, they are the linear
- * parts we obtained in Step 2. Our Task is now to find U1 and
- * U2.
- * We know that B1 * Delta = B2.
- * i.e. M1 * U1 * Delta = M2 * U2
- * or U1*Delta*U2Inverse = M1Inverse * M2.
- * and Delta is the Diagonal Matrix which satisifies the
- * above properties (in the Theorem).
- * So Delta is nothing but the Smith Normal Form of
- * M1Inverse * M2.
- * So, first we have to find M1Inverse.
- *
- * This Step, involves finding the Inverse of the Matrix M1.
- * We find the Inverse using the Polylib function
- * Matrix_Inverse. There is a catch here, the result of this
- * function is an integral matrix, not necessarily the exact
- * Inverse (since M1 need not be Unimodular), but a multiple
- * of the actual inverse. The number by which we have to divide
- * the matrix, is not obtained here as the input matrix is not
- * a Polylib matrix { We input only the Linear part }. Later I
- * give a way for finding that number.
- *
- * M1Inverse = Matrix_Inverse ( M1 );
- *
- * Step 4 : MtProduct = Matrix_Product (M1Inverse, M2);
- * Step 5 : SmithNormalFrom (MtProduct, Delta, U, V);
- * U1 = U and U2Inverse = V.
- * Step 6 : Find U2 = Matrix_Inverse (U2inverse). Here there is no prob
- * as U1 and its inverse are unimodular.
- *
- * Step 7 : Compute B1 = M1 * U1;
- * Step 8 : Compute B2 = M2 * U2;
- * Step 9 : Earlier when we computed M1Inverse, we knew that it was not
- * the exact inverse but a multiple of it. Now we find the
- * number, such that ( M1Inverse / number ) would give us the
- * exact inverse of M1.
- * We know that B1 * Delta = B2.
- * Let k = B2[0][0] / B1[0][0].
- * Let number = Delta[0][0]/k;
- * This 'number' is the number we want.
- * We Divide the matrix Delta by this number, to get the actual
- * Delta such that B1 * Delta = B2.
- * Step 10 : Call Split Lattice (B1, B2, Delta ).
- * This function returns the Union of Lattices in such a way
- * that B2 is at the Head of this List.
- *
- *If the intersection between X and Y is empty then the result is NULL.
- */
-
-
-LatticeUnion *Lattice2LatticeUnion(Lattice *X,Lattice *Y)
-{
- Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL, *Intersection=NULL;
- Matrix *U = NULL,*M1 = NULL, *M2 = NULL, *M1Inverse = NULL,*MtProduct = NULL;
- Matrix *Vinv, *V , *temp, *DiagMatrix ;
-
- LatticeUnion *Head = NULL, *tempHead = NULL;
- int i;
- Value k;
-
-
- Intersection = LatticeIntersection(X,Y);
- if (isEmptyLattice(Intersection) == True) {
- fprintf(stderr,"\nIn Lattice2LatticeUnion : the input lattices X and Y do not have any common part\n");
- return NULL;
- }
-
- value_init(k);
- M1 = (Matrix *)ExtractLinearPart(X);
- M2 = (Matrix *)ExtractLinearPart(Intersection);
-
- M1Inverse = Matrix_Alloc(M1->NbRows,M1->NbColumns);
- temp = Matrix_Copy(M1);
- Matrix_Inverse(temp,M1Inverse);
- Matrix_Free(temp);
-
- MtProduct = Matrix_Alloc(M1->NbRows, M1->NbColumns);
- Matrix_Product(M1Inverse,M2,MtProduct) ;
- Smith(MtProduct, &U, &Vinv, &DiagMatrix);
- V = Matrix_Alloc(Vinv->NbRows,Vinv->NbColumns);
- Matrix_Inverse(Vinv, V);
- Matrix_Free(Vinv);
- B1 = Matrix_Alloc(M1->NbRows, U->NbColumns);
- B2 = Matrix_Alloc(M2->NbRows, V->NbColumns);
- Matrix_Product(M1, U, B1);
- Matrix_Product(M2, V, B2);
- Matrix_Free(M1);
- Matrix_Free(M2);
- value_division(k,B2->p[0][0],B1->p[0][0]);
- value_division(k,DiagMatrix->p[0][0],k);
- for (i = 0; i < DiagMatrix->NbRows; i++)
- value_division(DiagMatrix->p[i][i],DiagMatrix->p[i][i],k);
- newB1 = ChangeLatticeDimension(B1, B1->NbRows + 1);
- Matrix_Free(B1);
- newB2 = ChangeLatticeDimension(B2, B2->NbRows +1);
- Matrix_Free(B2);
- for(i = 0; i < newB1->NbRows - 1;i ++)
- value_assign(newB2->p[i][newB1->NbRows-1],Intersection->p[i][X->NbRows-1]);
- Head = SplitLattice(newB1,newB2,DiagMatrix);
- Matrix_Free(newB1);
- Matrix_Free(DiagMatrix);
- value_clear(k);
- return Head;
-}
-
-
-
-/**
-
-*** Method :
-***
-**/
-/*
- * Return the Union of lattices that constitute the difference the lattices
- * 'A' and 'B'. The dimensions of 'A' and 'B' should be the same.
- * Note :
- * Inorder to Find the Difference of Lattices, we make use of
- * the following facts.
- *
- * Theorem : Given Two Lattices L1 and L2, (L2 subset of L1) there exists a
- * Basis B = {b1, b2,..bn} of L1 and integers {a1, a2...,an} such
- * that a1 divides a2, a2 divides a3 and so on and {a1b1, a2b2 ,...,
- * .., anbn} is a Basis of L2. So given this theorem we can express
- * the Lattice L1 in terms of Union of Lattices Involving L2, such
- * that Lattice L1 = B1 = Union of (B2 + i1b1 + i2b2 + .. inbn) such
- * that 0 <= i1 < a1; 0 <= i2 < a2; ....... 0 <= in < an. We also
- * know that A/B = A/(A Intersection B) and that (A Intersection B)
- * is a subset of A. So, Making use of these two facts, we find the
- * A/B. We Split The Lattice A in terms of Lattice (A Int B). From
- * this Union of Lattices Delete the Lattice (A Int B).
- *
- * Algorithm :
- *
- * Step 1: Find Intersection = LatticeIntersection (A, B).
- * Step 2: Extract the Linear Parts of the Lattices A and Intersection.
- * (while dealing with Basis we only deal with the Linear Parts)
- * Step 3: Let M1 = Basis of A and M2 = Basis of B.
- * Let B1 and B2 be the Basis of A and B respectively,
- * corresponding to the above Theorem.
- * Then we Have B1 = M1 * U1 {a unimodular Matrix }
- * and B2 = M2 * U2. M1 and M2 we know, they are the linear
- * parts we obtained in Step 2. Our Task is now to find U1 and
- * U2.
- * We know that B1 * Delta = B2.
- * i.e. M1 * U1 * Delta = M2 * U2
- * or U1*Delta*U2Inverse = M1Inverse * M2.
- * and Delta is the Diagonal Matrix which satisifies the
- * above properties (in the Theorem).
- * So Delta is nothing but the Smith Normal Form of
- * M1Inverse * M2.
- * So, first we have to find M1Inverse.
- *
- * This Step, involves finding the Inverse of the Matrix M1.
- * We find the Inverse using the Polylib function
- * Matrix_Inverse. There is a catch here, the result of this
- * function is an integral matrix, not necessarily the exact
- * Inverse (since M1 need not be Unimodular), but a multiple
- * of the actual inverse. The number by which we have to divide
- * the matrix, is not obtained here as the input matrix is not
- * a Polylib matrix { We input only the Linear part }. Later I
- * give a way for finding that number.
- *
- * M1Inverse = Matrix_Inverse ( M1 );
- *
- * Step 4 : MtProduct = Matrix_Product (M1Inverse, M2);
- * Step 5 : SmithNormalFrom (MtProduct, Delta, U, V);
- * U1 = U and U2Inverse = V.
- * Step 6 : Find U2 = Matrix_Inverse (U2inverse). Here there is no prob
- * as U1 and its inverse are unimodular.
- *
- * Step 7 : Compute B1 = M1 * U1;
- * Step 8 : Compute B2 = M2 * U2;
- * Step 9 : Earlier when we computed M1Inverse, we knew that it was not
- * the exact inverse but a multiple of it. Now we find the
- * number, such that ( M1Inverse / number ) would give us the
- * exact inverse of M1.
- * We know that B1 * Delta = B2.
- * Let k = B2[0][0] / B1[0][0].
- * Let number = Delta[0][0]/k;
- * This 'number' is the number we want.
- * We Divide the matrix Delta by this number, to get the actual
- * Delta such that B1 * Delta = B2.
- * Step 10 : Call Split Lattice (B1, B2, Delta ).
- * This function returns the Union of Lattices in such a way
- * that B2 is at the Head of this List.
- * Step 11 : To Remove B2 From the list of the Union of Lattices.
- * Head = Head->next;
- * Step 12 : Free the Memory that is now not needed and return Head.
- *
- */
-LatticeUnion *LatticeDifference(Lattice *A,Lattice *B) {
-
- Lattice *Intersection = NULL;
- LatticeUnion *Head = NULL, *tempHead = NULL;
- Matrix *H , *U1 , *X, *Y ;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered LATTICEDIFFERENCE \n");
- fclose(fp);
-#endif
-
- if (A->NbRows != A->NbColumns) {
- fprintf(stderr,"\nIn LatticeDifference : The Input Matrix A is not a proper Lattice \n");
- return NULL;
- }
-
- if (B->NbRows != B->NbColumns) {
- fprintf(stderr,"\nIn LatticeDifference : The Input Matrix B is not a proper Lattice \n");
- return NULL;
- }
-
- if (A->NbRows != B->NbRows) {
- fprintf(stderr,"\nIn Lattice Difference : The Input Lattices A and B have ");
- fprintf(stderr,"incompatible dimensions \n");
- return NULL;
- }
-
-if (isinHnf (A) != True) {
- AffineHermite(A,&H,&U1);
- X = Matrix_Copy(H);
- Matrix_Free(U1);
- Matrix_Free(H);
- }
- else
- X = Matrix_Copy(A);
-
- if (isinHnf(B) != True) {
- AffineHermite(B,&H,&U1);
- Y = Matrix_Copy(H);
- Matrix_Free(H);
- Matrix_Free(U1);
- }
- else
- Y = Matrix_Copy(B);
- if (isEmptyLattice(X)) {
- return NULL;
- }
-
- Head=Lattice2LatticeUnion(X,Y);
-
-/* If the spliting operation can't be done the result is X. */
-
- if (Head == NULL) {
- Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
- Head->M = Matrix_Copy(X);
- Head->next = NULL;
- Matrix_Free(X);
- Matrix_Free(Y);
- return Head;
- }
-
- tempHead = Head;
- Head = Head->next;
- Matrix_Free (tempHead->M);
- tempHead->next = NULL;
- free(tempHead);
-
- if ((Head != NULL))
- Head = LatticeSimplify (Head);
- Matrix_Free (X);
- Matrix_Free (Y);
-
- return Head;
-} /* LatticeDifference */
-
-
-/*
- * Given a Lattice 'B1' and a Lattice 'B2' and a Diagonal Matrix 'C' such that
- * 'B2' is a subset of 'B1' and C[0][0] divides C[1][1], C[1][1] divides C[2]
- * [2] and so on, output the list of matrices whose union is B1. The function
- * expresses the Lattice B1 in terms of B2 Unions of B1 = Union of {B2 + i0b0 +
- * i1b1 + .... + inbn} where 0 <= i0 < C[0][0]; 0 <= i1 < C[1][1] and so on and
- * {b0 ... bn} are the columns of Lattice B1. The list is so formed that the
- * Lattice B2 is the Head of the list.
- */
-LatticeUnion *SplitLattice(Lattice *B1, Lattice *B2, Matrix *C) {
-
- int i;
-
- LatticeUnion *Head = NULL;
- Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
- Head->M = (Lattice *)B2;
- Head->next = NULL;
- for (i = 0; i < C->NbRows ; i++)
- AddLattice(Head,B1,B2,VALUE_TO_INT(C->p[i][i]),i);
- return Head;
-} /* SplitLattice */
-
-/*
- * Given lattices 'B1' and 'B2', an integer 'NumofTimes', a column number
- * 'Colnumber' and a pointer to a list of lattices, the function does the
- * following :-
- * For every lattice in the list, it adds a set of lattices such that the
- * affine part of the new lattices is greater than the original lattice by 0 to
- * NumofTimes-1 * {the (ColumnNumber)-th column of B1}.
- * Note :
- * Three pointers are defined to point at various points of the list. They are:
- * Head -> It always points to the head of the list.
- * tail -> It always points to the last element in the list.
- * marker -> It points to the element, which is the last element of the Input
- * list.
- */
-static void AddLattice (LatticeUnion *Head, Matrix *B1, Matrix *B2, int NumofTimes, int Colnumber) {
-
- LatticeUnion *temp, *tail, *marker;
- int i,j;
- Value tmp;
-
- value_init(tmp);
- tail = Head;
- while (tail->next != NULL)
- tail = tail->next;
- marker = tail;
-
- for(temp = Head; temp != NULL; temp=temp->next) {
- for (i = 1; i < NumofTimes; i++) {
- Lattice *tempMatrix, *H, *U;
-
- tempMatrix = (Lattice *)Matrix_Copy(temp->M);
- for (j = 0; j < B2->NbRows; j++) {
- value_set_si(tmp,i);
- value_addmul(tempMatrix->p[j][B2->NbColumns-1], tmp, B1->p[j][Colnumber]);
- }
- tail->next = (LatticeUnion *)malloc(sizeof(LatticeUnion));
- AffineHermite(tempMatrix,&H,&U);
- Matrix_Free((Matrix *)tempMatrix);
- Matrix_Free(U);
- tail->next->M = H;
- tail->next->next=NULL;
- tail = tail->next;
- }
- if (temp == marker)
- break;
- }
- value_clear(tmp);
- return;
-} /* AddLattice */
-
-/*
- * Given a polyhedron 'A', store the Hermite basis 'B' and return the true
- * dimension of the polyhedron 'A'.
- * Algorithm :
- *
- * 1) First we find all the vertices of the Polyhedron A.
- * Now suppose the vertices are [v1, v2...vn], then
- * a particular set of vectors governing the space of A are
- * given by [v1-v2, v1-v3, ... v1-vn] (let us say V).
- * So we initially calculate these vectors.
- * 2) Then there are the rays and lines which contribute to the
- * space in which A is going to lie.
- * So we append to the rays and lines. So now we get a matrix
- * {These are the rows} [ V ] [l1] [l2]...[lk]
- * where l1 to lk are either rays or lines of the Polyhedron A.
- * 3) The above matrix is the set of vectors which determine
- * the space in which A is going to lie.
- * Using this matrix we find a Basis which is such that
- * the first 'm' columns of it determine the space of A.
- * 4) But we also have to ensure that in the last 'n-m'
- * coordinates the Polyhedron is '0', this is done by
- * taking the image by B(inv) of A and finding the remaining
- * equalities, and composing it with the matrix B, so as
- * to get a new matrix which is the actual Hermite Basis of
- * the Polyhedron.
- */
-int FindHermiteBasisofDomain(Polyhedron *A, Matrix **B) {
-
- int i, j;
- Matrix *temp,*temp1, *tempinv, *Newmat ;
- Matrix *vert, *rays, *result;
- Polyhedron *Image;
- int rank, equcount ;
- int noofvertices = 0, noofrays = 0;
- int vercount , raycount;
- Value lcm, fact;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered FINDHERMITEBASISOFDOMAIN \n");
- fclose(fp);
-#endif
-
- POL_ENSURE_FACETS(A);
- POL_ENSURE_VERTICES(A);
-
- /* Checking is empty */
- if (emptyQ(A)) {
- B[0] = Identity(A->Dimension+1);
- return(-1);
- }
-
- value_init(lcm); value_init(fact);
- value_set_si(lcm,1);
-
- /* Finding the Vertices */
- for (i = 0; i < A->NbRays; i++)
- if ((value_notzero_p(A->Ray[i][0])) && value_notzero_p(A->Ray[i][A->Dimension+1]))
- noofvertices++;
- else
- noofrays ++;
-
- vert = Matrix_Alloc(noofvertices,A->Dimension+1);
- rays = Matrix_Alloc(noofrays,A->Dimension);
- vercount = 0;
- raycount = 0;
-
- for(i = 0; i < A->NbRays; i++) {
- if ((value_notzero_p(A->Ray[i][0])) && value_notzero_p(A->Ray[i][A->Dimension+1])) {
- for(j = 1; j < A->Dimension+2; j++)
- value_assign(vert->p[vercount][j-1],A->Ray[i][j]);
- value_lcm(lcm, lcm, A->Ray[i][j-1]);
- vercount++;
- }
- else {
- for (j = 1; j < A->Dimension+1; j++)
- value_assign(rays->p[raycount][j-1],A->Ray[i][j]);
- raycount++;
- }
- }
-
- /* Multiplying the rows by the lcm */
- for(i = 0; i < vert->NbRows; i ++) {
- value_division(fact,lcm,vert->p[i][vert->NbColumns-1]);
- for (j = 0; j < vert->NbColumns-1; j++)
- value_multiply(vert->p[i][j],vert->p[i][j],fact);
- }
-
- /* Drop the Last Columns */
- temp = RemoveColumn(vert,vert->NbColumns-1);
- Matrix_Free(vert);
-
- /* Getting the Vectors */
- vert = Matrix_Alloc(temp->NbRows-1, temp->NbColumns);
- for (i = 1; i < temp->NbRows; i++)
- for (j = 0; j < temp->NbColumns ; j++)
- value_subtract(vert->p[i-1][j],temp->p[0][j],temp->p[i][j]);
-
- Matrix_Free(temp);
-
- /* Add the Rays and Lines */
- /* Combined Matrix */
- result = Matrix_Alloc(vert->NbRows+rays->NbRows, vert->NbColumns);
- for (i = 0; i < vert->NbRows; i++)
- for (j = 0 ;j < result->NbColumns ; j++)
- value_assign(result->p[i][j],vert->p[i][j]);
-
- for (; i<result->NbRows; i++)
- for (j = 0; j < result->NbColumns; j++)
- value_assign(result->p[i][j],rays->p[i-vert->NbRows][j]);
-
- Matrix_Free(vert);
- Matrix_Free(rays);
-
- rank = findHermiteBasis(result, &temp);
- temp1 = ChangeLatticeDimension(temp,temp->NbRows+1);
-
- Matrix_Free(result);
- Matrix_Free(temp);
-
- /* Adding the Affine Part to take care of the Equalities */
- temp = Matrix_Copy(temp1);
- tempinv = Matrix_Alloc(temp->NbRows,temp->NbColumns);
- Matrix_Inverse(temp,tempinv);
- Matrix_Free(temp);
- Image = DomainImage(A,tempinv,MAXNOOFRAYS);
- Matrix_Free(tempinv);
- Newmat = Matrix_Alloc(temp1->NbRows,temp1->NbColumns);
- for(i = 0; i < rank ; i++)
- for(j = 0; j < Newmat->NbColumns ; j++)
- value_set_si(Newmat->p[i][j],0);
- for(i = 0; i < rank; i++)
- value_set_si(Newmat->p[i][i],1);
- equcount = 0;
- for (i = 0; i < Image->NbConstraints; i ++)
- if (value_zero_p(Image->Constraint[i][0])) {
- for (j = 1; j<Image->Dimension+2; j ++)
- value_assign(Newmat->p[rank+equcount][j-1],Image->Constraint[i][j]);
- ++equcount ;
- }
- Domain_Free(Image);
- for (i = 0; i < Newmat->NbColumns-1; i++)
- value_set_si(Newmat->p[Newmat->NbRows-1][i],0);
- value_set_si(Newmat->p[Newmat->NbRows-1][Newmat->NbColumns-1],1);
- temp = Matrix_Alloc(Newmat->NbRows, Newmat->NbColumns);
- Matrix_Inverse(Newmat,temp);
- Matrix_Free(Newmat);
- B[0] = Matrix_Alloc(temp1->NbRows,temp->NbColumns);
-
- Matrix_Product(temp1,temp,B[0]);
- Matrix_Free(temp1);
- Matrix_Free(temp);
- value_clear(lcm);
- value_clear(fact);
- return rank;
-} /* FindHermiteBasisofDomain */
-
-/*
- * Return the image of a lattice 'A' by the invertible, affine, rational
- * function 'M'.
- */
-Lattice *LatticeImage(Lattice *A, Matrix *M) {
-
- Lattice *Img, *temp, *Minv;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp, "\nEntered LATTICEIMAGE \n");
- fclose(fp);
-#endif
-
- if ((A->NbRows != M->NbRows) || (M->NbRows != M->NbColumns))
- return (EmptyLattice (A->NbRows));
-
- if (value_one_p(M->p[M->NbRows-1][M->NbColumns-1])) {
- Img = Matrix_Alloc ( M->NbRows, A->NbColumns );
- Matrix_Product (M,A,Img);
- return Img;
- }
- temp = Matrix_Copy(M);
- Minv = Matrix_Alloc(temp->NbColumns, temp->NbRows);
- Matrix_Inverse(temp, Minv);
- Matrix_Free(temp);
-
- Img = LatticePreimage(A, Minv);
- Matrix_Free (Minv);
- return Img;
-} /* LatticeImage */
-
-/*
- * Return the preimage of a lattice 'L' by an affine, rational function 'G'.
- * Algorithm:
- * (1) Prepare Diophantine equation :
- * [Gl -Ll][x y] = [Ga -La]{"l-linear, a-affine"}
- * (2) Solve the Diophantine equations.
- * (3) If there is solution to the Diophantine eq., extract the
- * general solution and the particular solution of x and that
- * forms the preimage of 'L' by 'G'.
- */
-Lattice *LatticePreimage(Lattice *L, Matrix *G) {
-
- Matrix *Dio, *U ;
- Lattice *Result;
- Vector *X;
- int i,j;
- int rank;
- Value divisor, tmp;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered LATTICEPREIMAGE \n");
- fclose(fp);
-#endif
-
- /* Check for the validity of the function */
- if (G->NbRows != L->NbRows) {
- fprintf (stderr, "\nIn LatticePreimage: Incompatible types of Lattice and the function\n");
- return (EmptyLattice(G->NbColumns));
- }
-
- value_init(divisor); value_init(tmp);
-
- /* Making Diophantine Equations [g -L] */
- value_assign(divisor,G->p[G->NbRows-1][G->NbColumns-1]);
- Dio = Matrix_Alloc(G->NbRows, G->NbColumns+L->NbColumns-1);
- for (i = 0; i < G->NbRows-1; i++)
- for (j = 0; j < G->NbColumns-1; j++)
- value_assign(Dio->p[i][j],G->p[i][j]);
-
- for (i = 0;i < G->NbRows-1; i++)
- for (j = 0; j < L->NbColumns-1; j++) {
- value_multiply(tmp,divisor,L->p[i][j]);
- value_oppose(Dio->p[i][j+G->NbColumns-1],tmp);
- }
-
- for (i = 0; i < Dio->NbRows-1; i++) {
- value_multiply(tmp,divisor,L->p[i][L->NbColumns-1]);
- value_subtract(tmp,G->p[i][G->NbColumns-1],tmp);
- value_assign(Dio->p[i][Dio->NbColumns-1],tmp);
- }
- for (i = 0; i < Dio->NbColumns-1; i++)
- value_set_si(Dio->p[Dio->NbRows-1][i],0);
-
- value_set_si(Dio->p[Dio->NbRows-1][Dio->NbColumns-1],1);
- rank = SolveDiophantine(Dio, &U, &X);
-
- if (rank == -1)
- Result = EmptyLattice(G->NbColumns);
- else {
- Result = Matrix_Alloc (G->NbColumns, G->NbColumns);
- for (i = 0; i < Result->NbRows-1; i++)
- for (j = 0; j < Result->NbColumns-1; j++)
- value_assign(Result->p[i][j],U->p[i][j]);
-
- for (i = 0; i < Result->NbRows-1; i ++)
- value_assign(Result->p[i][Result->NbColumns-1],X->p[i]);
- Matrix_Free (U);
- Vector_Free (X);
- for (i = 0; i < Result->NbColumns-1; i ++)
- value_set_si(Result->p[Result->NbRows-1][i],0);
- value_set_si(Result->p[i][i],1);
- }
- Matrix_Free(Dio);
- value_clear(divisor);
- value_clear(tmp);
- return Result;
-} /* LatticePreimage */
-
-/*
- * Return True if the matrix 'm' is a valid lattice, otherwise return False.
- * Note: A valid lattice has the last row as [0 0 0 ... 1].
- */
-Bool IsLattice(Matrix *m) {
-
- int i;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen ("_debug", "a");
- fprintf (fp, "\nEntered ISLATTICE \n");
- fclose (fp);
-#endif
-
- /* Is it necessary to check if the lattice
- is fulldimensional or not here only? */
-
- if (m->NbRows != m->NbColumns)
- return False;
-
- for (i = 0; i < m->NbColumns-1; i++)
- if (value_notzero_p(m->p[m->NbRows-1][i]))
- return False ;
- if (value_notone_p(m->p[i][i]))
- return False;
- return True ;
-} /* IsLattice */
-
-/*
- * Check whether the matrix 'm' is full row-rank or not.
- */
-Bool isfulldim(Matrix *m) {
-
- Matrix *h, *u ;
- int i ;
-
- /*
- res = Hermite (m, &h, &u);
- if (res != m->NbRows)
- return False ;
- */
-
- Hermite(m, &h, &u);
- for (i = 0; i < h->NbRows; i ++)
- if (value_zero_p(h->p[i][i])) {
- Matrix_Free (h);
- Matrix_Free (u);
- return False;
- }
- Matrix_Free (h);
- Matrix_Free (u);
- return True;
-} /* isfulldim */
-
-/*
- * This function takes as input a lattice list in which the lattices have the
- * same linear part, and almost the same affinepart, i.e. if A and B are two
- * of the lattices in the above lattice list and [a1, .. , an] and [b1 .. bn]
- * are the affineparts of A and B respectively, then for 0 < i < n ai = bi and
- * 'an' may not be equal to 'bn'. These are not the affine parts in the n-th
- * dimension, but the lattices have been tranformed such that the value of the
- * elment in the dimension on which we are simplifying is in the last row and
- * also the lattices are in a sorted order.
- * This function also takes as input the dimension along which we
- * are simplifying and takes the diagonal element of the lattice along that
- * dimension and tries to find out the factors of that element and sees if the
- * list of lattices can be simplified using these factors. The output of this
- * function is the list of lattices in the simplified form and a flag to indic-
- * ate whether any form of simplification was actually done or not.
- */
-static Bool Simplify(LatticeUnion **InputList, LatticeUnion **ResultList, int dim) {
-
- int i;
- LatticeUnion *prev, *temp;
- factor allfac;
- Bool retval = False;
- int width;
- Value cnt, aux, k, fac, num, tmp, foobar;
-
- if ((*InputList == NULL) || (InputList[0]->next == NULL))
- return False ;
-
- value_init(aux); value_init(cnt);
- value_init(k); value_init(fac);
- value_init(num); value_init(tmp);
- value_init(foobar);
-
- width = InputList[0]->M->NbRows-1;
- allfac = allfactors(VALUE_TO_INT(InputList[0]->M->p[dim][dim]));
- value_set_si(cnt,0);
- for (temp = InputList[0]; temp != NULL; temp = temp->next)
- value_increment(cnt,cnt);
- for(i = 0; i < allfac.count; i++) {
- value_set_si(foobar,allfac.fac[i]);
- value_division(aux,InputList[0]->M->p[dim][dim],foobar);
- if(value_ge(cnt,aux))
- break;
- }
- if (i == allfac.count) {
- value_clear(cnt); value_clear(aux);
- value_clear(k); value_clear(fac);
- value_clear(num); value_clear(tmp);
- value_clear(foobar);
- return False;
- }
- for (; i < allfac.count; i++) {
- Bool Present = False;
- value_set_si(k,0);
-
- if (*InputList == NULL) {
- value_clear(cnt); value_clear(aux);
- value_clear(k); value_clear(fac);
- value_clear(num); value_clear(tmp);
- value_clear(foobar);
- return retval;
- }
- value_set_si(foobar,allfac.fac[i]);
- value_division(num,InputList[0]->M->p[dim][dim],foobar);
- while (value_lt(k,foobar)) {
- Present = False;
- value_assign(fac,k);
- for (temp = *InputList; temp != NULL; temp = temp->next) {
- if (value_eq(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],fac)) {
- value_set_si(foobar,allfac.fac[i]);
- value_addto(fac,fac,foobar);
- if (value_ge(fac,(*InputList)->M->p[dim][dim])) {
- Present = True;
- break;
- }
- }
- if (value_gt(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],fac))
- break;
- }
- if (Present == True) {
- retval = True;
- if (*ResultList == NULL)
- *ResultList = temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
- else {
- for (temp = *ResultList; temp->next != NULL; temp = temp->next);
- temp->next = (LatticeUnion *) malloc (sizeof (LatticeUnion));
- temp = temp->next;
- }
- temp->M = Matrix_Copy(InputList[0]->M);
- temp->next = NULL;
- value_set_si(foobar,allfac.fac[i]);
- value_assign(temp->M->p[dim][dim],foobar);
- value_assign(temp->M->p[dim][width],k);
- value_set_si(temp->M->p[width][width],1);
-
- /* Deleting the Lattices from the curlist */
- value_assign(tmp,k);
- prev = NULL;
- temp = InputList[0];
- while (temp != NULL) {
- if (value_eq(temp->M->p[width][width],tmp)) {
- if (temp == InputList[0]) {
- prev = temp;
- temp = InputList [0] = temp->next;
- Matrix_Free(prev->M);
- free(prev);
- }
- else {
- prev->next = temp->next;
- Matrix_Free(temp->M);
- free(temp);
- temp = prev->next;
- }
- value_set_si(foobar,allfac.fac[i]);
- value_addto(tmp,tmp,foobar);
- }
- else {
- prev = temp;
- temp = temp->next;
- }
- }
- }
- value_increment(k,k);
- }
- }
- value_clear(cnt); value_clear(aux);
- value_clear(k); value_clear(fac);
- value_clear(num); value_clear(tmp);
- value_clear(foobar);
- return retval;
-} /* Simplify */
-
-/*
- * This function is used in the qsort function in sorting the lattices. Given
- * two lattices 'A' and 'B', both in HNF, where A = [ [a11 0], [a21, a22, 0] .
- * .... [an1, .., ann] ] and B = [ [b11 0], [b21, b22, 0] ..[bn1, .., bnn] ],
- * then A < B, if there exists a pair <i,j> such that [aij < bij] and for every
- * other pair <i1, j1>, 0<=i1<i, 0<=j1<j [ai1j1 = bi1j1].
- */
-static int LinearPartCompare(const void *A, const void *B) {
-
- Lattice **L1, **L2;
- int i, j;
-
- L1 = (Lattice **) A;
- L2 = (Lattice **) B;
-
- for (i = 0; i < L1[0]->NbRows-1; i++)
- for (j = 0; j <= i ; j++) {
- if (value_gt(L1[0]->p[i][j],L2[0]->p[i][j]))
- return 1;
- if (value_lt(L1[0]->p[i][j],L2[0]->p[i][j]))
- return -1;
- }
- return 0;
-} /* LinearPartCompare */
-
-/*
- * This function takes as input a List of Lattices and sorts them on the basis
- * of their Linear parts. It sorts in place, as a result of which the input
- * list is modified to the sorted order.
- */
-static void LinearPartSort (LatticeUnion *Head) {
-
- int cnt;
- Lattice **Latlist;
- LatticeUnion *temp ;
-
- cnt = 0;
- for (temp = Head; temp != NULL; temp = temp->next)
- cnt ++;
-
- Latlist = (Lattice **) malloc ( sizeof (Lattice *) * cnt);
-
- cnt = 0;
- for (temp = Head; temp != NULL; temp = temp->next)
- Latlist[cnt++] = temp->M;
-
- qsort(Latlist, cnt, sizeof(Lattice *), LinearPartCompare);
-
- cnt = 0;
- for (temp = Head; temp != NULL; temp = temp->next)
- temp->M = Latlist[cnt++];
-
- free (Latlist);
- return;
-} /* LinearPartSort */
-
-/*
- * This function is used in 'AfiinePartSort' in sorting the lattices with the
- * same linear part. GIven two lattices 'A' and 'B' with affineparts [a1 .. an]
- * and [b1 ... bn], then A < B if for some 0 < i <= n, ai < bi and for 0 < i1 <
- * i, ai1 = bi1.
- */
-static int AffinePartCompare(const void *A, const void *B) {
-
- int i;
- Lattice **L1, **L2;
-
- L1 = (Lattice **)A;
- L2 = (Lattice **)B;
-
- for (i = 0; i < L1[0]->NbRows; i++) {
- if (value_gt(L1[0]->p[i][L1[0]->NbColumns-1],L2[0]->p[i][L1[0]->NbColumns-1]))
- return 1;
-
- if (value_lt(L1[0]->p[i][L1[0]->NbColumns-1],L2[0]->p[i][L1[0]->NbColumns-1]))
- return -1;
- }
- return 0 ;
-} /* AffinePartCompare */
-
-/*
- * This function takes a list of lattices with the same linear part and sorts
- * them on the basis of their affine part. The sorting is done in place.
- */
-static void AffinePartSort (LatticeUnion *List) {
-
- int cnt;
- Lattice **LatList;
- LatticeUnion *tmp;
-
- cnt = 0;
- for (tmp = List; tmp != NULL; tmp = tmp->next)
- cnt ++;
-
- LatList = (Lattice **) malloc (sizeof(Lattice *) * cnt);
-
- cnt = 0;
- for (tmp = List; tmp != NULL; tmp = tmp->next)
- LatList[cnt++] = tmp->M;
-
- qsort(LatList,cnt, sizeof (Lattice *), AffinePartCompare);
-
- cnt = 0;
- for (tmp = List; tmp != NULL; tmp = tmp->next)
- tmp->M = LatList[cnt++];
- return;
-} /* AffinePartSort */
-
-static Bool AlmostSameAffinePart(LatticeUnion *A, LatticeUnion *B) {
-
- int i;
-
- if ((A == NULL) || (B == NULL))
- return False;
-
- for (i = 0; i < A->M->NbRows-1; i ++)
- if (value_ne(A->M->p[i][A->M->NbColumns-1],B->M->p[i][A->M->NbColumns-1]))
- return False;
- return True;
-} /* AlmostSameAffinePart */
-
-/*
- * This function takes a list of lattices having the same linear part and tries
- * to simplify these lattices. This may not be the only way of simplifying the
- * lattices. The function returns a list of partially simplified lattices and
- * also a flag to tell whether any simplification was performed at all.
- */
-static Bool AffinePartSimplify(LatticeUnion *curlist, LatticeUnion **newlist) {
-
- int i;
- Value aux;
- LatticeUnion *temp, *curr, *next;
- LatticeUnion *nextlist;
- Bool change = False, chng;
-
- if (curlist == NULL)
- return False;
-
- if (curlist->next == NULL) {
- curlist->next = newlist[0];
- newlist[0] = curlist;
- return False ;
- }
-
- value_init(aux);
- for (i = 0; i < curlist->M->NbRows - 1; i ++) {
-
- /* Interchanging the elements of the Affine part for easy computation
- of the sort (using qsort) */
-
- for (temp = curlist; temp != NULL; temp = temp->next) {
- value_assign(aux,temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1]);
- value_assign(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],temp->M->p[i][temp->M->NbColumns-1]);
- value_assign(temp->M->p[i][temp->M->NbColumns-1],aux);
- }
- AffinePartSort(curlist);
- nextlist = NULL;
- curr = curlist;
- while (curr != NULL) {
- next = curr->next;
- if (!AlmostSameAffinePart(curr, next)) {
- curr->next = NULL;
- chng = Simplify(&curlist, newlist, i);
- if (nextlist == NULL)
- nextlist = curlist;
- else {
- LatticeUnion *tmp;
- for (tmp = nextlist; tmp->next; tmp=tmp->next);
- tmp->next = curlist;
- }
- change = (Bool)(change | chng);
- curlist = next;
- }
- curr = next;
- }
- curlist = nextlist;
-
- /* Interchanging the elements of the Affine part for easy computation
- of the sort (using qsort) */
-
- for(temp = curlist; temp != NULL; temp = temp->next) {
- value_assign(aux,temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1]);
- value_assign(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],temp->M->p[i][temp->M->NbColumns-1]);
- value_assign(temp->M->p[i][temp->M->NbColumns-1],aux);
- }
- if (curlist == NULL)
- break;
- }
- if ( *newlist == NULL)
- *newlist = nextlist;
- else {
- for (curr = *newlist; curr->next != NULL; curr = curr->next);
- curr->next = nextlist;
- }
- value_clear(aux);
- return change;
-} /* AffinePartSimplify */
-
-static Bool SameLinearPart(LatticeUnion *A, LatticeUnion *B) {
-
- int i, j;
- if ((A == NULL) || (B ==NULL))
- return False;
- for (i = 0; i < A->M->NbRows-1; i++)
- for (j = 0; j <= i; j++)
- if (value_ne(A->M->p[i][j],B->M->p[i][j]))
- return False;
-
- return True;
-} /* SameLinearPart */
-
-/*
- * Given a union of lattices, return a simplified list of lattices.
- */
-LatticeUnion *LatticeSimplify(LatticeUnion *latlist) {
-
- LatticeUnion *curlist, *nextlist;
- LatticeUnion *curr, *next;
- Bool change = True, chng;
-
- curlist = latlist;
- while (change == True) {
- change = False;
- LinearPartSort(curlist);
- curr = curlist;
- nextlist = NULL;
- while(curr != NULL) {
- next = curr->next;
- if (!SameLinearPart(curr, next)) {
- curr->next = NULL;
- chng = AffinePartSimplify(curlist, &nextlist);
- change = (Bool)(change | chng);
- curlist = next;
- }
- curr = next;
- }
- curlist = nextlist;
- }
- return curlist;
-} /* LatticeSimplify */
-
-int intcompare (const void *a, const void *b) {
-
- int *i, *j;
-
- i = (int *) a;
- j = (int *) b;
- if (*i > *j)
- return 1;
- if (*i < *j)
- return -1;
- return 0;
-} /* intcompare */
-
-static int polylib_sqrt(int i);
-static factor allfactors (int num) {
-
- int i,j, tmp;
- int noofelmts = 1;
- int *list, *newlist;
- int count;
- factor result;
-
- list = (int *)malloc(sizeof (int));
- list[0] = 1;
-
- tmp = num;
- for (i = 2; i <= polylib_sqrt(tmp); i++) {
- if ((tmp % i) == 0) {
- if (noofelmts == 0) {
- list = (int *) malloc (sizeof (int));
- list[0] = i;
- noofelmts = 1;
- }
- else {
- newlist = (int *) malloc (sizeof (int) * 2 * noofelmts + 1);
- for (j = 0; j < noofelmts; j++)
- newlist[j] = list[j] ;
- newlist[j] = i;
- for (j = 0; j < noofelmts; j++)
- newlist[j+noofelmts+1] = i * list[j];
- free (list);
- list = newlist;
- noofelmts= 2*noofelmts+1;
- }
- tmp = tmp / i;
- i = 1;
- }
- }
-
- if ((tmp != 0) && (tmp != num)) {
- newlist = (int *) malloc (sizeof (int) * 2 * noofelmts + 1);
- for (j = 0; j < noofelmts; j ++)
- newlist[j] = list[j] ;
- newlist[j] = tmp;
- for (j = 0; j < noofelmts; j ++)
- newlist[j+noofelmts+1] = tmp * list[j];
- free (list);
- list = newlist;
- noofelmts= 2*noofelmts+1;
- }
- qsort (list, noofelmts, sizeof(int), intcompare);
- count = 1;
- for (i = 1; i < noofelmts; i ++)
- if (list[i] != list[i-1])
- list[count++] = list[i];
- if (list[count-1] == num)
- count --;
-
- result.fac = (int *) malloc (sizeof (int) * count);
- result.count = count;
- for (i = 0; i < count; i ++)
- result.fac[i] = list[i];
- free (list);
- return result;
-} /* allfactors */
-
-static int polylib_sqrt (int i) {
-
- int j;
- j = 0;
- i = i > 0 ? i : -i;
-
- while (1) {
- if ((j * j) > i)
- break;
- else
- j ++;
- }
- return (j-1);
-} /* polylib_sqrt */
-
-
-
-
-
-
-
diff --git a/source/polylib_mod/Matop.c b/source/polylib_mod/Matop.c
deleted file mode 100644
index bfd6bd8..0000000
--- a/source/polylib_mod/Matop.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <polylib/polylib.h>
-
-/* computes c = lcm(a,b) using Gcd(a,b,&c) */
-void Lcm3(Value a, Value b, Value *c)
-{
- Value tmp;
-
- if (value_zero_p(a)) {
- value_assign(*c, b);
- return;
- }
- if (value_zero_p(b)) {
- value_assign(*c, a);
- return;
- }
- value_init(tmp);
- value_multiply(tmp, a, b);
- value_absolute(tmp, tmp);
- Gcd(a,b,c);
- value_division(*c, tmp, *c);
- value_clear(tmp);
-}
-
-/*
- * Return the lcm of 'i' and 'j'
- */
-Value *Lcm (Value i, Value j)
-{
- Value *tmp;
-
- tmp = (Value *) malloc (sizeof(Value));
- value_init(*tmp);
- Lcm3(i, j, tmp);
- return tmp;
-} /* Lcm */
-
-/*
- * Return an identity matrix of size 'size'.
- */
-Matrix *Identity(unsigned size)
-{
- unsigned i;
- Matrix *A;
-
- A = Matrix_Alloc(size, size);
- for (i = 0; i < size; i++)
- value_set_si(A->p[i][i], 1);
- return A;
-} /* Identity */
-
-/*
- * Exchange the rows 'Row1' and 'Row2' of the matrix 'M'
- */
-void ExchangeRows(Matrix *M, int Row1, int Row2) {
-
- int i;
- Value temp;
-
- value_init(temp);
- for (i = 0; i < (int)M->NbColumns; i++) {
- value_assign(temp,M->p[Row1][i]);
- value_assign(M->p[Row1][i],M->p[Row2][i]);
- value_assign(M->p[Row2][i],temp);
- }
- value_clear(temp);
- return ;
-} /* ExchangeRows */
-
-/*
- * Exchange the columns 'Column1' and 'Column2' of the matrix 'M'
- */
-void ExchangeColumns(Matrix *M, int Column1, int Column2) {
-
- int i;
-
- for (i = 0; i < M->NbRows; i++)
- value_swap(M->p[i][Column1],M->p[i][Column2]);
-
- return;
-} /* ExchangeColumns */
-
-/*
- * Return the Transpose of a matrix 'A'
- */
-Matrix *Transpose (Matrix *A) {
-
- int i,j;
- Matrix *transpose;
-
- transpose = Matrix_Alloc (A->NbColumns, A->NbRows);
- for (i = 0; i < (int)A->NbRows; i++)
- for (j = 0; j < (int)A->NbColumns; j++)
- value_assign(transpose->p[j][i],A->p[i][j]);
- return transpose;
-} /* Transpose */
-
-/*
- * Return a copy of the contents of a matrix 'Src'.
- */
-Matrix *Matrix_Copy(Matrix const *Src )
-{
- Matrix *Dst;
- unsigned i, j;
-
- Dst = Matrix_Alloc(Src->NbRows, Src->NbColumns);
-
- for (i = 0; i < Src->NbRows; i++)
- for (j = 0; j < Src->NbColumns; j++)
- value_assign(Dst->p[i][j],Src->p[i][j]);
- return Dst;
-} /* Matrix_copy */
-
-/*
- * Test if the input matrix is integral or not.
- */
-Bool isIntegral (Matrix *A) {
-
- unsigned i, j;
- Value divisor, tmp;
-
- value_init(divisor); value_init(tmp);
- value_assign(divisor,A->p[A->NbRows-1][A->NbColumns-1]);
-
- for (i = 0; i < A->NbRows ; i++)
- for (j = 0; j < A->NbColumns ; j++) {
- value_modulus(tmp,A->p[i][j],divisor);
- if (value_notzero_p(tmp)) {
- value_clear(divisor); value_clear(tmp);
- return False;
- }
- }
- value_clear(divisor); value_clear(tmp);
- return True ;
-} /* isIntegral */
-
-/*
- * Check if the matrix 'A' is in Hermite normal form or not.
- */
-Bool isinHnf(Matrix *A) {
-
- Matrix *temp ;
- unsigned i, j ;
- Value rem;
-
- value_init(rem);
- temp = Homogenise(A,True) ;
- for (i = 0; i < temp->NbRows; i++) {
- value_assign(rem,temp->p[i][i]);
- for (j = 0; j < i ; j++)
- if (value_ge(temp->p[i][j],rem)) {
- Matrix_Free(temp);
- value_clear(rem);
- return False ;
- }
- for (j = i+1; j < temp->NbColumns ; j++)
- if (value_notzero_p(temp->p[i][j])) {
- Matrix_Free(temp);
- value_clear(rem);
- return False ;
- }
- }
- Matrix_Free(temp);
- value_clear(rem);
- return True ;
-} /* isinHnf */
-
-/*
- * Remove the row 'Rownumber' and place it at the end of the matrix 'X'
- */
-void PutRowLast (Matrix *X, int Rownumber) {
-
- int i, j ;
- Value temp;
-
- if (Rownumber == X->NbRows-1)
- return;
-
- value_init(temp);
- for (j = 0; j < X->NbColumns; j++) {
- value_assign(temp,X->p[Rownumber][j]);
- for (i = Rownumber; i < X->NbRows-1; i++)
- value_assign(X->p[i][j],X->p[i+1][j]);
- value_assign(X->p[i][j],temp);
- }
- value_clear(temp);
- return;
-} /* PutRowLast */
-
-/*
- * Remove the row 'Rownumber' and place it at the begining of the matrix 'X'
- */
-void PutRowFirst(Matrix *X, int Rownumber) {
-
- int i, j ;
- Value temp;
-
- value_init(temp);
- for (j = 0; j < X->NbColumns; j++) {
- value_assign(temp,X->p[Rownumber][j]);
- for (i = Rownumber; i > 0; i--)
- value_assign(X->p[i][j],X->p[i-1][j]);
- value_assign(X->p[i][j],temp);
- }
- value_clear(temp);
- return;
-} /* PutRowFirst */
-
-/*
- * Remove the column 'Columnnumber' and place it at the begining of the matrix
- * 'X'
- */
-void PutColumnFirst (Matrix *X, int Columnnumber) {
-
- int i, j ;
- Value temp;
-
- value_init(temp);
- for (i = 0; i < X->NbRows; i ++) {
- value_assign(temp,X->p[i][Columnnumber]);
- for (j = Columnnumber; j > 0; j --)
- value_assign(X->p[i][j],X->p[i][j-1]);
- value_assign(X->p[i][0],temp);
- }
- value_clear(temp);
- return ;
-} /* PutColumnFirst */
-
-/*
- * Remove the column 'Columnnumber' and place it at the end of the matrix 'X'
- */
-void PutColumnLast (Matrix *X, int Columnnumber) {
-
- int i, j ;
- Value temp;
-
- value_init(temp);
- for (i = 0; i < X->NbRows; i++) {
- value_assign(temp,X->p[i][Columnnumber]);
- for (j = Columnnumber; j < X->NbColumns-1; j++)
- value_assign(X->p[i][j],X->p[i][j+1]);
- value_assign(X->p[i][X->NbColumns-1],temp);
- }
- value_clear(temp);
- return ;
-} /* PutColumnLast */
-
-/*
- * Add a row of zeros at the end of the matrix 'M' and return the new matrix
- */
-Matrix *AddANullRow (Matrix *M) {
-
- int i,j;
- Matrix *Result;
-
- Result = Matrix_Alloc(M->NbRows+1,M->NbColumns);
- for (i = 0;i < M->NbRows; i++)
- for (j = 0; j < M->NbColumns ; j++)
- value_assign(Result->p[i][j],M->p[i][j]);
- for (j = 0; j < M->NbColumns; j++)
- value_set_si(Result->p[i][j],0);
- return Result;
-} /* AddANullRow */
-
-/*
- * Add a column of zeros at the end of the matrix 'M' and return the new
- * matrix
- */
-Matrix *AddANullColumn(Matrix *M) {
-
- int i,j;
- Matrix *Result;
-
- Result = Matrix_Alloc(M->NbRows, M->NbColumns+1);
- for (i = 0;i < M->NbRows; i++)
- for (j = 0; j < M->NbColumns ; j++)
- value_assign(Result->p[i][j],M->p[i][j]);
- for (i = 0; i < M->NbRows; i++)
- value_set_si(Result->p[i][M->NbColumns],0);
- return Result;
-} /* AddANullColumn */
-
-/*
- * Remove a row 'Rownumber' from matrix 'M' and return the new matrix.
- */
-Matrix *RemoveRow(Matrix *M, int Rownumber) {
-
- Matrix *Result;
- int i;
-
- Result = Matrix_Alloc(M->NbRows-1, M->NbColumns);
-
- for (i = 0; i < Rownumber; i++)
- Vector_Copy(M->p[i], Result->p[i], M->NbColumns);
- for ( ; i < Result->NbRows; i++)
- Vector_Copy(M->p[i+1], Result->p[i], M->NbColumns);
-
- return Result;
-} /* RemoveRow */
-
-/*
- * Remove NumColumns columns starting at column number 'FirstColumnnumber' from matrix 'M'
- * and return the new matrix.
- */
-Matrix *RemoveNColumns (Matrix *M, int FirstColumnnumber, int NumColumns) {
-
- Matrix *Result;
- int i;
-
- Result = Matrix_Alloc (M->NbRows, M->NbColumns-NumColumns);
-
- for (i = 0; i < Result->NbRows; i++) {
- Vector_Copy(M->p[i], Result->p[i], FirstColumnnumber);
- Vector_Copy(M->p[i]+FirstColumnnumber+NumColumns, Result->p[i]+FirstColumnnumber,
- M->NbColumns-NumColumns-FirstColumnnumber);
- }
- return Result;
-} /* RemoveColumn */
-
-/*
- * Remove a column 'Columnnumber' from matrix 'M' and return the new matrix.
- */
-Matrix *RemoveColumn (Matrix *M, int Columnnumber) {
-
- Matrix *Result;
- int i;
-
- Result = Matrix_Alloc (M->NbRows, M->NbColumns-1);
-
- for (i = 0; i < Result->NbRows; i++) {
- Vector_Copy(M->p[i], Result->p[i], Columnnumber);
- Vector_Copy(M->p[i]+Columnnumber+1, Result->p[i]+Columnnumber,
- M->NbColumns-1-Columnnumber);
- }
- return Result;
-} /* RemoveColumn */
-
-/*
- * Given a Matrix M of dimesnion n * l and rank l1, find a unimodular matrix
- * 'Result' such that the Vector Space spanned by M is the subset of the vector
- * Space spanned by the first l1 Rows of Result. The function returns the rank
- * l1 and the Matrix Result.
- */
-int findHermiteBasis(Matrix *M, Matrix **Result) {
-
- int i, j;
- Matrix *C, *curMat, *temp1, *temp2;
- Matrix *H, *U;
- Vector *V;
- int dim, curDim, curVect,rank;
-
- if (M->NbRows == 0) {
- Result[0] = Identity (M->NbColumns);
- return 0;
- }
-
- if (M->NbRows <= M->NbColumns) {
- Hermite(M, &H, &U);
-
- for (i = 0; i < H->NbRows; i++)
- if (value_zero_p(H->p[i][i]))
- break;
-
- if (i == H->NbRows) {
- Result[0] = Transpose(U);
- Matrix_Free(H);
- Matrix_Free(U);
- return(i);
- }
- Matrix_Free (H);
- Matrix_Free (U);
- }
-
- /* Eliminating the Zero Rows */
-
- C = Matrix_Copy (M);
- for (i = 0; i < C->NbRows; i++) {
- for (j = 0; j < C->NbColumns; j++)
- if (value_notzero_p(C->p[i][j]))
- break;
- if (j == C->NbColumns) {
- Matrix *temp;
- temp = RemoveRow(C, i);
- Matrix_Free(C);
- C = Matrix_Copy(temp);
- Matrix_Free(temp);
- i --;
- }
- }
-
- /* Eliminating the Redundant Rows */
-
- curDim = 1;
- curVect = 1;
- dim = C->NbColumns;
-
- curMat = Matrix_Alloc(1,C->NbColumns);
- for (i = 0; i < C->NbColumns; i ++)
- value_assign(curMat->p[0][i],C->p[0][i]);
-
- while((curVect < C->NbRows) && (curDim < dim)) {
- Matrix *temp;
- temp = AddANullRow(curMat);
- for (i = 0; i < C->NbColumns; i++)
- value_assign(temp->p[temp->NbRows-1][i],C->p[curVect][i]);
-
- temp1 = AddANullRow(temp);
- temp2 = AddANullColumn(temp1);
- rank = SolveDiophantine(temp2, &U, &V);
- if (rank == temp->NbRows) {
- Matrix_Free(curMat);
- curMat = Matrix_Copy(temp);
- curDim ++;
- }
- curVect ++;
- Matrix_Free (U);
- Vector_Free (V);
- Matrix_Free (temp1);
- Matrix_Free (temp);
- Matrix_Free (temp2);
- }
- Matrix_Free(C);
-
- Hermite(curMat, &H, &U);
- rank = curMat->NbRows;
- Matrix_Free(curMat);
-
- Result[0] = Transpose (U);
- Matrix_Free (H);
- Matrix_Free (U);
- return (rank);
-} /* findHermiteBasis */
-
-
-
-
diff --git a/source/polylib_mod/NormalForms.c b/source/polylib_mod/NormalForms.c
deleted file mode 100644
index 0d96208..0000000
--- a/source/polylib_mod/NormalForms.c
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <polylib/polylib.h>
-
-/* nota bene: on stocke les matrices par lignes */
-/* nota bene: matrices are stored in row major order */
-
-/*------------------------------------------------------------------------
- change les signes de la ligne i de la matrice A
- change the sign of row i of matrix A
-------------------------------------------------------------------------*/
-
-static void moins_l(Value *a,int i,int n,int p) {
-
- int k;
- Value *c;
-
- c=a+(i-1)*p;
-
- for(k=1; k<=p; k++) {
- value_oppose(*c,*c);
- c++;
- }
- return;
-} /* moins_l */
-
-/*------------------------------------------------------------------------
- change les signes de la colonne i de la matrice A
- change the sign of column i of matrix A
-------------------------------------------------------------------------*/
-
-static void moins_c(Value *a,int i,int n,int p) {
-
- int k;
- Value *c;
-
- c=a+(i-1);
-
- for(k=1;k<=n;k++) {
- value_oppose(*c,*c);
- c=c+p;
- }
- return;
-} /* moins_c */
-
-/*------------------------------------------------------------------------
- echange les lignes i et j de la matrice A
- exchange row i and j of matrix A
-------------------------------------------------------------------------*/
-
-static void echange_l(Value *a,int i,int j,int n,int p) {
-
- int k;
- Value s;
- Value *c1,*c2;
-
- value_init(s);
- c1=a+(i-1)*p;
- c2=a+(j-1)*p;
-
- for(k=1;k<=p;k++) {
- value_assign(s,*c1);
- value_assign(*c1,*c2);
- value_assign(*c2,s);
- c1++;
- c2++;
- }
- value_clear(s);
- return;
-} /* echange_l */
-
-/*------------------------------------------------------------------------
- echange les colonnes i et j de la matrice A
- exchange columns i and j of matrix A
-------------------------------------------------------------------------*/
-
-static void echange_c(Value *a,int i,int j,int n,int p) {
-
- int k;
- Value s;
- Value *c1,*c2;
-
- value_init(s);
- c1=a+(i-1);
- c2=a+(j-1);
-
- for(k=1;k<=n;k++) {
- value_assign(s,*c1);
- value_assign(*c1,*c2);
- value_assign(*c2,s);
- c1=c1+p;
- c2=c2+p;
- }
- value_clear(s);
- return;
-} /* echange_c */
-
-/*------------------------------------------------------------------------
- A est une matrice de taille n*p
- on ajoute a la ligne i, x fois la ligne j
- A is a matrix of size n*p
- we add x times the row j to the row i
-------------------------------------------------------------------------*/
-
-static void ligne(Value *a,int i,int j,Value x,int n,int p) {
-
- int k;
- Value *c1,*c2;
-
- c1=a+(i-1)*p;
- c2=a+(j-1)*p;
-
- for(k=1;k<=p;k++) {
-
- value_addmul(*c1, x, *c2);
- c1++;
- c2++;
- }
- return;
-} /* ligne */
-
-/*------------------------------------------------------------------------
- A est une matrice de taille n*p
- on ajoute a la colonne i, x fois la colonne j
- A is a matrix of size n*p
- we add x times the column j to the column i
-
-------------------------------------------------------------------------*/
-
-static void colonne(Value *a,int i,int j,Value x,int n,int p) {
-
- int k;
- Value *c1,*c2;
-
- c1=a+(i-1);
- c2=a+(j-1);
-
- for(k=1;k<=n;k++) {
- value_addmul(*c1, x, *c2);
- c1=c1+p;
- c2=c2+p;
- }
- return;
-} /* colonne */
-
-/*----------------------------------------------------------------------
- trouve le numero de colonne du plus petit element non nul de
- la ligne q, d'indice superieur a q, de la matrice A, mais
- renvoie zero si tous les elements sont nuls sauf le qieme.
-
- find the column number (greater than q) of the smallest non
- null element of row q . it returns
- 0 if all the last elements of row q are null except the qth
-
-----------------------------------------------------------------------*/
-
-static int petit_l(Value *a,int n,int p,int q) {
-
- int numero=0, k, tousnuls;
- Value minus, comp;
- Value *c;
-
- value_init(minus); value_init(comp);
- c=a+(q-1)*p+(p-1);
- tousnuls=1;
- for(k=p;k>q;k--) {
- value_absolute(comp,*c);
- if (value_notzero_p(comp)) {
- if (tousnuls==1) {
- value_assign(minus,comp);
- numero=k;
- tousnuls=0;
- }
- else if (value_ge(minus,comp)) {
- value_assign(minus,comp);
- numero=k;
- }
- }
- c--;
- }
- if (tousnuls==1) {
- value_clear(minus); value_clear(comp);
- return(0);
- }
- else {
- value_absolute(comp,*c);
- if ((value_notzero_p(comp))&&(value_ge(minus,comp))) {
- value_clear(minus); value_clear(comp);
- return(q);
- }
- else {
- value_clear(minus); value_clear(comp);
- return(numero);
- }
- }
-} /* petit_l */
-
-/*----------------------------------------------------------------------
- trouve le numero de ligne du plus petit element non nul de
- la colonne q, d'indice superieur a q, de la matrice A, mais
- renvoie zero si tous les elements sont nuls sauf le qieme.
-
- find the row number (greater than q) of the smallest non
- null element of column q . it returns
- 0 if all the last elements of column q are null except the qth
-
-----------------------------------------------------------------------*/
-
-static int petit_c(Value *a,int n,int p,int q) {
-
- int numero=0, k, tousnuls;
- Value minus, comp;
- Value *c;
-
- value_init(minus); value_init(comp);
- c = a+q-1+p*(n-1);
- tousnuls=1;
- for(k=n;k>q;k--) {
- value_absolute(comp,*c);
- if (value_notzero_p(comp)) {
- if (tousnuls==1) {
- value_assign(minus,comp);
- numero=k;
- tousnuls=0;
- }
- else if (value_ge(minus,comp)) {
- value_assign(minus,comp);
- numero=k;
- }
- }
- c=c-p;
- }
-
- if (tousnuls==1) {
- value_clear(minus); value_clear(comp);
- return(0);
- }
- else {
- value_absolute(comp,*c);
- if ((value_notzero_p(comp)) && (value_ge(minus,comp))) {
- value_clear(minus); value_clear(comp);
- return(q);
- }
- else {
- value_clear(minus); value_clear(comp);
- return(numero);
- }
- }
-} /* petit_c */
-
-/*-----------------------------------------------------------------------
- A est initialisee a une matrice "identite" de taille n*p
- A is initialized to an "identity" matrix of size n*p
------------------------------------------------------------------------*/
-
-static void identite(Value *a,int n,int p) {
-
- int i,j;
- Value *b;
-
- b = a;
- for(i=1;i<=n;i++) {
- for(j=1;j<=p;j++) {
- if (i==j)
- value_set_si(*b,1);
- else
- value_set_si(*b,0);
- b++;
- }
- }
- return;
-} /* identite */
-
-/*-----------------------------------------------------------------------
- transpose la sous-matrice de A dont les indices sont
- superieurs ou egaux a q
- transposition of the sub-matrix of A composed of the elements
- whose indices are greater or equal to q
------------------------------------------------------------------------*/
-
-static void transpose(Value *a,int n,int q) {
-
- int i;
- Value val;
- Value *b,*c;
-
- value_init(val);
- if (q<n) {
- b=a+(q-1)+(q-1)*n;
- c=b;
- for(i=q+1;i<=n;i++) {
- b++;
- c=c+n;
- value_assign(val,*b);
- value_assign(*b,*c);
- value_assign(*c,val);
- }
- transpose(a,n,q+1);
- }
- value_clear(val);
- return;
-} /* transpose */
-
-/*----------------------------------------------------------------------
- trouve le numero de colonne du premier element non divisible
- par val dans la sous-matrice d'indices > q mais renvoie 0 sinon
-
- find the column number of the first non-divisible by val element
- in the sub-matrix of a composed of the elements of indices >q.
- Return 0 is there is no such element
-----------------------------------------------------------------------*/
-
-static int encore(Value *a,int n,int p,int q,Value val) {
-
- int k,l;
- Value comp, tmp;
- Value *c;
-
- if ((q>=n)||(q>=p)) return(0);
-
- value_init(comp); value_init(tmp);
- c=a+q*p+q;
- k=q+1;
- l=q+1;
- while (k<=n) {
- value_absolute(comp,*c);
- if (value_zero_p(val)) {
- if (value_notzero_p(comp)) {
- value_clear(comp);
- value_clear(tmp);
- return(l);
- }
- }
- else {
- value_modulus(tmp,comp,val);
- if (value_notzero_p(tmp)) {
- value_clear(comp);
- value_clear(tmp);
- return(l);
- }
- }
- if (l==p) {
- k=k+1;
- l=q+1;
- c=c+q+1;
- }
- else {
- l++;
- c++;
- }
- }
- value_clear(comp);
- value_clear(tmp);
- return(0);
-} /* encore */
-
-/*----------------------------------------------------------------------
- transforme la matrice A (de taille n*p), a partir de la position
- q*q en sa forme de smith, les matrices b et c subissant les memes
- transformations respectivement sur les lignes et colonnes
-
- transform the matrix A (size n*p), from position (q,q) into
- its smith normal form. the same transformations are applied to
- matrices b and c, respectively on rows and on columns
-----------------------------------------------------------------------*/
-
-static void smith(Value *a,Value *b,Value *c,Value *b_inverse,Value *c_inverse,int n,int p,int q) {
-
- int i,k,fini;
- Value x, pivot, tmp, x_inv;
- Value *f;
-
- value_init(pivot); value_init(tmp);
- value_init(x); value_init(x_inv);
-
- if ((q<=n)&&(q<=p)) {
- fini = 1;
-
- while (fini!=0) {
- i=petit_c(a,n,p,q);
- while (i!=0) {
- if (i!=q) {
- echange_l(a,i,q,n,p);
- echange_l(b,i,q,n,n);
- echange_c(b_inverse,i,q,n,n);
- }
- f=a+(q-1)+(q-1)*p;
- value_assign(pivot,*f);
- if (value_neg_p(pivot)) {
- moins_l(a,q,n,p);
- moins_l(b,q,n,n);
- moins_c(b_inverse,q,n,n);
- value_oppose(pivot,pivot);
- }
- for(k=q+1;k<=n;k++) {
- f=f+p;
- if (value_notzero_p(*f)) {
- value_division(x,*f,pivot);
- value_modulus(tmp,*f,pivot);
- if (value_neg_p(tmp))
- value_decrement(x,x);
- value_oppose(x_inv,x);
- ligne(a,k,q,x_inv,n,p);
- ligne(b,k,q,x_inv,n,n);
- colonne(b_inverse,q,k,x,n,n);
- }
- }
- i=petit_c(a,n,p,q);
- }
- fini=0;
- i=petit_l(a,n,p,q);
- while (i!=0) {
- if (i!=q) {
- echange_c(a,i,q,n,p);
- echange_c(c,i,q,p,p);
- echange_l(c_inverse,i,q,p,p);
- fini=1;
- }
- f=a+(q-1)+(q-1)*p;
- value_assign(pivot,*f);
- if (value_neg_p(pivot)) {
- moins_c(a,q,n,p);
- moins_c(c,q,p,p);
- moins_l(c_inverse,q,p,p);
- value_oppose(pivot,pivot);
- }
- for(k=q+1;k<=p;k++) {
- f++;
- if (value_notzero_p(*f)) {
- value_division(x,*f,pivot);
- value_modulus(tmp,*f,pivot);
- if (value_neg_p(tmp))
- value_decrement(x,x);
- value_oppose(x_inv,x);
- colonne(a,k,q,x_inv,n,p);
- colonne(c,k,q,x_inv,p,p);
- ligne(c_inverse,q,k,x,p,p);
- }
- }
- i=petit_l(a,n,p,q);
- }
- }
- value_assign(pivot,*(a+(q-1)+(q-1)*p));
- if (value_neg_p(pivot)) {
- moins_l(a,q,n,p);
- moins_l(b,q,n,n);
- moins_c(b_inverse,q,n,n);
- value_oppose(pivot,pivot);
- }
-
- i=encore(a,n,p,q,pivot);
- if (i!=0) {
- value_set_si(x,1);
- value_set_si(x_inv,-1);
- colonne(a,q,i,x,n,p);
- colonne(c,q,i,x,p,p);
- ligne(c_inverse,i,q,x_inv,p,p);
- smith(a,b,c,b_inverse,c_inverse,n,p,q);
- }
- else smith(a,b,c,b_inverse,c_inverse,n,p,q+1);
- }
- value_clear(pivot); value_clear(tmp);
- value_clear(x); value_clear(x_inv);
-
- return;
-} /* smith */
-
-/*----------------------------------------------------------------------
- decompose la matrice A en le produit d'une matrice B
- unimodulaire et d'une matrice triangulaire superieure
- D est l'inverse de B
- Decompose the matrix A in the product of a matrix B unimodular
- and a matrix upper triangular, D is the inverse of B
-----------------------------------------------------------------------*/
-
-static void hermite(Value *a,Value *b,Value *d,int n,int p,int q) {
-
- int i,k;
- Value x, pivot, x_inv, tmp;
- Value *c1;
-
- value_init(pivot); value_init(tmp);
- value_init(x); value_init(x_inv);
-
- if ((q<=p)&&(q<=n)) {
- i=petit_c(a,n,p,q);
- while (i!=0) {
- if (i!=q) {
- echange_l(a,i,q,n,p);
- echange_c(b,i,q,n,n);
- echange_l(d,i,q,n,n);
- }
-
- c1=a+(q-1)+(q-1)*p;
- value_assign(pivot,*c1);
- if (value_neg_p(pivot)) {
- moins_l(a,q,n,p);
- moins_l(d,q,n,n);
- moins_c(b,q,n,n);
- value_oppose(pivot,pivot);
- }
- for(k=q+1;k<=n;k++) {
- c1=c1+p;
- if (value_notzero_p(*c1)) {
- value_division(x,*c1,pivot);
- value_modulus(tmp,*c1,pivot);
- if (value_neg_p(tmp))
- value_decrement(x,x);
- value_oppose(x_inv,x);
- ligne(a,k,q,x_inv,n,p);
- colonne(b,q,k,x,n,n);
- ligne(d,k,q,x_inv,n,n);
- }
- }
- i=petit_c(a,n,p,q);
- }
- c1=a+(q-1);
- value_assign(pivot,*(c1+(q-1)*p));
- if (value_neg_p(pivot)) {
- moins_l(a,q,n,p);
- moins_l(d,q,n,n);
- moins_c(b,q,n,n);
- value_oppose(pivot,pivot);
- }
- if (value_notzero_p(pivot)) {
- for(k=1;k<q;k++) {
- if (value_notzero_p(*c1)) {
- value_division(x,*c1,pivot);
- value_modulus(tmp,*c1,pivot);
- if (value_neg_p(tmp))
- value_decrement(x,x);
- value_oppose(x_inv,x);
- ligne(a,k,q,x_inv,n,p);
- colonne(b,q,k,x,n,n);
- ligne(d,k,q,x_inv,n,n);
- }
- c1=c1+p;
- }
- }
- hermite(a,b,d,n,p,q+1);
- }
- value_clear(pivot); value_clear(tmp);
- value_clear(x); value_clear(x_inv);
- return;
-} /* hermite */
-
-/*----------------------------------------------------------------------
- B est une g_base de dimension n dont les p premiers vecteurs
- colonnes sont colineaires aux vecteurs colonnes de A
- C est l'invers de B
-
- B is an integral (g_base ?) of dimension n whose p first columns
- vectors are proportionnal to the column vectors of A. C is the
- inverse of B.
- ----------------------------------------------------------------------*/
-
-/** Convert PolmattoDarmat :
-*** This function converts the matrix of a Polylib to a int * as necessary
-*** for the functions in Darte's implementation.
-***
-*** Input : A Polylib Matrix ( a pointer to it );
-*** Output : An int * with the matrix copied into it
-**/
-static Value *ConvertPolMattoDarMat(Matrix *A ) {
-
- int i,j;
- Value *result;
-
- result = (Value *)malloc(sizeof(Value) * A->NbRows * A->NbColumns);
- for(i=0;i<A->NbRows * A->NbColumns;i++)
- value_init(result[i]);
-
- for (i = 0; i < A->NbRows; i++)
- for (j = 0 ; j < A->NbColumns; j++)
- value_assign(result[i*A->NbColumns + j],A->p[i][j]);
- return result;
-} /* ConvertPolMattoDarMat */
-
-/** Convert DarmattoPolmat
-*** This function converts the matrix from Darte representation to a matrix
-*** in PolyLib.
-***
-*** Input : The matrix (a pointer to it), number of Rows, number of columns
-*** Output : The matrix of the PolyLib
-***
-**/
-
-static Matrix *ConvertDarMattoPolMat (Value *A, int NbRows, int NbCols) {
-
- int i,j;
- Matrix *result;
-
- result = Matrix_Alloc(NbRows, NbCols);
-
- for (i = 0; i < NbRows; i ++)
- for (j = 0; j < NbCols; j ++)
- value_assign(result->p[i][j],A[i*NbCols + j]);
- return result;
-} /* ConvertDarMattoPolMat */
-
-/**
-*** Smith : This function takes a Matrix A of dim n * l as its input
-*** and returns the three matrices U, V and Product such that
-*** A = U * Product * V, where U is an unimodular matrix of dimension
-*** n * n and V is an unimodular matrix of dimension l * l.
-*** Product is a diagonal matrix of dimension n * l.
-***
-*** We use Alan Darte's implementation of Smith for computing
-*** the Smith Normal Form
-**/
-void Smith(Matrix *A, Matrix **U, Matrix **V, Matrix **Product)
-{
- int i;
- Matrix *u, *v;
-
- u = Identity(A->NbRows);
- v = Identity(A->NbColumns);
-
- *U = Identity(A->NbRows);
- *V = Identity(A->NbColumns);
-
- *Product = Matrix_Copy(A);
- smith((*Product)->p_Init, u->p_Init, v->p_Init, (*U)->p_Init, (*V)->p_Init,
- A->NbRows, A->NbColumns, 1);
-
- Matrix_Free(u);
- Matrix_Free(v);
-} /* Smith */
-
-/** Hermite :
-*** This function takes a Matrix as its input and finds its HNF
-*** ( Left form )
-***
-*** Input : A Matrix A (The Matrix A is not necessarily a Polylib matrix.
-*** It is just a matrix as far as Hermite is concerned. It
-*** does not even check if the matrix is a Polylib matrix or not)
-*** Output : The Hnf matrix H and the Unimodular matrix U such that
-*** A = H * U.
-***
-*** We use Alan Darte's implementation of Hermite to compute the HNF.
-*** Alan Darte's implementation computes the Upper Triangular HNF.
-*** So We work on the fact that if A = H * U then
-*** A (transpose) = U(transpose) * H (transpose)
-*** There are a set of interface functions written in Interface.c
-*** which convert a matrix from Polylib representationt to that of
-*** Alan Darte's and vice versa.
-***
-*** This Function Does the Following
-*** Step 1 : Given the matrix A it finds its Transpose.
-*** Step 2 : Finds the HNF (Right Form) using Alan Darte's Algorithm.
-*** Step 3 : The H1 and U1 obtained in Step2 are both Transposed to get
-*** the actual H and U such that A = HU.
-**/
-void Hermite (Matrix *A, Matrix **H, Matrix **U) {
-
- int i;
- Matrix *transpose, *tempH, *tempU ;
- Value *darte_matA, *darte_identite, *darte_id_inv;
-
- transpose = Transpose(A);
- darte_matA = ConvertPolMattoDarMat(transpose);
-
- darte_identite = (Value *)malloc(sizeof(Value) * A->NbColumns* A->NbColumns);
- darte_id_inv = (Value *) malloc(sizeof(Value) * A->NbColumns*A->NbColumns);
- for (i=0; i< A->NbColumns * A->NbColumns; i++)
- value_init(darte_identite[i]);
- for (i=0; i< A->NbColumns * A->NbColumns; i++)
- value_init(darte_id_inv[i]);
-
- identite(darte_identite, transpose->NbRows, transpose->NbRows);
- identite(darte_id_inv, transpose->NbRows, transpose->NbRows);
- hermite(darte_matA, darte_identite, darte_id_inv,A->NbColumns,A->NbRows, 1);
- Matrix_Free (transpose);
- transpose = ConvertDarMattoPolMat(darte_matA, A->NbColumns, A->NbRows);
- tempU = ConvertDarMattoPolMat(darte_identite, A->NbColumns, A->NbColumns);
-
- /* Finding H Transpose */
- tempH = Transpose(transpose);
- Matrix_Free(transpose);
-
- /* Finding U Transpose */
- transpose = Transpose(tempU);
-
- H[0] = Matrix_Copy(tempH);
- U[0] = Matrix_Copy(transpose);
-
- Matrix_Free (tempH);
- Matrix_Free (transpose);
- Matrix_Free (tempU);
-
- for (i=0; i< A->NbRows * A->NbColumns; i++)
- value_clear(darte_matA[i]);
- for (i=0; i< A->NbColumns * A->NbColumns; i++)
- value_clear(darte_identite[i]);
- for (i=0; i< A->NbColumns * A->NbColumns; i++)
- value_clear(darte_id_inv[i]);
- free (darte_matA);
- free (darte_identite);
- free (darte_id_inv);
- return;
-} /* Hermite */
-
-
diff --git a/source/polylib_mod/SolveDio.c b/source/polylib_mod/SolveDio.c
deleted file mode 100644
index e1553bb..0000000
--- a/source/polylib_mod/SolveDio.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <polylib/polylib.h>
-
-static void RearrangeMatforSolveDio(Matrix *M);
-
-/*
- * Solve Diophantine Equations :
- * This function takes as input a system of equations in the form
- * Ax + C = 0 and finds the solution for it, if it exists
- *
- * Input : The matrix form the system of the equations Ax + C = 0
- * ( a pointer to a Matrix. )
- * A pointer to the pointer, where the matrix U
- * corresponding to the free variables of the equation
- * is stored.
- * A pointer to the pointer of a vector is a solution to T.
- *
- *
- * Output : The above matrix U and the vector T.
- *
- * Algorithm :
- * Given an integral matrix A, we can split it such that
- * A = HU, where H is in HNF (lowr triangular)
- * and U is unimodular.
- * So Ax = c -> HUx = c -> Ht = c ( where Ux = t).
- * Solving for Ht = c is easy.
- * Using 't' we find x = U(inverse) * t.
- *
- * Steps :
- * 1) For the above algorithm to work correctly to
- * need the condition that the first 'rank' rows are
- * the rows which contribute to the rank of the matrix.
- * So first we copy Input into a matrix 'A' and
- * rearrange the rows of A (if required) such that
- * the first rank rows contribute to the rank.
- * 2) Extract A and C from the matrix 'A'. A = n * l matrix.
- * 3) Find the Hermite normal form of the matrix A.
- * ( the matrices the lower tri. H and the unimod U).
- * 4) Using H, find the values of T one by one.
- * Here we use a sort of Gaussian elimination to find
- * the solution. You have a lower triangular matrix
- * and a vector,
- * [ [a11, 0], [a21, a22, 0] ...,[arank1...a rankrank 0]]
- * and the solution vector [t1.. tn] and the vector
- * [ c1, c2 .. cl], now as we are traversing down the
- * rows one by one, we will have all the information
- * needed to calculate the next 't'.
- *
- * That is to say, when you want to calculate t2,
- * you would have already calculated the value of t1
- * and similarly if you are calculating t3, you will
- * need t1 and t2 which will be available by that time.
- * So, we apply a sort of Gaussian Elimination inorder
- * to find the vector T.
- *
- * 5) After finding t_rank, the remaining (l-rank) t's are
- * made equal to zero, and we verify, if these values
- * agree with the remaining (n-rank) rows of A.
- *
- * 6) If a solution exists, find the values of X using
- * U (inverse) * T.
- */
-
-int SolveDiophantine(Matrix *M, Matrix **U, Vector **X) {
-
- int i, j, k1, k2, min, rank;
- Matrix *A, *temp, *hermi, *unimod, *unimodinv ;
- Value *C; /* temp storage for the vector C */
- Value *T; /* storage for the vector t */
- Value sum, tmp;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered SOLVEDIOPHANTINE\n");
- fclose(fp);
-#endif
-
- value_init(sum); value_init(tmp);
-
- /* Ensuring that the first rank row of A contribute to the rank*/
- A = Matrix_Copy(M);
- RearrangeMatforSolveDio(A);
- temp = Matrix_Alloc(A->NbRows-1, A->NbColumns-1);
-
- /* Copying A into temp, ignoring the Homogeneous part */
- for (i = 0; i < A->NbRows -1; i++)
- for (j = 0; j < A->NbColumns-1; j++)
- value_assign(temp->p[i][j],A->p[i][j]);
-
- /* Copying C into a temp, ignoring the Homogeneous part */
- C = (Value *) malloc (sizeof(Value) * (A->NbRows-1));
- k1 = A->NbRows-1;
-
- for (i = 0; i < k1; i++) {
- value_init(C[i]);
- value_oppose(C[i],A->p[i][A->NbColumns-1]);
- }
- Matrix_Free (A);
-
- /* Finding the HNF of temp */
- Hermite(temp, &hermi, &unimod);
-
- /* Testing for existence of a Solution */
-
- min=(hermi->NbRows <= hermi->NbColumns ) ? hermi->NbRows : hermi->NbColumns ;
- rank = 0;
- for (i = 0; i < min ; i++) {
- if (value_notzero_p(hermi->p[i][i]))
- rank ++;
- else
- break ;
- }
-
- /* Solving the Equation using Gaussian Elimination*/
-
- T = (Value *) malloc(sizeof(Value) * temp->NbColumns);
- k2 = temp->NbColumns;
- for(i=0;i< k2; i++)
- value_init(T[i]);
-
- for (i = 0; i < rank ; i++) {
- value_set_si(sum,0);
- for (j = 0; j < i; j++) {
- value_addmul(sum, T[j], hermi->p[i][j]);
- }
- value_subtract(tmp,C[i],sum);
- value_modulus(tmp,tmp,hermi->p[i][i]);
- if (value_notzero_p(tmp)) { /* no solution to the equation */
- *U = Matrix_Alloc(0,0);
- *X = Vector_Alloc (0);
- value_clear(sum); value_clear(tmp);
- for (i = 0; i < k1; i++)
- value_clear(C[i]);
- for (i = 0; i < k2; i++)
- value_clear(T[i]);
- free(C);
- free(T);
- return (-1);
- };
- value_subtract(tmp,C[i],sum);
- value_division(T[i],tmp,hermi->p[i][i]);
- }
-
- /** Case when rank < Number of Columns; **/
-
- for (i = rank; i < hermi->NbColumns; i++)
- value_set_si(T[i],0);
-
- /** Solved the equtions **/
- /** When rank < hermi->NbRows; Verifying whether the solution agrees
- with the remaining n-rank rows as well. **/
-
- for (i = rank; i < hermi->NbRows; i++) {
- value_set_si(sum,0);
- for (j = 0; j < hermi->NbColumns; j++) {
- value_addmul(sum, T[j], hermi->p[i][j]);
- }
- if (value_ne(sum,C[i])) {
- *U = Matrix_Alloc(0,0);
- *X = Vector_Alloc (0);
- value_clear(sum); value_clear(tmp);
- for (i = 0; i < k1; i++)
- value_clear(C[i]);
- for (i = 0; i < k2; i++)
- value_clear(T[i]);
- free(C);
- free(T);
- return (-1);
- }
- }
- unimodinv = Matrix_Alloc(unimod->NbRows, unimod->NbColumns);
- Matrix_Inverse(unimod, unimodinv);
- Matrix_Free(unimod);
- *X = Vector_Alloc(M->NbColumns-1);
-
- if (rank == hermi->NbColumns)
- *U = Matrix_Alloc(0,0);
- else { /* Extracting the General solution form U(inverse) */
-
- *U = Matrix_Alloc(hermi->NbColumns, hermi->NbColumns-rank);
- for (i = 0; i < U[0]->NbRows; i++)
- for (j = 0; j < U[0]->NbColumns; j++)
- value_assign(U[0]->p[i][j],unimodinv->p[i][j+rank]);
- }
-
- for (i = 0; i < unimodinv->NbRows; i++) {
-
- /* Calculating the vector X = Uinv * T */
- value_set_si(sum,0);
- for (j = 0; j < unimodinv->NbColumns; j++) {
- value_addmul(sum, unimodinv->p[i][j], T[j]);
- }
- value_assign(X[0]->p[i],sum);
- }
-
- /*
- for (i = rank; i < A->NbColumns; i ++)
- X[0]->p[i] = 0;
- */
- Matrix_Free (unimodinv);
- Matrix_Free (hermi);
- Matrix_Free (temp);
- value_clear(sum); value_clear(tmp);
- for (i = 0; i < k1; i++)
- value_clear(C[i]);
- for (i = 0; i < k2; i++)
- value_clear(T[i]);
- free(C);
- free(T);
- return (rank);
-} /* SolveDiophantine */
-
-/*
- * Rearrange :
- * This function takes as input a matrix M (pointer to it)
- * and it returns the tranformed matrix M, such that the first
- * 'rank' rows of the new matrix M are the ones which contribute
- * to the rank of the matrix M.
- *
- * 1) For a start we try to put all the zero rows at the end.
- * 2) Then cur = 1st row of the remaining matrix.
- * 3) nextrow = 2ndrow of M.
- * 4) temp = cur + nextrow
- * 5) If (rank(temp) == temp->NbRows.) {cur = temp;nextrow ++}
- * 6) Else (Exchange the nextrow of M with the currentlastrow.
- * and currentlastrow --).
- * 7) Repeat steps 4,5,6 till it is no longer possible.
- *
- */
-static void RearrangeMatforSolveDio(Matrix *M) {
-
- int i, j, curend, curRow, min, rank=1;
- Bool add = True;
- Matrix *A, *L, *H, *U;
-
- /* Though I could have used the Lattice function
- Extract Linear Part, I chose not to use it so that
- this function can be independent of Lattice Operations */
-
- L = Matrix_Alloc(M->NbRows-1,M->NbColumns-1);
- for (i = 0; i < L->NbRows; i++)
- for (j = 0; j < L->NbColumns; j++)
- value_assign(L->p[i][j],M->p[i][j]);
-
- /* Putting the zero rows at the end */
- curend = L->NbRows-1;
- for (i = 0; i < curend; i++) {
- for (j = 0; j < L->NbColumns; j++)
- if (value_notzero_p(L->p[i][j]))
- break;
- if (j == L->NbColumns) {
- ExchangeRows(M,i,curend);
- curend --;
- }
- }
-
- /* Trying to put the redundant rows at the end */
-
- if (curend > 0) { /* there are some useful rows */
-
- Matrix *temp;
- A = Matrix_Alloc(1, L->NbColumns);
-
- for (i = 0; i <L->NbColumns; i++)
- value_assign(A->p[0][i],L->p[0][i]);
- curRow = 1;
- while (add == True ) {
- temp= AddANullRow(A);
- for (i = 0;i <A->NbColumns; i++)
- value_assign(temp->p[curRow][i],L->p[curRow][i]);
- Hermite(temp, &H, &U);
- for (i = 0; i < H->NbRows; i++)
- if (value_zero_p(H->p[i][i]))
- break;
- if (i != H->NbRows) {
- ExchangeRows(M, curRow, curend);
- curend --;
- }
- else {
- curRow ++;
- rank ++;
- Matrix_Free (A);
- A = Matrix_Copy (temp);
- Matrix_Free (temp);
- }
- Matrix_Free (H);
- Matrix_Free (U);
- min = (curend >= L->NbColumns) ? L->NbColumns : curend ;
- if (rank==min || curRow >= curend)
- break;
- }
- Matrix_Free (A);
- }
- Matrix_Free (L);
- return;
-} /* RearrangeMatforSolveDio */
diff --git a/source/polylib_mod/Zpolyhedron.c b/source/polylib_mod/Zpolyhedron.c
deleted file mode 100644
index 531d58e..0000000
--- a/source/polylib_mod/Zpolyhedron.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <polylib/polylib.h>
-#include <stdlib.h>
-
-static ZPolyhedron * ZPolyhedronIntersection(ZPolyhedron *, ZPolyhedron *);
-static ZPolyhedron *ZPolyhedron_Copy(ZPolyhedron *A);
-static void ZPolyhedron_Free(ZPolyhedron *Zpol);
-static ZPolyhedron * ZPolyhedronDifference(ZPolyhedron *, ZPolyhedron *);
-static ZPolyhedron * ZPolyhedronImage(ZPolyhedron *, Matrix *);
-static ZPolyhedron * ZPolyhedronPreimage(ZPolyhedron *, Matrix *);
-static ZPolyhedron *AddZPolytoZDomain(ZPolyhedron *A, ZPolyhedron *Head);
-static void ZPolyhedronPrint(FILE *fp, const char *format, ZPolyhedron *A);
-
-typedef struct forsimplify {
- Polyhedron *Pol;
- LatticeUnion *LatUni;
- struct forsimplify *next;
-} ForSimplify;
-
-
-/*
- * Returns True if 'Zpol' is empty, otherwise returns False
- */
-Bool isEmptyZPolyhedron (ZPolyhedron *Zpol) {
-
- if(Zpol == NULL)
- return True;
- if((isEmptyLattice (Zpol->Lat)) || (emptyQ(Zpol->P)))
- return True;
- return False;
-} /* isEmptyZPolyhedron */
-
-/*
- * Given Lattice 'Lat' and a Polyhderon 'Poly', allocate space, and return
- * the Z-polyhderon corresponding to the image of the polyhderon 'Poly' by the
- * lattice 'Lat'. If the input lattice 'Lat' is not integeral, it integralises
- * it, i.e. the lattice of the Z-polyhderon returned is integeral.
- */
-ZPolyhedron *ZPolyhedron_Alloc(Lattice *Lat, Polyhedron *Poly) {
-
- ZPolyhedron *A;
-
- POL_ENSURE_FACETS(Poly);
- POL_ENSURE_VERTICES(Poly);
-
- if(Lat->NbRows != Poly->Dimension+1) {
- fprintf(stderr,"\nInZPolyAlloc - The Lattice and the Polyhedron");
- fprintf(stderr," are not compatible to form a ZPolyhedra\n");
- return NULL;
- }
- if((!(isEmptyLattice(Lat))) && (!isfulldim (Lat))) {
- fprintf(stderr,"\nZPolAlloc: Lattice not Full Dimensional\n");
- return NULL;
- }
- A = (ZPolyhedron *)malloc(sizeof(ZPolyhedron));
- if (!A) {
- fprintf(stderr,"ZPolAlloc : Out of Memory\n");
- return NULL;
- }
- A->next = NULL;
- A->P = Domain_Copy(Poly);
- A->Lat = Matrix_Copy(Lat);
-
- if(IsLattice(Lat) == False) {
- ZPolyhedron *Res;
-
- Res = IntegraliseLattice (A);
- ZPolyhedron_Free (A);
- return Res;
- }
- return A;
-} /* ZPolyhedron_Alloc */
-
-/*
- * Free the memory used by the Z-domain 'Head'
- */
-void ZDomain_Free (ZPolyhedron *Head) {
-
- if (Head == NULL)
- return;
- if (Head->next != NULL)
- ZDomain_Free(Head->next);
- ZPolyhedron_Free(Head);
-} /* ZDomain_Free */
-
-/*
- * Free the memory used by the Z-polyhderon 'Zpol'
- */
-static void ZPolyhedron_Free (ZPolyhedron *Zpol) {
-
- if (Zpol == NULL)
- return;
- Matrix_Free((Matrix *) Zpol->Lat);
- Domain_Free(Zpol->P);
- free(Zpol);
- return;
-} /* ZPolyhderon_Free */
-
-/*
- * Return a copy of the Z-domain 'Head'
- */
-ZPolyhedron *ZDomain_Copy(ZPolyhedron *Head) {
-
- ZPolyhedron *Zpol;
- Zpol = ZPolyhedron_Copy(Head);
-
- if (Head->next != NULL)
- Zpol->next = ZDomain_Copy(Head->next);
- return Zpol;
-} /* ZDomain_Copy */
-
-/*
- * Return a copy of the Z-polyhderon 'A'
- */
-static ZPolyhedron *ZPolyhedron_Copy(ZPolyhedron *A) {
-
- ZPolyhedron *Zpol;
-
- Zpol = ZPolyhedron_Alloc(A->Lat, A->P);
- return Zpol;
-} /* ZPolyhderon_Copy */
-
-/*
- * Add the ZPolyhedron 'Zpol' to the Z-domain 'Result' and return a pointer
- * to the new Z-domain.
- */
-static ZPolyhedron *AddZPoly2ZDomain(ZPolyhedron *Zpol, ZPolyhedron *Result) {
-
- ZPolyhedron *A;
-
- if (isEmptyZPolyhedron(Zpol))
- return Result;
- A = ZPolyhedron_Copy(Zpol);
- A->next = NULL;
-
- if (isEmptyZPolyhedron (Result)) {
- ZDomain_Free (Result);
- return A;
- }
- A->next = Result;
- return A;
-} /* AddZPoly2ZDomain */
-
-/*
- * Given a Z-polyhderon 'A' and a Z-domain 'Head', return a new Z-domain with
- * 'A' added to it. If the new Z-polyhedron 'A', is already included in the
- * Z-domain 'Head', it is not added in the list. Othewise, the function checks
- * if the new Z-polyhedron 'A' to be added to the Z-domain 'Head' has a common
- * lattice with some other Z-polyhderon already present in the Z-domain. If it
- * is so, it takes the union of the underlying polyhdera; domains and returns.
- * The function tries to make sure that the added Z-polyhedron 'A' is in the
- * canonical form.
- */
-static ZPolyhedron *AddZPolytoZDomain(ZPolyhedron *A, ZPolyhedron *Head) {
-
- ZPolyhedron *Zpol, *temp, *temp1;
- Polyhedron *i;
- Bool Added;
-
- if ((A == NULL) || (isEmptyZPolyhedron(A)))
- return Head;
-
- /* For each "underlying" Pol, find the Cnf and add Zpol in Cnf*/
- for(i=A->P; i!= NULL; i=i->next) {
- ZPolyhedron *Z, *Z1;
- Polyhedron *Image;
- Matrix *H, *U;
- Lattice *Lat ;
-
- Added = False;
- Image = Domain_Copy(i);
- Domain_Free(Image->next);
- Image->next = NULL;
- Z1 = ZPolyhedron_Alloc(A->Lat,Image);
- Domain_Free(Image);
- CanonicalForm(Z1,&Z,&H);
- ZDomain_Free(Z1);
- Lat = (Lattice *)Matrix_Alloc(H->NbRows,Z->Lat->NbColumns);
- Matrix_Product(H,Z->Lat,(Matrix *)Lat);
- Matrix_Free(H);
- AffineHermite(Lat,(Lattice **)&H,&U);
- Image = DomainImage(Z->P,U,MAXNOOFRAYS);
- ZDomain_Free(Z);
-
- Zpol=ZPolyhedron_Alloc((Lattice *)H,Image);
- Domain_Free(Image);
- Matrix_Free((Matrix *)Lat);
- Matrix_Free(H);
- Matrix_Free(U);
-
- if ((Head == NULL) || (isEmptyZPolyhedron (Head))) {
- Head = Zpol;
- continue;
- }
- temp1 = temp = Head;
-
- /* Check if the curr pol is included in the zpol or vice versa. */
- for(; temp != NULL; temp = temp->next) {
- if (ZPolyhedronIncludes(Zpol, temp) == True) {
- ZPolyhedron_Free (Zpol);
- Added = True;
- break;
- }
- else if (ZPolyhedronIncludes(temp, Zpol) == True) {
- if (temp == Head) {
- Zpol->next = temp->next;
- Head = Zpol;
- ZPolyhedron_Free (temp);
- Added = True;
- break;
- }
- temp1->next = Zpol;
- Zpol->next = temp->next;
- ZPolyhedron_Free (temp);
- Added = True;
- break ;
- }
- temp1 = temp ;
- }
- if(Added == True)
- continue ;
- for(temp = Head; temp != NULL; temp = temp->next) {
- if(sameLattice(temp->Lat, Zpol->Lat) == True) {
- Polyhedron *Union;
-
- Union = DomainUnion (temp->P,Zpol->P,MAXNOOFRAYS);
- if (!Union)
- fprintf (stderr,"\n In AddZPolytoZDomain: Out of memory\n");
- else {
- Domain_Free(temp->P);
- temp->P = Union;
- Added = True;
- ZPolyhedron_Free(Zpol);
- }
- break ;
- }
- temp1 = temp;
- }
- if (Added == False)
- temp1->next = Zpol;
- }
- return Head ;
-} /* AddZPolytoZDomain */
-
-/*
- * Return the empty Z-polyhedron of dimension 'dimension'
- */
-ZPolyhedron *EmptyZPolyhedron(int dimension) {
-
- ZPolyhedron *Zpol;
- Lattice *E ;
- Polyhedron *P;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen ("_debug", "a");
- fprintf (fp, "\nEntered EMPTYZPOLYHEDRON\n");
- fclose (fp);
-#endif
-
- E = EmptyLattice(dimension+1);
- P = Empty_Polyhedron(dimension);
- Zpol = ZPolyhedron_Alloc(E,P);
- Matrix_Free((Matrix *) E);
- Domain_Free(P);
- return Zpol;
-} /* EmptyZPolyhedron */
-
-/*
- * Given Z-domains 'A' and 'B', return True if A is included in 'B', otherwise
- * return False.
- */
-Bool ZDomainIncludes(ZPolyhedron *A, ZPolyhedron *B) {
-
- ZPolyhedron *Diff;
- Bool ret = False;
-
- Diff = ZDomainDifference(A,B);
- if (isEmptyZPolyhedron(Diff))
- ret = True;
-
- ZDomain_Free(Diff);
- return ret;
-} /* ZDomainIncludes */
-
-/*
- * Given Z-polyhedra 'A' and 'B', return True if 'A' is included in 'B',
- * otherwise return False
- */
-Bool ZPolyhedronIncludes(ZPolyhedron *A, ZPolyhedron *B) {
-
- Polyhedron *Diff = NULL ;
- Bool retval = False;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug","a");
- fprintf(fp,"\nEntered ZPOLYHEDRONINCLUDES\n");
- fclose(fp);
-#endif
-
- if (LatticeIncludes(A->Lat, B->Lat) == True) {
- Polyhedron *ImageA, *ImageB ;
-
- ImageA = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
- ImageB = DomainImage(B->P,B->Lat,MAXNOOFRAYS);
-
- Diff = DomainDifference(ImageA, ImageB, MAXNOOFRAYS);
- if(emptyQ (Diff))
- retval = True ;
-
- Domain_Free (ImageA);
- Domain_Free (ImageB);
- Domain_Free (Diff);
- }
- return retval;
-} /* ZPolyhedronIncludes */
-
-/*
- * Print the contents of a Z-domain 'A'
- */
-void ZDomainPrint(FILE *fp, const char *format, ZPolyhedron *A)
-{
-#ifdef DOMDEBUG
- FILE *fp1;
- fp1 = fopen("_debug", "a");
- fprintf(fp1,"\nEntered ZDOMAINPRINT\n");
- fclose(fp1);
-#endif
-
- ZPolyhedronPrint(fp,format,A);
- if (A->next != NULL) {
- fprintf(fp,"\nUNIONED with\n");
- ZDomainPrint(fp,format,A->next);
- }
- return;
-} /* ZDomainPrint */
-
-/*
- * Print the contents of a ZPolyhderon 'A'
- */
-static void ZPolyhedronPrint (FILE *fp, const char *format, ZPolyhedron *A)
-{
- if (A == NULL)
- return ;
- fprintf(fp,"\nZPOLYHEDRON: Dimension %d \n",A->Lat->NbRows-1);
- fprintf(fp, "\nLATTICE: \n");
- Matrix_Print(fp,format,(Matrix *)A->Lat);
- Polyhedron_Print(fp,format,A->P);
- return;
-} /* ZPolyhedronPrint */
-
-/*
- * Return the Z-domain union of the Z-domain 'A' and 'B'. The dimensions of the
- * Z-domains 'A' and 'B' must be equal. All the Z-polyhedra of the resulting
- * union are expected to be in Canonical forms.
- */
-ZPolyhedron *ZDomainUnion (ZPolyhedron *A, ZPolyhedron *B) {
-
- ZPolyhedron *Result = NULL, *temp;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered ZDOMAINUNION\n");
- fclose(fp);
-#endif
-
- for(temp = A; temp != NULL; temp = temp->next)
- Result = AddZPolytoZDomain(temp, Result);
- for(temp = B; temp != NULL; temp = temp->next )
- Result = AddZPolytoZDomain(temp, Result);
- return Result;
-} /* ZDomainUnion */
-
-/*
- * Return the Z-domain intersection of the Z-domains 'A' and 'B'.The dimensions
- * of domains 'A' and 'B' must be equal.
- */
-ZPolyhedron *ZDomainIntersection (ZPolyhedron *A, ZPolyhedron *B) {
-
- ZPolyhedron *Result = NULL, *tempA = NULL, *tempB = NULL;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered ZDOMAININTERSECTION\n");
- fclose(fp);
-#endif
-
- for(tempA = A; tempA != NULL; tempA = tempA->next)
- for(tempB = B; tempB != NULL; tempB = tempB->next) {
- ZPolyhedron *Zpol;
- Zpol = ZPolyhedronIntersection(tempA, tempB);
- Result = AddZPolytoZDomain(Zpol, Result );
- ZPolyhedron_Free (Zpol);
- }
- if (Result == NULL)
- return EmptyZPolyhedron (A->Lat->NbRows-1);
- return Result;
-} /* ZDomainIntersection */
-
-/*
- * Return the Z-domain difference of the domains 'A' and 'B'. The dimensions of
- * the Z-domains 'A' and 'B' must be equal. Note that the difference of two
- * Z-polyhedra is a Union of Z-polyhedra. The algorithms is as given below :-
- * Algorithm: (Given Z-domains A and B)
- * Result <-- NULL
- * for every Z-polyhderon Zpoly of A {
- * temp <-- Zpoly;
- * for every Z-polyhderon Z1 of B
- * temp = temp - Z1;
- * }
- * Add temp to Result;
- * return;
- */
-ZPolyhedron *ZDomainDifference(ZPolyhedron *A, ZPolyhedron *B) {
-
- ZPolyhedron *Result = NULL, *tempA = NULL, *tempB = NULL;
- ZPolyhedron *templist, *res, *i, *j;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered ZDOMAINDIFFERENCE\n");
- fclose(fp);
-#endif
-
- if (A->Lat->NbRows != B->Lat->NbRows) {
- fprintf(stderr, "In ZDomainDifference : the input ZDomains ");
- fprintf(stderr, "do not have compatible dimensions\n");
- fprintf(stderr, "ZDomainDifference not performed\n");
- return NULL;
- }
-
- for(tempA = A; tempA != NULL; tempA = tempA->next) {
- ZPolyhedron *temp = NULL;
- temp = ZPolyhedron_Copy(tempA);
-
- for(tempB = B; tempB != NULL; tempB = tempB->next) {
- templist = NULL; res = NULL;
- for(i = temp; i != NULL; i = i->next) {
- res = ZPolyhedronDifference(i,tempB);
- for (j = res; j != NULL; j = j->next )
- templist = AddZPoly2ZDomain(j,templist);
- ZDomain_Free(res);
- }
- ZDomain_Free (temp);
- temp = NULL;
- for(i = templist; i != NULL; i = i->next)
- temp = AddZPoly2ZDomain(i, temp);
- ZDomain_Free (templist);
- }
- for(i = temp; i != NULL; i = i->next)
- Result = AddZPolytoZDomain(i, Result);
- ZDomain_Free(temp);
- }
- if (Result==NULL)
- return (EmptyZPolyhedron(A->Lat->NbRows-1));
- return Result;
-} /* ZDomainDifference */
-
-/*
- * Return the image of the Z-domain 'A' under the invertible, affine, rational
- * transformation function 'Func'. The matrix representing the function 'Func'
- * must be non-singular and the number of rows of the function must be equal
- * to the number of rows in the matrix representing the lattice of 'A'.
- * Note:: Image((Z1 U Z2),F) = Image(Z1,F) U Image(Z2 U F).
- */
-ZPolyhedron *ZDomainImage (ZPolyhedron *A, Matrix *Func) {
-
- ZPolyhedron *Result = NULL, *temp;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen ("_debug", "a");
- fprintf (fp, "\nEntered ZDOMAINIMAGE\n");
- fclose (fp);
-#endif
-
- for(temp = A; temp != NULL; temp = temp->next) {
- ZPolyhedron *Zpol;
- Zpol = ZPolyhedronImage (temp, Func);
- Result = AddZPolytoZDomain (Zpol, Result);
- ZPolyhedron_Free (Zpol);
- }
- if(Result == NULL)
- return EmptyZPolyhedron(A->Lat->NbRows-1);
- return Result;
-} /* ZDomainImage */
-
-/*
- * Return the preimage of the Z-domain 'A' under the invertible, affine, ratio-
- * nal transformation 'Func'. The number of rows of the matrix representing
- * the function 'Func' must be equal to the number of rows of the matrix repr-
- * senting the lattice of 'A'.
- */
-ZPolyhedron *ZDomainPreimage (ZPolyhedron *A, Matrix *Func) {
-
- ZPolyhedron *Result = NULL, *temp ;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered ZDOMAINPREIMAGE\n");
- fclose(fp);
-#endif
-
- if (A->Lat->NbRows != Func->NbRows) {
- fprintf(stderr,"\nError : In ZDomainPreimage, ");
- fprintf(stderr,"Incompatible dimensions of ZPolyhedron ");
- fprintf(stderr,"and the Function \n");
- return(EmptyZPolyhedron(Func->NbColumns-1));
- }
- for(temp = A; temp != NULL; temp = temp->next) {
- ZPolyhedron *Zpol;
- Zpol = ZPolyhedronPreimage(temp, Func);
- Result = AddZPolytoZDomain(Zpol, Result);
- ZPolyhedron_Free(Zpol);
- }
- if (Result == NULL)
- return(EmptyZPolyhedron(Func->NbColumns-1));
- return Result;
-} /* ZDomainPreimage */
-
-/*
- * Return the Z-polyhedron intersection of the Z-polyhedra 'A' and 'B'.
- * Note: If Z1 = L1 (intersect) P1 and Z2 = L2 (intersect) P2, then
- * Z1 (intersect) Z2 = (L1 (intersect) L2) (intersect) (P1 (intersect) P2)
- */
-static ZPolyhedron *ZPolyhedronIntersection(ZPolyhedron *A, ZPolyhedron *B) {
-
- ZPolyhedron *Result = NULL;
- Lattice *LInter;
- Polyhedron *PInter, *ImageA, *ImageB, *PreImage;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug","a");
- fprintf(fp,"\nEntered ZPOLYHEDRONINTERSECTION\n");
- fclose(fp);
-#endif
-
- LInter = LatticeIntersection(A->Lat,B->Lat);
- if(isEmptyLattice(LInter) == True) {
- ZPolyhedron_Free (Result);
- Matrix_Free(LInter);
- return (EmptyZPolyhedron(A->Lat->NbRows-1));
- }
- ImageA = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
- ImageB = DomainImage(B->P,B->Lat,MAXNOOFRAYS);
- PInter = DomainIntersection(ImageA,ImageB,MAXNOOFRAYS);
- if (emptyQ(PInter))
- Result = EmptyZPolyhedron(LInter->NbRows-1);
- else {
- PreImage = DomainPreimage(PInter,(Matrix *)LInter,MAXNOOFRAYS);
- Result = ZPolyhedron_Alloc(LInter, PreImage);
- Domain_Free (PreImage);
- }
- Matrix_Free(LInter);
- Domain_Free(PInter);
- Domain_Free(ImageA);
- Domain_Free(ImageB);
- return Result ;
-} /* ZPolyhedronIntersection */
-
-/*
- * Return the difference of the two Z-polyhedra 'A' and 'B'. Below is the
- * procedure to find the difference of 'A' and 'B' :-
- * Procedure:
- * Let A = L1 (intersect) P1' and B = L2 (intersect) P2' where
- * (P1' = DomImage(P1,L1) and P2' = DomImage(P2,L2)). Then
- * A-B = L1 (intersect) (P1'-P2') Union
- * (L1-L2) (intersect) (P1' (intersect) P2')
- */
-static ZPolyhedron *ZPolyhedronDifference(ZPolyhedron *A, ZPolyhedron *B) {
-
- ZPolyhedron *Result = NULL ;
- LatticeUnion *LatDiff, *temp;
- Polyhedron *DomDiff, *DomInter, *PreImage, *ImageA, *ImageB;
- Bool flag = False;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered ZPOLYHEDRONDIFFERENCE\n");
- fclose(fp);
-#endif
-
- if(isEmptyZPolyhedron (A))
- return NULL;
- if(isEmptyZPolyhedron (B)) {
- Result = ZDomain_Copy (A);
- return Result;
- }
- ImageA = DomainImage(A->P,(Matrix *)A->Lat,MAXNOOFRAYS);
- ImageB = DomainImage(B->P,(Matrix *)B->Lat,MAXNOOFRAYS);
- DomDiff = DomainDifference(ImageA,ImageB,MAXNOOFRAYS);
- if (emptyQ (DomDiff))
- flag = True;
- else {
- ZPolyhedron *Z;
- PreImage = DomainPreimage(DomDiff,A->Lat,MAXNOOFRAYS);
- Z = ZPolyhedron_Alloc(A->Lat,PreImage);
- Result = AddZPolytoZDomain(Z,Result);
- }
- if (flag == True) /* DomDiff = NULL; DomInter = A */
- DomInter = Domain_Copy(ImageA);
- else {
- DomInter = DomainIntersection(ImageA,ImageB,MAXNOOFRAYS);
- if (emptyQ(DomInter)) {
- if (flag == True)
- return (EmptyZPolyhedron(A->Lat->NbRows-1));
- else
- return Result;
- }
- }
- LatDiff = LatticeDifference(A->Lat, B->Lat);
- if(LatDiff == NULL)
- if(flag == True )
- return(EmptyZPolyhedron (A->Lat->NbRows-1));
-
- while (LatDiff != NULL) {
- ZPolyhedron *tempZ = NULL;
-
- PreImage = DomainPreimage(DomInter, LatDiff->M, MAXNOOFRAYS);
- tempZ = ZPolyhedron_Alloc(LatDiff->M, PreImage);
- Domain_Free(PreImage);
- Result = AddZPoly2ZDomain(tempZ,Result);
- ZPolyhedron_Free(tempZ);
- temp = LatDiff;
- LatDiff = LatDiff->next;
- Matrix_Free ((Matrix *) temp->M);
- free (temp);
- }
- Domain_Free (DomInter);
- Domain_Free (DomDiff);
- return Result;
-} /* ZPolyhedronDifference */
-
-/*
- * Return the image of the Z-polyhedron 'ZPol' under the invertible, affine,
- * rational transformation function 'Func'. The matrix representing the funct-
- * ion must be non-singular and the number of rows of the function must be
- * equal to the number of rows in the matrix representing the lattice of 'ZPol'
- * Algorithm:
- * 1) Let ZPol = L (intersect) Q
- * 2) L1 = LatticeImage(L,F)
- * 3) Q1 = DomainImage(Q,F)
- * 4) Z1 = L1(Inverse(L1)*Q1)
- * 5) Return Z1
- */
-static ZPolyhedron *ZPolyhedronImage(ZPolyhedron *ZPol,Matrix *Func) {
-
- ZPolyhedron *Result = NULL ;
- Matrix *LatIm ;
- Polyhedron *Pol, *PolImage ;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered ZPOLYHEDRONIMAGE\n");
- fclose(fp);
-#endif
-
- if ((Func->NbRows != ZPol->Lat->NbRows) || (Func->NbColumns != ZPol->Lat->NbColumns)) {
- fprintf (stderr, "In ZPolImage - The Function, is not compatible with the ZPolyhedron\n");
- return NULL;
- }
- LatIm = LatticeImage(ZPol->Lat,Func);
- if (isEmptyLattice(LatIm)) {
- Matrix_Free(LatIm);
- return NULL;
- }
- Pol = DomainImage(ZPol->P,ZPol->Lat,MAXNOOFRAYS);
- PolImage = DomainImage(Pol,Func,MAXNOOFRAYS);
- Domain_Free(Pol);
- if(emptyQ(PolImage)) {
- Matrix_Free (LatIm);
- Domain_Free (PolImage);
- return NULL;
- }
- Pol = DomainPreimage(PolImage,LatIm,MAXNOOFRAYS);
- Result = ZPolyhedron_Alloc(LatIm,Pol);
- Domain_Free(Pol);
- Domain_Free(PolImage);
- Matrix_Free(LatIm);
- return Result;
-} /* ZPolyhedronImage */
-
-/*
- * Return the preimage of the Z-polyhedron 'Zpol' under an affine transformati-
- * on function 'G'. The number of rows of matrix representing the function 'G',
- * must be equal to the number of rows of the matrix representing the lattice
- * of Z1.
- * Algorithm:
- * 1) Let Zpol = L (intersect) Q
- * 2) L1 =LatticePreimage(L,F);
- * 3) Q1 = DomainPreimage(Q,F);
- * 4) Z1 = L1(Inverse(L1)*Q1);
- * 5) Return Z1
- */
-static ZPolyhedron *ZPolyhedronPreimage(ZPolyhedron *Zpol, Matrix *G) {
-
- Lattice *Latpreim;
- Polyhedron *Qprime, *Q, *Polpreim;
- ZPolyhedron *Result;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug","a");
- fprintf(fp,"\nEntered ZPOLYHEDRONPREIMAGE\n");
- fclose(fp);
-#endif
-
- if(G->NbRows != Zpol->Lat->NbRows) {
- fprintf(stderr,"\nIn ZPolyhedronPreimage: Error, The dimensions of the ");
- fprintf(stderr,"function are not compatible with that of the Zpolyhedron");
- return EmptyZPolyhedron(G->NbColumns-1);
- }
- Q = DomainImage(Zpol->P,Zpol->Lat,MAXNOOFRAYS);
- Polpreim = DomainPreimage(Q,G,MAXNOOFRAYS);
- if (emptyQ(Polpreim))
- Result = NULL;
- else {
- Latpreim = LatticePreimage(Zpol->Lat,G);
- if(isEmptyLattice(Latpreim))
- Result = NULL;
- else {
- Qprime = DomainPreimage(Polpreim, Latpreim, MAXNOOFRAYS);
- Result = ZPolyhedron_Alloc(Latpreim, Qprime);
- Domain_Free(Qprime);
- }
- Matrix_Free(Latpreim);
- }
- Domain_Free(Q);
- return Result;
-} /* ZPolyhedronPreimage */
-
-/*
- * Return the Z-polyhderon 'Zpol' in canonical form: 'Result' (for the Z-poly-
- * hedron in canonical form) and Basis 'Basis' (for the basis with respect to
- * which 'Result' is in canonical form.
- */
-void CanonicalForm(ZPolyhedron *Zpol,ZPolyhedron **Result,Matrix **Basis) {
-
- Matrix *B1 = NULL, *B2=NULL, *T1 , *B2inv;
- int i, l1, l2;
- Value tmp;
- Polyhedron *Image, *ImageP;
- Matrix *H, *U, *temp, *Hprime, *Uprime, *T2;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered CANONICALFORM\n");
- fclose(fp);
-#endif
-
- if(isEmptyZPolyhedron (Zpol)) {
- Basis[0] = Identity(Zpol->Lat->NbRows);
- Result[0] = ZDomain_Copy (Zpol);
- return ;
- }
- value_init(tmp);
- l1 = FindHermiteBasisofDomain(Zpol->P,&B1);
- Image = DomainImage (Zpol->P,(Matrix *)Zpol->Lat,MAXNOOFRAYS);
- l2 = FindHermiteBasisofDomain(Image,&B2);
-
- if (l1 != l2)
- fprintf(stderr,"In CNF : Something wrong with the Input Zpolyhedra \n");
-
- B2inv = Matrix_Alloc(B2->NbRows, B2->NbColumns);
- temp = Matrix_Copy(B2);
- Matrix_Inverse(temp,B2inv);
- Matrix_Free(temp);
-
- temp = Matrix_Alloc(B2inv->NbRows,Zpol->Lat->NbColumns);
- T1 = Matrix_Alloc(temp->NbRows,B1->NbColumns);
- Matrix_Product(B2inv,(Matrix *)Zpol->Lat,temp);
- Matrix_Product(temp,B1,T1);
- Matrix_Free(temp);
-
- T2 = ChangeLatticeDimension(T1,l1);
- temp = ChangeLatticeDimension(T2,T2->NbRows+1);
-
- /* Adding the affine part */
- for(i = 0; i < l1; i ++)
- value_assign(temp->p[i][temp->NbColumns-1],T1->p[i][T1->NbColumns-1]);
-
- AffineHermite(temp,&H,&U);
- Hprime = ChangeLatticeDimension(H,Zpol->Lat->NbRows);
-
- /* Exchanging the Affine part */
- for(i = 0; i < l1; i ++) {
- value_assign(tmp,Hprime->p[i][Hprime->NbColumns-1]);
- value_assign(Hprime->p[i][Hprime->NbColumns-1],Hprime->p[i][H->NbColumns-1]);
- value_assign(Hprime->p[i][H->NbColumns-1],tmp);
- }
- Uprime = ChangeLatticeDimension(U,Zpol->Lat->NbRows);
-
- /* Exchanging the Affine part */
- for (i = 0;i < l1; i++) {
- value_assign(tmp,Uprime->p[i][Uprime->NbColumns-1]);
- value_assign(Uprime->p[i][Uprime->NbColumns-1],Uprime->p[i][U->NbColumns-1]);
- value_assign(Uprime->p[i][U->NbColumns-1],tmp);
- }
- Polyhedron_Free (Image);
- Matrix_Free (B2inv);
- B2inv = Matrix_Alloc(B1->NbRows, B1->NbColumns);
- Matrix_Inverse(B1,B2inv);
- ImageP = DomainImage(Zpol->P, B2inv, MAXNOOFRAYS);
- Matrix_Free(B2inv);
- Image = DomainImage(ImageP, Uprime, MAXNOOFRAYS);
- Domain_Free(ImageP);
- Result[0] = ZPolyhedron_Alloc(Hprime, Image);
- Basis[0] = Matrix_Copy(B2);
-
- /* Free the variables */
- Polyhedron_Free (Image);
- Matrix_Free (B1);
- Matrix_Free (B2);
- Matrix_Free (temp);
- Matrix_Free (T1);
- Matrix_Free (T2);
- Matrix_Free (H);
- Matrix_Free (U);
- Matrix_Free (Hprime);
- Matrix_Free (Uprime);
- value_clear(tmp);
- return;
-} /* CanonicalForm */
-
-/*
- * Given a Z-polyhedron 'A' in which the Lattice is not integral, return the
- * Z-polyhedron which contains all the integral points in the input lattice.
- */
-ZPolyhedron *IntegraliseLattice(ZPolyhedron *A) {
-
- ZPolyhedron *Result;
- Lattice *M = NULL, *Id;
- Polyhedron *Im = NULL, *Preim = NULL;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug","a");
- fprintf(fp,"\nEntered INTEGRALISELATTICE\n");
- fclose(fp);
-#endif
-
- Im = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
- Id = Identity(A->Lat->NbRows);
- M = LatticeImage(Id, A->Lat);
- if (isEmptyLattice(M))
- Result = EmptyZPolyhedron(A->Lat->NbRows-1);
- else {
- Preim = DomainPreimage(Im,M,MAXNOOFRAYS);
- Result = ZPolyhedron_Alloc(M,Preim);
- }
- Matrix_Free(M);
- Domain_Free(Im);
- Domain_Free(Preim);
- return Result;
-} /* IntegraliseLattice */
-
-/*
- * Return the simplified representation of the Z-domain 'ZDom'. It attempts to
- * convexize unions of polyhedra when they correspond to the same lattices and
- * to simplify union of lattices when they correspond to the same polyhdera.
- */
-ZPolyhedron *ZDomainSimplify(ZPolyhedron *ZDom) {
-
- ZPolyhedron *Ztmp, *Result;
- ForSimplify *Head, *Prev, *Curr;
- ZPolyhedron *ZDomHead, *Emp;
-
- if (ZDom == NULL) {
- fprintf(stderr,"\nError in ZDomainSimplify - ZDomHead = NULL\n");
- return NULL;
- }
- if (ZDom->next == NULL)
- return (ZPolyhedron_Copy (ZDom));
- Emp = EmptyZPolyhedron(ZDom->Lat->NbRows-1);
- ZDomHead = ZDomainUnion(ZDom, Emp);
- ZPolyhedron_Free(Emp);
- Head = NULL;
- Ztmp = ZDomHead;
- do {
- Polyhedron *Img;
- Img = DomainImage(Ztmp->P,Ztmp->Lat,MAXNOOFRAYS);
- for(Curr = Head; Curr != NULL; Curr = Curr->next) {
- Polyhedron *Diff1;
- Bool flag = False;
-
- Diff1 = DomainDifference(Img,Curr->Pol,MAXNOOFRAYS);
- if (emptyQ(Diff1)) {
- Polyhedron *Diff2;
-
- Diff2 = DomainDifference(Curr->Pol,Img,MAXNOOFRAYS);
- if (emptyQ(Diff2))
- flag = True;
- Domain_Free(Diff2);
- }
- Domain_Free (Diff1);
- if (flag == True) {
- LatticeUnion *temp;
-
- temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
- temp->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat);
- temp->next = Curr->LatUni;
- Curr->LatUni = temp;
- break;
- }
- }
- if(Curr == NULL) {
- Curr = (ForSimplify *)malloc(sizeof(ForSimplify));
- Curr->Pol = Domain_Copy(Img);
- Curr->LatUni = (LatticeUnion *)malloc(sizeof(LatticeUnion));
- Curr->LatUni->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat);
- Curr->LatUni->next = NULL;
- Curr->next = Head;
- Head = Curr;
- }
- Domain_Free (Img);
- Ztmp = Ztmp->next;
- } while(Ztmp != NULL);
-
- for (Curr = Head; Curr != NULL; Curr = Curr->next)
- Curr->LatUni = LatticeSimplify(Curr->LatUni);
- Result = NULL;
- for(Curr = Head; Curr != NULL; Curr = Curr->next) {
- LatticeUnion *L;
- for(L = Curr->LatUni; L != NULL; L = L->next) {
- Polyhedron *Preim;
- ZPolyhedron *Zpol;
-
- Preim = DomainPreimage(Curr->Pol,L->M,MAXNOOFRAYS);
- Zpol = ZPolyhedron_Alloc(L->M, Preim);
- Zpol->next = Result;
- Result = Zpol;
- Domain_Free(Preim);
- }
- }
- Curr = Head;
- while (Curr != NULL) {
- Prev = Curr;
- Curr = Curr->next;
- LatticeUnion_Free(Prev->LatUni);
- Domain_Free(Prev->Pol);
- free(Prev);
- }
- return Result;
-} /* ZDomainSimplify */
-
-ZPolyhedron *SplitZpolyhedron(ZPolyhedron *ZPol,Lattice *B) {
-
- Lattice *Intersection = NULL;
- Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL;
- Matrix *U = NULL,*M1 = NULL, *M2 = NULL, *M1Inverse = NULL,*MtProduct = NULL;
- Matrix *Vinv, *V , *temp, *DiagMatrix ;
- Matrix *H , *U1 , *X, *Y ;
- ZPolyhedron *zpnew, *Result;
- LatticeUnion *Head = NULL, *tempHead = NULL;
- int i;
- Value k;
-
-#ifdef DOMDEBUG
- FILE *fp;
- fp = fopen("_debug", "a");
- fprintf(fp,"\nEntered SplitZpolyhedron \n");
- fclose(fp);
-#endif
-
-
- if (B->NbRows != B->NbColumns) {
- fprintf(stderr,"\n SplitZpolyhedron : The Input Matrix B is not a proper Lattice \n");
- return NULL;
- }
-
- if (ZPol->Lat->NbRows != B->NbRows) {
- fprintf(stderr,"\nSplitZpolyhedron : The Lattice in Zpolyhedron and B have ");
- fprintf(stderr,"incompatible dimensions \n");
- return NULL;
- }
-
- if (isinHnf (ZPol->Lat) != True) {
- AffineHermite(ZPol->Lat,&H,&U1);
- X = Matrix_Copy(H);
- Matrix_Free(U1);
- Matrix_Free(H);
- }
- else
- X = Matrix_Copy(ZPol->Lat);
-
- if (isinHnf(B) != True) {
- AffineHermite(B,&H,&U1);
- Y = Matrix_Copy(H);
- Matrix_Free(H);
- Matrix_Free(U1);
- }
- else
- Y = Matrix_Copy(B);
- if (isEmptyLattice(X)) {
- return NULL;
- }
-
- Head=Lattice2LatticeUnion(X,Y);
-
-/* If the spliting operation can't be done the result is the original Zplyhedron. */
-
- if (Head == NULL) {
- Matrix_Free(X);
- Matrix_Free(Y);
- return ZPol;
- }
-
-
- Result=NULL;
-
- if (Head)
- while(Head)
- {
- tempHead = Head;
- Head = Head->next;
- zpnew=ZPolyhedron_Alloc(tempHead->M,ZPol->P);
- Result=AddZPoly2ZDomain(zpnew,Result);
- ZPolyhedron_Free(zpnew);
- tempHead->next = NULL;
- free(tempHead);
- }
-
- return Result;
-}
-
-
-
diff --git a/source/polylib_mod/alpha.c b/source/polylib_mod/alpha.c
deleted file mode 100644
index 1a7d005..0000000
--- a/source/polylib_mod/alpha.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* polytest.c */
-#include <stdio.h>
-#include <polylib/polylib.h>
-
-/* alpha.c
- COPYRIGHT
- Both this software and its documentation are
-
- Copyright 1993 by IRISA /Universite de Rennes I - France,
- Copyright 1995,1996 by BYU, Provo, Utah
- all rights reserved.
-
- Permission is granted to copy, use, and distribute
- for any commercial or noncommercial purpose under the terms
- of the GNU General Public license, version 2, June 1991
- (see file : LICENSING).
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*---------------------------------------------------------------------*/
-/* int exist_points(pos,P,context) */
-/* pos : index position of current loop index (0..hdim-1) */
-/* P: loop domain */
-/* context : context values for fixed indices */
-/* recursive procedure, recurs for each imbriquation */
-/* returns 1 if there exists any integer points in this polyhedron */
-/* returns 0 if there are none */
-/*---------------------------------------------------------------------*/
-static int exist_points(int pos,Polyhedron *Pol,Value *context) {
-
- Value LB, UB, k,tmp;
-
- value_init(LB); value_init(UB);
- value_init(k); value_init(tmp);
- value_set_si(LB,0);
- value_set_si(UB,0);
-
- /* Problem if UB or LB is INFINITY */
- if (lower_upper_bounds(pos,Pol,context,&LB,&UB) !=0) {
- errormsg1("exist_points", "infdom", "infinite domain");
- value_clear(LB);
- value_clear(UB);
- value_clear(k);
- value_clear(tmp);
- return -1;
- }
- value_set_si(context[pos],0);
- if(value_lt(UB,LB)) {
- value_clear(LB);
- value_clear(UB);
- value_clear(k);
- value_clear(tmp);
- return 0;
- }
- if (!Pol->next) {
- value_subtract(tmp,UB,LB);
- value_increment(tmp,tmp);
- value_clear(UB);
- value_clear(LB);
- value_clear(k);
- return (value_pos_p(tmp));
- }
-
- for (value_assign(k,LB);value_le(k,UB);value_increment(k,k)) {
-
- /* insert k in context */
- value_assign(context[pos],k);
- if (exist_points(pos+1,Pol->next,context) > 0 ) {
- value_clear(LB); value_clear(UB);
- value_clear(k); value_clear(tmp);
- return 1;
- }
- }
- /* Reset context */
- value_set_si(context[pos],0);
- value_clear(UB); value_clear(LB);
- value_clear(k); value_clear(tmp);
- return 0;
-}
-
-/*--------------------------------------------------------------*/
-/* Test to see if there are any integral points in a polyhedron */
-/*--------------------------------------------------------------*/
-int Polyhedron_Not_Empty(Polyhedron *P,Polyhedron *C,int MAXRAYS) {
-
- int res,i;
- Value *context;
- Polyhedron *L;
-
- POL_ENSURE_FACETS(P);
- POL_ENSURE_VERTICES(P);
- POL_ENSURE_FACETS(C);
- POL_ENSURE_VERTICES(C);
-
- /* Create a context vector size dim+2 and set it to all zeros */
- context = (Value *) malloc((P->Dimension+2)*sizeof(Value));
-
- /* Initialize array 'context' */
- for (i=0;i<(P->Dimension+2);i++)
- value_init(context[i]);
-
- Vector_Set(context,0,(P->Dimension+2));
-
- /* Set context[P->Dimension+1] = 1 (the constant) */
- value_set_si(context[P->Dimension+1],1);
-
- L = Polyhedron_Scan(P,C,MAXRAYS);
- res = exist_points(1,L,context);
- Domain_Free(L);
-
- /* Clear array 'context' */
- for (i=0;i<(P->Dimension+2);i++)
- value_clear(context[i]);
- free(context);
- return res;
-}
-
-/* PolyhedronLTQ ( P1, P2 ) */
-/* P1 and P2 must be simple polyhedra */
-/* result = 0 --> not comparable */
-/* result = -1 --> P1 < P2 */
-/* result = 1 --> P1 > P2 */
-/* INDEX = 1 .... Dimension */
-int PolyhedronLTQ (Polyhedron *Pol1,Polyhedron *Pol2,int INDEX, int PDIM, int NbMaxConstrs) {
-
- int res, dim, i, j, k;
- Polyhedron *Q1, *Q2, *Q3, *Q4, *Q;
- Matrix *Mat;
-
- if (Pol1->next || Pol2->next) {
- errormsg1("PolyhedronLTQ", "compoly", "Can only compare polyhedra");
- return 0;
- }
- if (Pol1->Dimension != Pol2->Dimension) {
- errormsg1("PolyhedronLTQ","diffdim","Polyhedra are not same dimension");
- return 0;
- }
- dim = Pol1->Dimension+2;
-
- POL_ENSURE_FACETS(Pol1);
- POL_ENSURE_VERTICES(Pol1);
- POL_ENSURE_FACETS(Pol2);
- POL_ENSURE_VERTICES(Pol2);
-
-#ifdef DEBUG
- fprintf(stdout, "P1\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Pol1);
- fprintf(stdout, "P2\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Pol2);
-#endif
-
- /* Create the Line to add */
- k = Pol1->Dimension-INDEX+1-PDIM;
- Mat = Matrix_Alloc(k,dim);
- Vector_Set(Mat->p_Init,0,dim*k);
- for(j=0,i=INDEX;j<k;i++,j++)
- value_set_si(Mat->p[j][i],1);
-
- Q1 = AddRays(Mat->p[0],k,Pol1,NbMaxConstrs);
- Q2 = AddRays(Mat->p[0],k,Pol2,NbMaxConstrs);
-
-#ifdef DEBUG
- fprintf(stdout, "Q1\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Q1);
- fprintf(stdout, "Q2\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Q2);
-#endif
-
- Matrix_Free(Mat);
- Q = DomainIntersection(Q1,Q2,NbMaxConstrs);
-
-#ifdef DEBUG
- fprintf(stdout, "Q\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Q);
-#endif
-
- Domain_Free(Q1);
- Domain_Free(Q2);
-
- if (emptyQ(Q)) res = 0; /* not comparable */
- else {
- Q1 = DomainIntersection(Pol1,Q,NbMaxConstrs);
- Q2 = DomainIntersection(Pol2,Q,NbMaxConstrs);
-
-#ifdef DEBUG
- fprintf(stdout, "Q1\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Q1);
- fprintf(stdout, "Q2\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Q2);
-#endif
-
- k = Q1->NbConstraints + Q2->NbConstraints;
- Mat = Matrix_Alloc(k, dim);
- Vector_Set(Mat->p_Init,0,k*dim);
-
- /* First compute surrounding polyhedron */
- j=0;
- for (i=0; i<Q1->NbConstraints; i++) {
- if ((value_one_p(Q1->Constraint[i][0])) && (value_pos_p(Q1->Constraint[i][INDEX]))) {
-
- /* keep Q1's lower bounds */
- for (k=0; k<dim; k++)
- value_assign(Mat->p[j][k],Q1->Constraint[i][k]);
- j++;
- }
- }
- for (i=0; i<Q2->NbConstraints; i++) {
- if ((value_one_p(Q2->Constraint[i][0])) && (value_neg_p(Q2->Constraint[i][INDEX]))) {
-
- /* and keep Q2's upper bounds */
- for (k=0; k<dim; k++)
- value_assign(Mat->p[j][k],Q2->Constraint[i][k]);
- j++;
- }
- }
- Q4 = AddConstraints(Mat->p[0], j, Q, NbMaxConstrs);
- Matrix_Free(Mat);
-
-#ifdef debug
- fprintf(stderr, "Q4 surrounding polyhedron\n");
- Polyhderon_Print(stderr,P_VALUE_FMT, Q4);
-#endif
-
- /* if surrounding polyhedron is empty, D1>D2 */
- if (emptyQ(Q4)) {
- res = 1;
-
-#ifdef debug
- fprintf(stderr, "Surrounding polyhedron is empty\n");
-#endif
- goto LTQdone2;
- }
-
- /* Test if Q1 < Q2 */
- /* Build a constraint array for >= Q1 and <= Q2 */
- Mat = Matrix_Alloc(2,dim);
- Vector_Set(Mat->p_Init,0,2*dim);
-
- /* Choose a contraint from Q1 */
- for (i=0; i<Q1->NbConstraints; i++) {
- if (value_zero_p(Q1->Constraint[i][0])) {
-
- /* Equality */
- if (value_zero_p(Q1->Constraint[i][INDEX])) {
-
- /* Ignore side constraint (they are in Q) */
- continue;
- }
- else if (value_neg_p(Q1->Constraint[i][INDEX])) {
-
- /* copy -constraint to Mat */
- value_set_si(Mat->p[0][0],1);
- for (k=1; k<dim; k++)
- value_oppose(Mat->p[0][k],Q1->Constraint[i][k]);
- }
- else {
-
- /* Copy constraint to Mat */
-
- value_set_si(Mat->p[0][0],1);
- for (k=1; k<dim; k++)
- value_assign(Mat->p[0][k],Q1->Constraint[i][k]);
- }
- }
- else if(value_neg_p(Q1->Constraint[i][INDEX])) {
-
- /* Upper bound -- make a lower bound from it */
- value_set_si(Mat->p[0][0],1);
- for (k=1; k<dim; k++)
- value_oppose(Mat->p[0][k],Q1->Constraint[i][k]);
- }
- else {
-
- /* Lower or side bound -- ignore it */
- continue;
- }
-
- /* Choose a constraint from Q2 */
- for (j=0; j<Q2->NbConstraints; j++) {
- if (value_zero_p(Q2->Constraint[j][0])) { /* equality */
- if (value_zero_p(Q2->Constraint[j][INDEX])) {
-
- /* Ignore side constraint (they are in Q) */
- continue;
- }
- else if (value_pos_p(Q2->Constraint[j][INDEX])) {
-
- /* Copy -constraint to Mat */
- value_set_si(Mat->p[1][0],1);
- for (k=1; k<dim; k++)
- value_oppose(Mat->p[1][k],Q2->Constraint[j][k]);
- }
- else {
-
- /* Copy constraint to Mat */
- value_set_si(Mat->p[1][0],1);
- for (k=1; k<dim; k++)
- value_assign(Mat->p[1][k],Q2->Constraint[j][k]);
- };
- }
- else if (value_pos_p(Q2->Constraint[j][INDEX])) {
-
- /* Lower bound -- make an upper bound from it */
- value_set_si(Mat->p[1][0],1);
- for(k=1;k<dim;k++)
- value_oppose(Mat->p[1][k],Q2->Constraint[j][k]);
- }
- else {
-
- /* Upper or side bound -- ignore it */
- continue;
- };
-
-#ifdef DEBUG
- fprintf(stdout, "i=%d j=%d M=\n", i+1, j+1);
- Matrix_Print(stdout,P_VALUE_FMT,Mat);
-#endif
-
- /* Add Mat to Q and see if anything is made */
- Q3 = AddConstraints(Mat->p[0],2,Q,NbMaxConstrs);
-
-#ifdef DEBUG
- fprintf(stdout, "Q3\n");
- Polyhedron_Print(stdout,P_VALUE_FMT,Q3);
-#endif
-
- if (!emptyQ(Q3)) {
- Domain_Free(Q3);
-
-#ifdef DEBUG
- fprintf(stdout, "not empty\n");
-#endif
- res = -1;
- goto LTQdone;
- }
-#ifdef DEBUG
- fprintf(stdout,"empty\n");
-#endif
- Domain_Free(Q3);
- } /* end for j */
- } /* end for i */
- res = 1;
-LTQdone:
- Matrix_Free(Mat);
-LTQdone2:
- Domain_Free(Q4);
- Domain_Free(Q1);
- Domain_Free(Q2);
- }
- Domain_Free(Q);
-
-#ifdef DEBUG
- fprintf(stdout, "res = %d\n", res);
-#endif
-
- return res;
-} /* PolyhedronLTQ */
-
-/* GaussSimplify --
- Given Mat1, a matrix of equalities, performs Gaussian elimination.
- Find a minimum basis, Returns the rank.
- Mat1 is context, Mat2 is reduced in context of Mat1
-*/
-int GaussSimplify(Matrix *Mat1,Matrix *Mat2) {
-
- int NbRows = Mat1->NbRows;
- int NbCols = Mat1->NbColumns;
- int *column_index;
- int i, j, k, n, t, pivot, Rank;
- Value gcd, tmp, *cp;
-
- column_index=(int *)malloc(NbCols * sizeof(int));
- if (!column_index) {
- errormsg1("GaussSimplify", "outofmem", "out of memory space\n");
- Pol_status = 1;
- return 0;
- }
-
- /* Initialize all the 'Value' variables */
- value_init(gcd); value_init(tmp);
-
- Rank=0;
- for (j=0; j<NbCols; j++) { /* for each column starting at */
- for (i=Rank; i<NbRows; i++) /* diagonal, look down to find */
- if (value_notzero_p(Mat1->p[i][j])) /* the first non-zero entry */
- break;
- if (i!=NbRows) { /* was one found ? */
- if (i!=Rank) /* was it found below the diagonal?*/
- Vector_Exchange(Mat1->p[Rank],Mat1->p[i],NbCols);
-
- /* Normalize the pivot row */
- Vector_Gcd(Mat1->p[Rank],NbCols,&gcd);
-
- /* If (gcd >= 2) */
- value_set_si(tmp,2);
- if (value_ge(gcd,tmp)) {
- cp = Mat1->p[Rank];
- for (k=0; k<NbCols; k++,cp++)
- value_division(*cp,*cp,gcd);
- }
- if (value_neg_p(Mat1->p[Rank][j])) {
- cp = Mat1->p[Rank];
- for (k=0; k<NbCols; k++,cp++)
- value_oppose(*cp,*cp);
- }
- /* End of normalize */
- pivot=i;
- for (i=0;i<NbRows;i++) /* Zero out the rest of the column */
- if (i!=Rank) {
- if (value_notzero_p(Mat1->p[i][j])) {
- Value a, a1, a2, a1abs, a2abs;
- value_init(a); value_init(a1); value_init(a2);
- value_init(a1abs); value_init(a2abs);
- value_assign(a1,Mat1->p[i][j]);
- value_absolute(a1abs,a1);
- value_assign(a2,Mat1->p[Rank][j]);
- value_absolute(a2abs,a2);
- value_gcd(a, a1abs, a2abs);
- value_divexact(a1, a1, a);
- value_divexact(a2, a2, a);
- value_oppose(a1,a1);
- Vector_Combine(Mat1->p[i],Mat1->p[Rank],Mat1->p[i],a2,
- a1,NbCols);
- Vector_Normalize(Mat1->p[i],NbCols);
- value_clear(a); value_clear(a1); value_clear(a2);
- value_clear(a1abs); value_clear(a2abs);
- }
- }
- column_index[Rank]=j;
- Rank++;
- }
- } /* end of Gauss elimination */
-
-
- if (Mat2) { /* Mat2 is a transformation matrix (i,j->f(i,j))....
- can't scale it because can't scale both sides of -> */
- /* normalizes an affine transformation */
- /* priority of forms */
- /* 1. i' -> i (identity) */
- /* 2. i' -> i + constant (uniform) */
- /* 3. i' -> constant (broadcast) */
- /* 4. i' -> j (permutation) */
- /* 5. i' -> j + constant ( ) */
- /* 6. i' -> i + j + constant (non-uniform) */
- for (k=0; k<Rank; k++) {
- j = column_index[k];
- for (i=0; i<(Mat2->NbRows-1);i++) { /* all but the last row 0...0 1 */
- if ((i!=j) && value_notzero_p(Mat2->p[i][j])) {
-
- /* Remove dependency of i' on j */
- Value a, a1, a1abs, a2, a2abs;
- value_init(a); value_init(a1); value_init(a2);
- value_init(a1abs); value_init(a2abs);
- value_assign(a1,Mat2->p[i][j]);
- value_absolute(a1abs,a1);
- value_assign(a2,Mat1->p[k][j]);
- value_absolute(a2abs,a2);
- value_gcd(a, a1abs, a2abs);
- value_divexact(a1, a1, a);
- value_divexact(a2, a2, a);
- value_oppose(a1,a1);
- if (value_one_p(a2)) {
- Vector_Combine(Mat2->p[i],Mat1->p[k],Mat2->p[i],a2,
- a1,NbCols);
-
- /* Vector_Normalize(Mat2->p[i],NbCols); -- can't do T */
- } /* otherwise, can't do it without mult lhs prod (2i,3j->...) */
- value_clear(a); value_clear(a1); value_clear(a2);
- value_clear(a1abs); value_clear(a2abs);
-
- }
- else if ((i==j) && value_zero_p(Mat2->p[i][j])) {
-
- /* 'i' does not depend on j */
- for (n=j+1; n < (NbCols-1); n++) {
- if (value_notzero_p(Mat2->p[i][n])) { /* i' depends on some n */
- value_set_si(tmp,1);
- Vector_Combine(Mat2->p[i],Mat1->p[k],Mat2->p[i],tmp,
- tmp,NbCols);
- break;
- } /* if 'i' depends on just a constant, then leave it alone.*/
- }
- }
- }
- }
-
- /* Check last row of transformation Mat2 */
- for (j=0; j<(NbCols-1); j++)
- if (value_notzero_p(Mat2->p[Mat2->NbRows-1][j])) {
- errormsg1("GaussSimplify", "corrtrans", "Corrupted transformation\n");
- break;
- }
-
- if (value_notone_p(Mat2->p[Mat2->NbRows-1][NbCols-1])) {
- errormsg1("GaussSimplify", "corrtrans", "Corrupted transformation\n");
- }
- }
- value_clear(gcd); value_clear(tmp);
- free(column_index);
- return Rank;
-} /* GaussSimplify */
-
-/*
- * Topologically sort 'n' polyhdera and return 0 on failure, otherwise return
- * 1 on success. Here 'L' is a an array of pointers to polyhedra, 'n' is the
- * number of polyhedra, 'index' is the level to consider for partial ordering
- * 'pdim' is the parameter space dimension, 'time' is an array of 'n' integers
- * to store logical time values, 'pvect', if not NULL, is an array of 'n'
- * integers that contains a permutation specification after call and MAXRAYS is
- * the workspace size for polyhedra operations.
- */
-int PolyhedronTSort (Polyhedron **L,unsigned int n,unsigned int index,unsigned int pdim,int *time,int *pvect,unsigned int MAXRAYS) {
-
- unsigned int const nbcells = ((n*(n-1))>>1); /* Number of memory cells
- to allocate, see below */
- int *dag; /* The upper triangular matrix */
- int **p; /* Array of matrix row addresses */
- unsigned int i, j, k;
- unsigned int t, nb, isroot;
-
- if (n<2) return 0;
-
- /* we need an upper triangular matrix (example with n=4):
-
- . o o o
- . . o o . are unuseful cells, o are useful cells
- . . . o
- . . . .
-
- so we need to allocate (n)(n-1)/2 cells
- - dag will point to this memory.
- - p[i] will point to row i of the matrix
- p[0] = dag - 1 (such that p[0][1] == dag[0])
- p[1] = dag - 1 + (n-1)
- p[2] = dag - 1 + (n-1) + (n-2)
- ...
- p[i] = p[i-1] + (n-1-i)
- */
-
- /* malloc n(n-1)/2 for dag and n-1 for p (node n does not have any row) */
- dag = (int *) malloc(nbcells*sizeof(int));
- if (!dag) return 0;
- p = (int **) malloc ((n-1) * sizeof(int *));
- if (!p) {
- free(dag); return 0;
- }
-
- /* Initialize 'p' and 'dag' */
- p[0] = dag-1;
- for (i=1; i<n-1; i++)
- p[i] = p[i-1] + (n-1)-i;
- for (i=0; i<nbcells; i++)
- dag[i] = -2; /* -2 means 'not computed yet' */
- for (i=0; i<n; i++) time[i] = -1;
-
- /* Compute the dag using transitivity to reduce the number of */
- /* PolyhedronLTQ calls. */
- for (i=0; i<n-1; i++) {
- POL_ENSURE_FACETS(L[i]);
- POL_ENSURE_VERTICES(L[i]);
- for (j=i+1; j<n; j++) {
- if (p[i][j] == -2) /* not computed yes */
- p[i][j] = PolyhedronLTQ(L[i], L[j], index, pdim, MAXRAYS);
- if (p[i][j] != 0) {
-
- /* if p[i][j] is 1 or -1, look for -p[i][j] on the same row:
- p[i][j] == -p[i][k] ==> p[j][k] = p[i][k] (transitivity)
- note: p[r][c] == -p[c][r], use this to avoid reading or writing
- under the matrix diagonal
- */
-
- /* first, k<i so look for p[i][j] == p[k][i] (i.e. -p[i][k]) */
- for (k=0; k<i; k++)
- if (p[k][i] == p[i][j]) p[k][j] = p[k][i];
-
- /* then, i<k<j so look for p[i][j] == -p[i][k] */
- for (k=i+1; k<j; k++)
- if (p[i][k] == -p[i][j]) p[k][j] = -p[i][k];
-
- /* last, k>j same search but */
- for (k=j+1; k<n; k++)
- if (p[i][k] == -p[i][j]) p[j][k] = p[i][k];
- }
- }
- }
-
- /* walk thru the dag to compute the partial order (and optionally
- the permutation)
- Note: this is not the fastest way to do it but it takes
- negligible time compared to a single call of PolyhedronLTQ !
- Each macro-step (while loop) gives the same logical time to all
- found roots and optionally add these nodes in the permutation vector
- */
-
- t = 0; /* current logical time, assigned to current roots and
- increased by 1 at the end of each step */
- nb = 0; /* number of processed nodes (have been given a time) */
- while (nb<n) {
- for (i=0; i<n; i++) { /* search for roots */
- /* for any node, if it's not already been given a logical time
- then walk thru the node row; if we find a 1 at some column j,
- it means that node j preceeds the current node, so it is not
- a root */
- if (time[i]<0) {
- isroot = 1; /* assume that it is until it is definitely not */
- /* first search on a column */
- for (j=0; j<i; j++) {
- if (p[j][i]==-1) { /* found a node lower than it */
- isroot = 0; break;
- }
- }
- if /*still*/ (isroot)
- for (j=i+1; j<n; j++) {
- if (p[i][j]==1) { /* greater than this node */
- isroot = 0; break;
- }
- }
- if (isroot) { /* then it definitely is */
- time[i] = t; /* this node gets current logical time */
- if (pvect)
- pvect[nb] = i+1; /* nodes will be numbered from 1 to n */
- nb++; /* one more node processed */
- }
- }
- }
- /* now make roots become neutral, i.e. non comparable with all other nodes */
- for (i=0; i<n; i++) {
- if (time[i]==t) {
- for (j=0; j<i; j++)
- p[j][i] = 0;
- for (j=i+1; j<n; j++)
- p[i][j] = 0;
- }
- }
- t++; /* ready for next set of root nodes */
- }
-
- free (p); /* let's be clean, collect the garbage */
- free (dag);
- return 1;
-} /* PolyhedronTSort */
-
-
-
-
diff --git a/source/polylib_mod/arithmetic_errors.h b/source/polylib_mod/arithmetic_errors.h
deleted file mode 100644
index 1e9e08d..0000000
--- a/source/polylib_mod/arithmetic_errors.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * $Id: arithmetic_errors.h,v 1.4 2006/03/15 19:59:37 verdoolaege Exp $
- *
- * managing arithmetic errors...
- * detecting and managing arithmetic errors on Values should be
- * systematic. These macros gives a C++ look and feel to this
- * management.
- *
- * (c) CA et FC, Sept 1997
- *
- * $Log: arithmetic_errors.h,v $
- * Revision 1.4 2006/03/15 19:59:37 verdoolaege
- * arith: add some missing consts
- *
- * Revision 1.3 2004/02/08 21:53:27 kienhuis
- * Update from Fabien Coelho, via Bart Kienhuis
- *
- * I've updated here in the C3/Linear library the arithmetic_error
- * package that I developped (with others) to handle exceptions in C.
- * It adds a simple callback feature which is needed for pips here.
- * If you do not use it, it should not harm;-)
- *
- * Revision 1.34 2003/09/03 13:59:46 coelho
- * ++
- *
- * Revision 1.33 2003/09/03 13:35:34 coelho
- * no more callback.
- *
- * Revision 1.32 2003/08/18 14:55:38 coelho
- * callback fix.
- *
- * Revision 1.31 2003/08/18 14:16:45 coelho
- * NULL callback added.
- *
- * Revision 1.30 2003/06/13 13:59:55 coelho
- * hop.
- *
- * Revision 1.29 2000/07/27 15:01:55 coelho
- * hop.
- *
- * Revision 1.28 2000/07/26 09:11:58 coelho
- * hop.
- *
- * Revision 1.27 2000/07/26 09:07:32 coelho
- * *** empty log message ***
- *
- * Revision 1.26 2000/07/26 09:06:32 coelho
- * the_last_just_thrown_exception declared.
- *
- * Revision 1.25 2000/07/26 08:41:40 coelho
- * RETHROW added.
- *
- * Revision 1.24 1998/10/26 14:37:48 coelho
- * constants moved out.
- *
- * Revision 1.23 1998/10/26 14:36:13 coelho
- * constants explicitely defined in .h.
- *
- * Revision 1.22 1998/10/24 15:18:26 coelho
- * THROW macro updated to tell its source.
- *
- * Revision 1.21 1998/10/24 14:33:08 coelho
- * parser exception added.
- *
- * Revision 1.20 1998/10/24 14:32:45 coelho
- * simpler macros.
- *
- * Revision 1.19 1998/10/24 09:22:47 coelho
- * size update.
- *
- * Revision 1.18 1998/10/24 09:21:45 coelho
- * const added to constants.
- *
- */
-
-#if !defined(linear_arithmetic_error_included)
-#define linear_arithmetic_error_included
-
-#include <setjmp.h>
-
-typedef void (*exception_callback_t)(const char *, const char *, int);
-
-/*
-const unsigned int overflow_error = 1;
-const unsigned int simplex_arithmetic_error = 2;
-const unsigned int user_exception_error = 4;
-const unsigned int parser_exception_error = 8;
-const unsigned int any_exception_error = ~0;
-*/
-
-/* use gnu cpp '__FUNCTION__' extension if possible.
- */
-#if defined(__GNUC__)
-#define __CURRENT_FUNCTION_NAME__ __FUNCTION__
-#else
-#define __CURRENT_FUNCTION_NAME__ "<unknown>"
-#endif
-
-/* 'const' out because of cproto 4.6. FC 13/06/2003 */
-#define EXCEPTION extern unsigned int
-
-#define THROW(what) \
- (throw_exception(what, __CURRENT_FUNCTION_NAME__, __FILE__, __LINE__))
-
-#define CATCH(what) \
- if (setjmp(*push_exception_on_stack(what, __CURRENT_FUNCTION_NAME__, \
- __FILE__, __LINE__)))
-
-#define UNCATCH(what) \
- (pop_exception_from_stack(what, __CURRENT_FUNCTION_NAME__, \
- __FILE__, __LINE__))
-
-#define TRY else
-
-extern unsigned int the_last_just_thrown_exception;
-#define RETHROW() THROW(the_last_just_thrown_exception)
-
-#endif /* linear_arithmetic_error_included */
-
-/* end of it.
- */
diff --git a/source/polylib_mod/arithmetique.h b/source/polylib_mod/arithmetique.h
deleted file mode 100644
index 0c706c6..0000000
--- a/source/polylib_mod/arithmetique.h
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* header file built by cproto */
-#ifndef arithmetique_header_included
-#define arithmetique_header_included
-
-/** package arithmetique
- *
- * $Id: arithmetique.h,v 1.24 2007/02/22 09:16:57 skimo Exp $
- *
- * Francois Irigoin, mai 1989
- *
- * Modifications
- * - rewrite of DIVIDE which was wrong (Remi Triolet, Francois Irigoin,
- * april 90)
- * - simplification of POSITIVE_DIVIDE by suppressing one modulo
- * - B.Meister : added addmul, operation existing in gmp and quite useful
- * (05-2005)
- */
-
-/* We would like linear to be generic about the "integer" type used
- * to represent integer values. Thus Value is defined here. It should
- * be changed to "int" "long" or "long long". In an ideal world,
- * any source modification should be limited to this package.
- *
- * Indeed, we cannot switch easily to bignums that need constructors
- * dans destructors... That would lead to too many modifications...
- * C++ would make things easier and cleaner...
- *
- * Fabien COELHO
- */
-
-#include <stdio.h>
-#include <limits.h> /* Included for getting constants: INT_MAX, etc.. */
-
-#ifdef GNUMP
-#include <gmp.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef mp_get_memory_functions
-#if defined(__cplusplus)
-extern "C" {
-#endif
-void mp_get_memory_functions(
- void *(**alloc_func_ptr) (size_t),
- void *(**realloc_func_ptr) (void *, size_t, size_t),
- void (**free_func_ptr) (void *, size_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif
-#endif
-
-#ifdef CLN
-#include <sstream>
-#define WANT_OBFUSCATING_OPERATORS
-#include <cln/cln.h>
-#endif
-
-/*
- # #### # # #### # #### # # ####
- # # # ## # # # # # # ## # # #
- # # # # # # # # # # # # # #
- # # # # # # # ### # # # # # # # ###
- # # # # ## # # # # # # ## # #
- ###### #### # # #### ###### #### # # ####
-
-*/
-
-/*
- * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
- * defined here.
- */
-
-#ifndef LONG_LONG_MAX
-
-/* would fix on solaris:
- * #define LONG_LONG_MAX LLONG_MAX
- * #define LONG_LONG_MIN LLONG_MIN
- */
-
-#ifndef __LONG_LONG_MAX__
-#define __LONG_LONG_MAX__ 9223372036854775807LL
-#endif
-#undef LONG_LONG_MAX
-#define LONG_LONG_MAX __LONG_LONG_MAX__
-#undef LONG_LONG_MIN
-#define LONG_LONG_MIN (-LONG_LONG_MAX-1)
-#undef ULONG_LONG_MAX
-#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
-#endif
-
-#if defined(LINEAR_VALUE_IS_LONGLONG)
-
-#define LINEAR_VALUE_STRING "long long int"
-typedef long long int Value;
-#if defined(WIN32) && !defined(unix)
- /* Mingw or Windows need an incompatible format string. */
-# define VALUE_FMT "%I64d"
-#else
-# define VALUE_FMT "%lld"
-#endif
-#define VALUE_CONST(val) (val##LL)
-
-/*
- * CAUTION! 'VALUE_MIN' is defined as 'LONG_LONG_MIN +1' so as to preserve the
- * symmetry (-min==max) and to have a NAN value. FC
- */
-
-#define VALUE_NAN LONG_LONG_MIN
-#define VALUE_MIN (LONG_LONG_MIN+1LL)
-#define VALUE_MAX LONG_LONG_MAX
-#define VALUE_SQRT_MIN long_to_value(LONG_MIN)
-#define VALUE_SQRT_MAX long_to_value(LONG_MAX)
-#define VALUE_ZERO (0LL)
-#define VALUE_ONE (1LL)
-#define VALUE_MONE (-1LL)
-
-#define VALUE_TO_LONG(val) \
- ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
- (val):(THROW(overflow_error), LONG_MIN))
-
-#define VALUE_TO_INT(val) \
- ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
- (val):(THROW(overflow_error), INT_MIN))
-
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-/* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
-#define VALUE_TO_FLOAT(val) ((float)((int)(val)))
-
-/* end LINEAR_VALUE_IS_LONGLONG */
-
-/*
-
- # #### # # ####
- # # # ## # # #
- # # # # # # #
- # # # # # # # ###
- # # # # ## # #
- ###### #### # # ####
-
-*/
-
-#elif defined(LINEAR_VALUE_IS_LONG)
-
-#define LINEAR_VALUE_STRING "long int"
-typedef long Value;
-#define VALUE_FMT "%ld"
-#define VALUE_CONST(val) (val##L)
-#define VALUE_NAN LONG_MIN
-#define VALUE_MIN (LONG_MIN+1L)
-#define VALUE_MAX LONG_MAX
-#define VALUE_SQRT_MIN int_to_value(INT_MIN)
-#define VALUE_SQRT_MAX int_to_value(INT_MAX)
-#define VALUE_ZERO 0L
-#define VALUE_ONE 1L
-#define VALUE_MONE -1L
-#define VALUE_TO_LONG(val) (val)
-#define VALUE_TO_INT(val) ((int)(val))
-#define VALUE_TO_FLOAT(val) ((float)(val))
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-/* end LINEAR_VALUE_IS_LONG */
-
-/*
- ###### # #### ## #####
- # # # # # # #
- ##### # # # # # #
- # # # # ###### #
- # # # # # # #
- # ###### #### # # #
-
-*/
-
-/*
-#elif defined(LINEAR_VALUE_IS_FLOAT)
-
-#define LINEAR_VALUE_STRING "float"
-typedef float Value;
-#define VALUE_FMT "%f"
-#define VALUE_CONST(val) (val)
-#define VALUE_MIN FLOAT_MIN
-#define VALUE_MAX FLOAT_MAX
-#define VALUE_ZERO 0.0
-#define VALUE_ONE 1.0
-#define VALUE_MONE -1.0
-#define VALUE_TO_LONG(val) ((long)(val))
-#define VALUE_TO_INT(val) ((int)(val))
-#define VALUE_TO_FLOAT(val) ((float)(val))
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-*/
-
-/* end LINEAR_VALUE_IS_FLOAT */
-
-/*
- #### # # ## ##### # #
- # # # # # # # # # #
- # ###### # # # # #######
- # # # ###### ##### # #
- # # # # # # # # # #
- #### # # # # # #
-
- */
-
-/* Char version is used to detect invalid assignments */
-
-#elif defined(LINEAR_VALUE_IS_CHARS)
-
-#define LINEAR_VALUE_STRING "char"
-typedef union { char *s; long l; int i; float f; double d;} Value;
-#define VALUE_FMT "%s"
-#define VALUE_CONST(val) ((Value)(val))
-#define VALUE_NAN ((Value)(long)0xdadeebee)
-#define VALUE_MIN ((Value)(long)0xdeadbeef)
-#define VALUE_MAX ((Value)(long)0xfeedabee)
-#define VALUE_ZERO ((Value)0)
-#define VALUE_ONE ((Value)1)
-#define VALUE_MONE ((Value)-1)
-#define VALUE_TO_LONG(val) (val.l)
-#define VALUE_TO_INT(val) (val.i)
-#define VALUE_TO_FLOAT(val) (val.f)
-#define VALUE_TO_DOUBLE(val) (val.d)
-
-/* end LINEAR_VALUE_IS_CHARS */
-
-/*
- # # # #####
- # ## # #
- # # # # #
- # # # # #
- # # ## #
- # # # #
-
-*/
-
-#elif defined(LINEAR_VALUE_IS_INT)
-
-#define LINEAR_VALUE_STRING "int"
-typedef int Value;
-#define VALUE_FMT "%d"
-#define VALUE_CONST(val) (val)
-#define VALUE_NAN INT_MIN
-#define VALUE_MIN (INT_MIN+1)
-#define VALUE_MAX INT_MAX
-#define VALUE_ZERO 0
-#define VALUE_ONE 1
-#define VALUE_MONE -1
-#define VALUE_TO_LONG(val) ((long)(val))
-#define VALUE_TO_INT(val) ((int)(val))
-#define VALUE_TO_FLOAT(val) ((float)(val))
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-/* end LINEAR_VALUE_IS_INT */
-
-#elif defined(GNUMP)
-
-#define LINEAR_VALUE_STRING "gmp"
-typedef mpz_t Value;
-#define VALUE_FMT "%s"
-
-/* don't use these, use value_set_si instead ! */
-#undef VALUE_ZERO
-#undef VALUE_ONE
-#undef VALUE_MONE
-#define VALUE_TO_LONG(val) (mpz_get_si(val))
-#define VALUE_TO_INT(val) ((int)mpz_get_si(val))
-#define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
-#define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
-
-#elif defined(CLN)
-
-#define LINEAR_VALUE_STRING "cln"
-typedef cln::cl_I Value;
-#define VALUE_FMT "%s"
-
-#define VALUE_TO_INT(val) (cln::cl_I_to_int(val))
-#define VALUE_TO_DOUBLE(val) (cln::double_approx(val))
-
-#endif
-
-/* ***************** MACROS FOR MANIPULATING VALUES ******************** */
-
-#if defined(CLN)
-
-#define value_init(val) ((val).word = ((cln::cl_uint)cl_FN_tag) << cl_tag_shift)
-#define value_assign(v1,v2) ((v1) = (v2))
-#define value_set_si(val,i) ((val) = (i))
-#define value_set_double(val,d) ((val) = cln::truncate1(cln::cl_R(d)))
-#define value_clear(val) ((val) = 0)
-#define value_read(val,str) ((val) = (str))
-#define value_print(Dst,fmt,val) {std::ostringstream strm; strm << val; \
- fprintf((Dst),(fmt),strm.str().c_str()); \
- }
-#define value_swap(v1,v2) {Value tmp; tmp = v2; \
- v2 = v1; v1 = tmp; \
- }
-
-/* Boolean operators on 'Value' */
-
-#define value_eq(v1,v2) ((v1)==(v2))
-#define value_ne(v1,v2) ((v1)!=(v2))
-#define value_gt(v1,v2) ((v1)>(v2))
-#define value_ge(v1,v2) ((v1)>=(v2))
-#define value_lt(v1,v2) ((v1)<(v2))
-#define value_le(v1,v2) ((v1)<=(v2))
-
-#define value_abs_eq(v1,v2) (cln::abs(v1)==cln::abs(v2))
-#define value_abs_ne(v1,v2) (cln::abs(v1)!=cln::abs(v2))
-#define value_abs_gt(v1,v2) (cln::abs(v1)>cln::abs(v2))
-#define value_abs_ge(v1,v2) (cln::abs(v1)>=cln::abs(v2))
-#define value_abs_lt(v1,v2) (cln::abs(v1)<cln::abs(v2))
-#define value_abs_le(v1,v2) (cln::abs(v1)<=cln::abs(v2))
-
-#define value_sign(val) (cln::signum(val))
-#define value_compare(v1,v2) (cln::compare((v1),(v2)))
-
-#define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
-#define value_add_int(ref,val,vint) ((ref) = (val)+(vint))
-#define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
-#define value_increment(ref,val) ((ref) = (val)+1)
-#define value_multiply(ref,val1,val2) ((ref) = (val1)*(val2))
-#define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
-#define value_sub_int(ref,val1,val2) ((ref) = (val1)-(val2))
-#define value_decrement(ref,val) ((ref) = (val)-1)
-#define value_division(ref,val1,val2) ((ref) = cln::truncate1(val1,val2))
-#define value_divexact(ref,val1,val2) ((ref) = cln::exquo(val1,val2))
-#define value_modulus(ref,val1,val2) ((ref) = cln::truncate2(val1,val2).remainder)
-#define value_pdivision(ref,val1,val2) ((ref) = cln::floor1(val1,val2))
-#define value_pmodulus(ref,val1,val2) ((ref) = cln::floor2(val1,val2).remainder)
-#define value_oppose(ref,val) ((ref) = -(val))
-#define value_absolute(ref,val) ((ref) = cln::abs(val))
-#define value_minimum(ref,val1,val2) ((ref) = cln::min((val1),(val2)))
-#define value_maximum(ref,val1,val2) ((ref) = cln::max((val1),(val2)))
-#define value_gcd(ref,val1,val2) ((ref) = cln::gcd((val1),(val2)))
-#define value_lcm(ref,val1,val2) ((ref) = cln::lcm((val1),(val2)))
-#define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
-#define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
-
-/* Conditional operations on 'Value' */
-
-#define value_pos_p(val) ((val) > 0)
-#define value_neg_p(val) ((val) < 0)
-#define value_posz_p(val) ((val) >= 0)
-#define value_negz_p(val) ((val) <= 0)
-#define value_zero_p(val) ((val) == 0)
-#define value_notzero_p(val) ((val) != 0)
-#define value_one_p(val) ((val) == 1)
-#define value_notone_p(val) ((val) != 1)
-#define value_mone_p(val) ((val) == -1)
-#define value_notmone_p(val) ((val) != -1)
-#define value_cmp_si(val, n) (cln::compare(val,n))
-
-#elif defined(GNUMP)
-
-/* Basic macros */
-
-#define value_init(val) (mpz_init((val)))
-#define value_assign(v1,v2) (mpz_set((v1),(v2)))
-#define value_set_si(val,i) (mpz_set_si((val),(i)))
-#define value_set_double(val,d)(mpz_set_d((val),(d)))
-#define value_clear(val) (mpz_clear((val)))
-#define value_read(val,str) (mpz_set_str((val),(str),10))
-typedef void (*value_print_gmp_free_t)(void *, size_t);
-#define value_print(Dst,fmt,val) {char *str; \
- value_print_gmp_free_t gmp_free; \
- str = mpz_get_str(0,10,(val)); \
- fprintf((Dst),(fmt),str); \
- mp_get_memory_functions(NULL, NULL, &gmp_free); \
- (*gmp_free) (str, strlen(str)+1); \
- }
-#define value_swap(val1,val2) (mpz_swap(val1, val2))
-
-/* Boolean operators on 'Value' */
-
-#define value_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
-#define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
-#define value_gt(v1,v2) (mpz_cmp((v1),(v2)) > 0)
-#define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
-#define value_lt(v1,v2) (mpz_cmp((v1),(v2)) < 0)
-#define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
-
-#define value_abs_eq(v1,v2) (mpz_cmpabs((v1),(v2)) == 0)
-#define value_abs_ne(v1,v2) (mpz_cmpabs((v1),(v2)) != 0)
-#define value_abs_gt(v1,v2) (mpz_cmpabs((v1),(v2)) > 0)
-#define value_abs_ge(v1,v2) (mpz_cmpabs((v1),(v2)) >= 0)
-#define value_abs_lt(v1,v2) (mpz_cmpabs((v1),(v2)) < 0)
-#define value_abs_le(v1,v2) (mpz_cmpabs((v1),(v2)) <= 0)
-
-/* Trian operators on 'Value' */
-
-#define value_sign(val) (mpz_sgn(val))
-#define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
-
-/* Binary operations on 'Value' */
-
-#define value_addto(ref,val1,val2) (mpz_add((ref),(val1),(val2)))
-#define value_add_int(ref,val,vint) (mpz_add_ui((ref),(val),(long)(vint)))
-#define value_addmul(ref, val1, val2) (mpz_addmul((ref), (val1), (val2)))
-#define value_increment(ref,val) (mpz_add_ui((ref),(val),1))
-#define value_multiply(ref,val1,val2) (mpz_mul((ref),(val1),(val2)))
-#define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
-#define value_sub_int(ref,val,vint) (mpz_sub_ui((ref),(val),(long)(vint)))
-#define value_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
-#define value_division(ref,val1,val2) (mpz_tdiv_q((ref),(val1),(val2)))
-#define value_divexact(ref,val1,val2) (mpz_divexact((ref),(val1),(val2)))
-#define value_modulus(ref,val1,val2) (mpz_tdiv_r((ref),(val1),(val2)))
-#define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
-#define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2)))
-#define value_oppose(ref,val) (mpz_neg((ref),(val)))
-#define value_absolute(ref,val) (mpz_abs((ref),(val)))
-#define value_minimum(ref,val1,val2) (value_le((val1),(val2)) ? \
- mpz_set((ref),(val1)) : \
- mpz_set((ref),(val2)))
-#define value_maximum(ref,val1,val2) (value_ge((val1),(val2)) ? \
- mpz_set((ref),(val1)) : \
- mpz_set((ref),(val2)))
-#define value_gcd(ref,val1,val2) (mpz_gcd(ref,val1,val2))
-#define value_lcm(ref,val1,val2) (mpz_lcm(ref,val1,val2))
-#define value_orto(ref,val1,val2) (mpz_ior((ref),(val1),(val2)))
-#define value_andto(ref,val1,val2) (mpz_and((ref),(val1),(val2)))
-
-/* Conditional operations on 'Value' */
-
-#define value_pos_p(val) (mpz_sgn(val) > 0)
-#define value_neg_p(val) (mpz_sgn(val) < 0)
-#define value_posz_p(val) (mpz_sgn(val) >= 0)
-#define value_negz_p(val) (mpz_sgn(val) <= 0)
-#define value_zero_p(val) (mpz_sgn(val) == 0)
-#define value_notzero_p(val) (mpz_sgn(val) != 0)
-#define value_one_p(val) (mpz_cmp_si(val,1) == 0)
-#define value_notone_p(val) (mpz_cmp_si(val,1) != 0)
-#define value_mone_p(val) (mpz_cmp_si(val,-1) ==0)
-#define value_notmone_p(val) (mpz_cmp_si(val,-1) !=0)
-#define value_cmp_si(val, n) (mpz_cmp_si(val,n))
-
-/* ************************************************************************* */
-
-#else /* 'Value' set to longlong|long|float|char *|int */
-/* Basic Macros */
-
-#define value_init(val) ((val) = 0)
-#define value_assign(v1,v2) ((v1) = (v2))
-#define value_set_si(val,i) ((val) = (Value)(i))
-#define value_set_double(val,d) ((val) = (Value)(d))
-#define value_clear(val) ((val) = 0)
-#define value_read(val,str) (sscanf((str),VALUE_FMT,&(val)))
-#define value_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
-#define value_swap(v1,v2) {Value tmp; tmp = v2; \
- v2 = v1; v1 = tmp; \
- }
-/* Cast to 'Value' */
-
-#define int_to_value(i) ((Value)(i))
-#define long_to_value(l) ((Value)(l))
-#define float_to_value(f) ((Value)(f))
-#define double_to_value(d) ((Value)(d))
-
-/* Boolean operators on 'Value' */
-
-#define value_eq(v1,v2) ((v1)==(v2))
-#define value_ne(v1,v2) ((v1)!=(v2))
-#define value_gt(v1,v2) ((v1)>(v2))
-#define value_ge(v1,v2) ((v1)>=(v2))
-#define value_lt(v1,v2) ((v1)<(v2))
-#define value_le(v1,v2) ((v1)<=(v2))
-
-#define value_abs_eq(v1,v2) (value_abs(v1)==value_abs(v2))
-#define value_abs_ne(v1,v2) (value_abs(v1)!=value_abs(v2))
-#define value_abs_gt(v1,v2) (value_abs(v1)>value_abs(v2))
-#define value_abs_ge(v1,v2) (value_abs(v1)>=value_abs(v2))
-#define value_abs_lt(v1,v2) (value_abs(v1)<value_abs(v2))
-#define value_abs_le(v1,v2) (value_abs(v1)<=value_abs(v2))
-
-/* Trian operators on 'Value' */
-
-#define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
-#define value_compare(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
-
-/* Binary operators on 'Value' */
-
-#define value_plus(v1,v2) ((v1)+(v2))
-#define value_div(v1,v2) ((v1)/(v2))
-#define value_mod(v1,v2) ((v1)%(v2))
-#define value_direct_multiply(v1,v2) ((v1)*(v2)) /* direct! */
-#define value_minus(v1,v2) ((v1)-(v2))
-#define value_pdiv(v1,v2) (DIVIDE((v1),(v2)))
-#define value_pmod(v1,v2) (MODULO((v1),(v2)))
-#define value_min(v1,v2) (value_le((v1),(v2))? (v1): (v2))
-#define value_max(v1,v2) (value_ge((v1),(v2))? (v1): (v2))
-#define value_or(v1,v2) ((v1)|(v2))
-#define value_and(v1,v2) ((v1)&(v2))
-#define value_lshift(v1,v2) ((v1)<<(v2))
-#define value_rshift(v1,v2) ((v1)>>(v2))
-
-/* Binary operations on 'Value' */
-
-#define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
-#define value_add_int(ref,val,vint) ((ref) = (val)+(Value)(vint))
-#define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
-#define value_increment(ref,val) ((ref) = (val)+VALUE_ONE)
-#define value_direct_product(ref,val1,val2) ((ref) = (val1)*(val2)) /* direct! */
-#define value_multiply(ref,val1,val2) ((ref) = value_mult((val1),(val2)))
-#define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
-#define value_sub_int(ref,val,vint) ((ref) = (val)-(Value)(vint))
-#define value_decrement(ref,val) ((ref) = (val)-VALUE_ONE)
-#define value_division(ref,val1,val2) ((ref) = (val1)/(val2))
-#define value_divexact(ref,val1,val2) ((ref) = (val1)/(val2))
-#define value_modulus(ref,val1,val2) ((ref) = (val1)%(val2))
-#define value_pdivision(ref,val1,val2) ((ref) = value_pdiv((val1),(val2)))
-#define value_pmodulus(ref,val1,val2) ((ref) = value_pmod((val1),(val2)))
-#define value_oppose(ref,val) ((ref) = value_uminus((val)))
-#define value_absolute(ref,val) ((ref) = value_abs((val)))
-#define value_minimum(ref,val1,val2) ((ref) = value_min((val1),(val2)))
-#define value_maximum(ref,val1,val2) ((ref) = value_max((val1),(val2)))
-#define value_gcd(ref,val1,val2) Gcd((val1),(val2),&(ref))
-#define value_lcm(ref,val1,val2) Lcm3((val1),(val2),&(ref))
-#define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
-#define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
-
-/* Unary operators on 'Value' */
-
-#define value_uminus(val) (-(val))
-#define value_not(val) (~(val))
-#define value_abs(val) (value_posz_p(val)? \
- (val) : \
- (value_ne((val), VALUE_NAN) ? \
- value_uminus(val) : \
- (THROW (overflow_error), VALUE_NAN )))
-
-/* Conditional operations on 'Value' */
-
-#define value_pos_p(val) value_gt(val,VALUE_ZERO)
-#define value_neg_p(val) value_lt(val,VALUE_ZERO)
-#define value_posz_p(val) value_ge(val,VALUE_ZERO)
-#define value_negz_p(val) value_le(val,VALUE_ZERO)
-#define value_zero_p(val) value_eq(val,VALUE_ZERO)
-#define value_notzero_p(val) value_ne(val,VALUE_ZERO)
-#define value_one_p(val) value_eq(val,VALUE_ONE)
-#define value_notone_p(val) value_ne(val,VALUE_ONE)
-#define value_mone_p(val) value_eq(val,VALUE_MONE)
-#define value_notmone_p(val) value_ne(val,VALUE_MONE)
-#define value_cmp_si(val, n) (val - (n))
-#define value_min_p(val) value_eq(val,VALUE_MIN)
-#define value_max_p(val) value_eq(val,VALUE_MAX)
-#define value_notmin_p(val) value_ne(val,VALUE_MIN)
-#define value_notmax_p(val) value_ne(val,VALUE_MAX)
-
-#endif /* 'Value' set to |longlong|long|float|char *|int */
-
-
-/* *********************** PROTECTED MULTIPLICATION ********************** */
-
-#include "arithmetic_errors.h"
-
-/* (|v| < MAX / |w|) => v*w is okay
- * I could check ((v*w)/w)==v but a tmp would be useful
- */
-#define value_protected_hard_idiv_multiply(v,w,throw) \
- ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO: \
- value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))? \
- value_direct_multiply(v,w): (throw, VALUE_NAN))
-
-/* is a software idiv is assumed, quick check performed first
- */
-#if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
-#define value_protected_multiply(v,w,throw) \
- ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) && \
- value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))? \
- value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
-#else
-#define value_protected_multiply(v,w,throw) \
- value_protected_hard_idiv_multiply(v,w,throw)
-#endif
-
-/* protected versions
- */
-#define value_protected_mult(v,w) \
- value_protected_multiply(v,w,THROW(overflow_error))
-#define value_protected_product(v,w) \
- v=value_protected_mult(v,w)
-
-/* whether the default is protected or not
- * this define makes no sense any more... well, doesn't matter. FC.
- */
-#if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
-#define value_mult(v,w) value_protected_mult(v,w)
-#define value_product(v,w) value_protected_product(v,w)
-#else
-
-/* I do enforce the protection whatever requested:-)
- * prints out a message and throws the exception, hoping
- * that some valid CATCH waits for it upwards.
- */
-#define value_mult(v,w) \
- value_protected_multiply(v,w, \
- (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
-#define value_product(v,w) v=value_mult(v,w)
-
-/* was:
- * #define value_mult(v,w) value_direct_multiply(v,w)
- * #define value_product(v,w) value_direct_product(v,w)
- * could be: protected versions...
- */
-#endif
-
-/******************************************************* STATIC VALUE DEBUG */
-
-/* LINEAR_VALUE_IS_CHARS is used for type checking.
- * some operations are not allowed on (char*), thus
- * they are switched to some other operation here...
- */
-#if defined(LINEAR_VALUE_IS_CHARS)
-#define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
-#define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
-#undef float_to_value
-#define float_to_value(f) ((Value)f)
-#undef double_to_value
-#define double_to_value(f) ((Value)f)
-#undef value_uminus
-#define value_uminus(v) (v)
-#undef value_mult
-#define value_mult(v1,v2) value_fake_binary(v1,v2)
-#undef value_mod
-#define value_mod(v1,v2) value_fake_binary(v1,v2)
-#undef value_ge
-#define value_ge(v1,v2) value_bool_binary(v1,v2)
-#undef value_gt
-#define value_gt(v1,v2) value_bool_binary(v1,v2)
-#undef value_le
-#define value_le(v1,v2) value_bool_binary(v1,v2)
-#undef value_lt
-#define value_lt(v1,v2) value_bool_binary(v1,v2)
-#undef value_ne
-#define value_ne(v1,v2) value_bool_binary(v1,v2)
-#undef value_eq
-#define value_eq(v1,v2) value_bool_binary(v1,v2)
-#undef value_plus
-#define value_plus(v1,v2) value_fake_binary(v1,v2)
-#undef value_minus
-#define value_minus(v1,v2) value_fake_binary(v1,v2)
-#undef value_pdiv
-#define value_pdiv(v1,v2) value_fake_binary(v1,v2)
-#undef value_div
-#define value_div(v1,v2) value_fake_binary(v1,v2)
-#undef value_mod
-#define value_mod(v1,v2) value_fake_binary(v1,v2)
-#undef value_addto
-#define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
-#undef value_subtract
-#define value_subtract(v1,v2) value_addto(v1,v2)
-#undef value_product
-#define value_product(v1,v2) value_addto(v1,v2)
-#undef value_modulus
-#define value_modulus(v1,v2) value_addto(v1,v2)
-#undef value_division
-#define value_division(v1,v2) value_addto(v1,v2)
-#undef value_divexact
-#define value_divexact(v1,v2) value_addto(v1,v2)
-#undef value_increment
-#define value_increment(v) value_addto(v,VALUE_ONE)
-#undef value_decrement
-#define value_decrement(v) value_addto(v,VALUE_MONE)
-#undef value_orto
-#define value_orto(ref,val) value_addto(v1,v2)
-#undef value_andto
-#define value_andto(ref,val) value_addto(v1,v2)
-#undef value_or
-#define value_or(v1,v2) value_fake_binary(v1,v2)
-#undef value_and
-#define value_and(v1,v2) value_fake_binary(v1,v2)
-#undef value_lshift
-#define value_lshift(v1,v2) value_fake_binary(v1,v2)
-#undef value_rshift
-#define value_rshift(v1,v2) value_fake_binary(v1,v2)
-#endif
-
-/* for backward compatibility */
-#define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
-
-/* valeur absolue
- */
-#ifndef ABS
-#define ABS(x) (((x)>=0) ? (x) : -(x))
-#endif
-
-/* minimum et maximum
- * if they are defined somewhere else, they are very likely
- * to be defined the same way. Thus the previous def is not overwritten.
- */
-#ifndef MIN
-#define MIN(x,y) (((x)>=(y))?(y):(x))
-#endif
-#ifndef MAX
-#define MAX(x,y) (((x)>=(y))?(x):(y))
-#endif
-
-/* signe d'un entier: -1, 0 ou 1 */
-#define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
-
-/* division avec reste toujours positif
- * basee sur les equations:
- * a/(-b) = - (a/b)
- * (-a)/b = - ((a+b-1)/b)
- * ou a et b sont des entiers positifs
- */
-#define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
- -POSITIVE_DIVIDE((x),(-(y))))
-
-/* division avec reste toujours positif quand y est positif: assert(y>=0) */
-#define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
-
-/* modulo a resultat toujours positif */
-#define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
-
-/* modulo par rapport a un nombre positif: assert(y>=0)
- *
- * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
- * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
- * surement pas plus cablee que la division ou la multiplication
- */
-#define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
- ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
-
-/* errors.c */
-extern unsigned int overflow_error;
-extern unsigned int simplex_arithmetic_error;
-extern unsigned int user_exception_error;
-extern unsigned int parser_exception_error;
-extern unsigned int any_exception_error;
-extern unsigned int the_last_just_thrown_exception;
-extern void dump_exception_stack_to_file(FILE * /*f*/);
-extern void dump_exception_stack(void);
-extern jmp_buf *push_exception_on_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
-extern void pop_exception_from_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
-extern void throw_exception(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
-
-#endif /* arithmetique_header_included */
-
-
-
diff --git a/source/polylib_mod/compress_parms.c b/source/polylib_mod/compress_parms.c
deleted file mode 100644
index 77f481e..0000000
--- a/source/polylib_mod/compress_parms.c
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * $Id: compress_parms.c,v 1.32 2006/11/03 17:34:26 skimo Exp $
- *
- * The integer points in a parametric linear subspace of Q^n are generally
- * lying on a sub-lattice of Z^n.
- * Functions here use and compute validity lattices, i.e. lattices induced on a
- * set of variables by such equalities involving another set of integer
- * variables.
- * @author B. Meister 12/2003-2006 meister at icps.u-strasbg.fr
- * LSIIT -ICPS
- * UMR 7005 CNRS
- * Louis Pasteur University (ULP), Strasbourg, France
-*/
-
-#include <stdlib.h>
-#include <polylib/polylib.h>
-
-/**
- * debug flags (2 levels)
- */
-#define dbgCompParm 0
-#define dbgCompParmMore 0
-
-#define dbgStart(a) if (dbgCompParmMore) { printf(" -- begin "); \
- printf(#a); \
- printf(" --\n"); } \
- while(0)
-#define dbgEnd(a) if (dbgCompParmMore) { printf(" -- end "); \
- printf(#a); \
- printf(" --\n"); } \
- while(0)
-
-
-/**
- * Given a full-row-rank nxm matrix M made of m row-vectors), computes the
- * basis K (made of n-m column-vectors) of the integer kernel of the rows of M
- * so we have: M.K = 0
-*/
-Matrix * int_ker(Matrix * M) {
- Matrix *U, *Q, *H, *H2, *K=NULL;
- int i, j, rk;
-
- if (dbgCompParm)
- show_matrix(M);
- /* eliminate redundant rows : UM = H*/
- right_hermite(M, &H, &Q, &U);
- for (rk=H->NbRows-1; (rk>=0) && Vector_IsZero(H->p[rk], H->NbColumns); rk--);
- rk++;
- if (dbgCompParmMore) {
- printf("rank = %d\n", rk);
- }
-
- /* there is a non-null kernel if and only if the dimension m of
- the space spanned by the rows
- is inferior to the number n of variables */
- if (M->NbColumns <= rk) {
- Matrix_Free(H);
- Matrix_Free(Q);
- Matrix_Free(U);
- K = Matrix_Alloc(M->NbColumns, 0);
- return K;
- }
- Matrix_Free(U);
- Matrix_Free(Q);
- /* fool left_hermite by giving NbRows =rank of M*/
- H->NbRows=rk;
- /* computes MU = [H 0] */
- left_hermite(H, &H2, &Q, &U);
- if (dbgCompParmMore) {
- printf("-- Int. Kernel -- \n");
- show_matrix(M);
- printf(" = \n");
- show_matrix(H2);
- show_matrix(U);
- }
- H->NbRows==M->NbRows;
- Matrix_Free(H);
- /* the Integer Kernel is made of the last n-rk columns of U */
- Matrix_subMatrix(U, 0, rk, U->NbRows, U->NbColumns, &K);
-
- /* clean up */
- Matrix_Free(H2);
- Matrix_Free(U);
- Matrix_Free(Q);
- return K;
-} /* int_ker */
-
-
-/**
- * Computes the intersection of two linear lattices, whose base vectors are
- * respectively represented in A and B.
- * If I and/or Lb is set to NULL, then the matrix is allocated.
- * Else, the matrix is assumed to be allocated already.
- * I and Lb are rk x rk, where rk is the rank of A (or B).
- * @param A the full-row rank matrix whose column-vectors are the basis for the
- * first linear lattice.
- * @param B the matrix whose column-vectors are the basis for the second linear
- * lattice.
- * @param Lb the matrix such that B.Lb = I, where I is the intersection.
- * @return their intersection.
- */
-static void linearInter(Matrix * A, Matrix * B, Matrix ** I, Matrix **Lb) {
- Matrix * AB=NULL;
- int rk = A->NbRows;
- int a = A->NbColumns;
- int b = B->NbColumns;
- int i,j, z=0;
-
- Matrix * H, *U, *Q;
- /* ensure that the spanning vectors are in the same space */
- assert(B->NbRows==rk);
- /* 1- build the matrix
- * (A 0 1)
- * (0 B 1)
- */
- AB = Matrix_Alloc(2*rk, a+b+rk);
- Matrix_copySubMatrix(A, 0, 0, rk, a, AB, 0, 0);
- Matrix_copySubMatrix(B, 0, 0, rk, b, AB, rk, a);
- for (i=0; i< rk; i++) {
- value_set_si(AB->p[i][a+b+i], 1);
- value_set_si(AB->p[i+rk][a+b+i], 1);
- }
- if (dbgCompParm) {
- show_matrix(AB);
- }
-
- /* 2- Compute its left Hermite normal form. AB.U = [H 0] */
- left_hermite(AB, &H, &Q, &U);
- Matrix_Free(AB);
- Matrix_Free(Q);
- /* count the number of non-zero colums in H */
- for (z=H->NbColumns-1; value_zero_p(H->p[H->NbRows-1][z]); z--);
- z++;
- if (dbgCompParm) {
- show_matrix(H);
- printf("z=%d\n", z);
- }
- Matrix_Free(H);
- /* if you split U in 9 submatrices, you have:
- * A.U_13 = -U_33
- * B.U_23 = -U_33,
- * where the nb of cols of U_{*3} equals the nb of zero-cols of H
- * U_33 is a (the smallest) combination of col-vectors of A and B at the same
- * time: their intersection.
- */
- Matrix_subMatrix(U, a+b, z, U->NbColumns, U->NbColumns, I);
- Matrix_subMatrix(U, a, z, a+b, U->NbColumns, Lb);
- if (dbgCompParm) {
- show_matrix(U);
- }
- Matrix_Free(U);
-} /* linearInter */
-
-
-/**
- * Given a system of equalities, looks if it has an integer solution in the
- * combined space, and if yes, returns one solution.
- * <p>pre-condition: the equalities are full-row rank (without the constant
- * part)</p>
- * @param Eqs the system of equations (as constraints)
- * @param I a feasible integer solution if it exists, else NULL. Allocated if
- * initially set to NULL, else reused.
- */
-void Equalities_integerSolution(Matrix * Eqs, Matrix **I) {
- Matrix * Hm, *H=NULL, *U, *Q, *M=NULL, *C=NULL, *Hi;
- Matrix *Ip;
- int i;
- Value mod;
- unsigned int rk;
- if (Eqs==NULL){
- if ((*I)!=NULL) Matrix_Free(*I);
- I = NULL;
- return;
- }
- /* we use: AI = C = (Ha 0).Q.I = (Ha 0)(I' 0)^T */
- /* with I = Qinv.I' = U.I'*/
- /* 1- compute I' = Hainv.(-C) */
- /* HYP: the equalities are full-row rank */
- rk = Eqs->NbRows;
- Matrix_subMatrix(Eqs, 0, 1, rk, Eqs->NbColumns-1, &M);
- left_hermite(M, &Hm, &Q, &U);
- Matrix_Free(M);
- Matrix_subMatrix(Hm, 0, 0, rk, rk, &H);
- if (dbgCompParmMore) {
- show_matrix(Hm);
- show_matrix(H);
- show_matrix(U);
- }
- Matrix_Free(Q);
- Matrix_Free(Hm);
- Matrix_subMatrix(Eqs, 0, Eqs->NbColumns-1, rk, Eqs->NbColumns, &C);
- Matrix_oppose(C);
- Hi = Matrix_Alloc(rk, rk+1);
- MatInverse(H, Hi);
- if (dbgCompParmMore) {
- show_matrix(C);
- show_matrix(Hi);
- }
- /* put the numerator of Hinv back into H */
- Matrix_subMatrix(Hi, 0, 0, rk, rk, &H);
- Ip = Matrix_Alloc(Eqs->NbColumns-2, 1);
- /* fool Matrix_Product on the size of Ip */
- Ip->NbRows = rk;
- Matrix_Product(H, C, Ip);
- Ip->NbRows = Eqs->NbColumns-2;
- Matrix_Free(H);
- Matrix_Free(C);
- value_init(mod);
- for (i=0; i< rk; i++) {
- /* if Hinv.C is not integer, return NULL (no solution) */
- value_pmodulus(mod, Ip->p[i][0], Hi->p[i][rk]);
- if (value_notzero_p(mod)) {
- if ((*I)!=NULL) Matrix_Free(*I);
- value_clear(mod);
- Matrix_Free(U);
- Matrix_Free(Ip);
- Matrix_Free(Hi);
- I = NULL;
- return;
- }
- else {
- value_pdivision(Ip->p[i][0], Ip->p[i][0], Hi->p[i][rk]);
- }
- }
- /* fill the rest of I' with zeros */
- for (i=rk; i< Eqs->NbColumns-2; i++) {
- value_set_si(Ip->p[i][0], 0);
- }
- value_clear(mod);
- Matrix_Free(Hi);
- /* 2 - Compute the particular solution I = U.(I' 0) */
- ensureMatrix((*I), Eqs->NbColumns-2, 1);
- Matrix_Product(U, Ip, (*I));
- Matrix_Free(U);
- Matrix_Free(Ip);
- if (dbgCompParm) {
- show_matrix(*I);
- }
-}
-
-
-/**
- * Computes the validity lattice of a set of equalities. I.e., the lattice
- * induced on the last <tt>b</tt> variables by the equalities involving the
- * first <tt>a</tt> integer existential variables. The submatrix of Eqs that
- * concerns only the existential variables (so the first a columns) is assumed
- * to be full-row rank.
- * @param Eqs the equalities
- * @param a the number of existential integer variables, placed as first
- * variables
- * @param vl the (returned) validity lattice, in homogeneous form. It is
- * allocated if initially set to null, or reused if already allocated.
- */
-void Equalities_validityLattice(Matrix * Eqs, int a, Matrix** vl) {
- unsigned int b = Eqs->NbColumns-2-a;
- unsigned int r = Eqs->NbRows;
- Matrix * A=NULL, * B=NULL, *I = NULL, *Lb=NULL, *sol=NULL;
- Matrix *H, *U, *Q;
- unsigned int i;
-
- if (dbgCompParm) {
- printf("Computing validity lattice induced by the %d first variables of:"
- ,a);
- show_matrix(Eqs);
- }
- if (b==0) {
- ensureMatrix((*vl), 1, 1);
- value_set_si((*vl)->p[0][0], 1);
- return;
- }
-
- /* 1- check that there is an integer solution to the equalities */
- /* OPT: could change integerSolution's profile to allocate or not*/
- Equalities_integerSolution(Eqs, &sol);
- /* if there is no integer solution, there is no validity lattice */
- if (sol==NULL) {
- if ((*vl)!=NULL) Matrix_Free(*vl);
- return;
- }
- Matrix_subMatrix(Eqs, 0, 1, r, 1+a, &A);
- Matrix_subMatrix(Eqs, 0, 1+a, r, 1+a+b, &B);
- linearInter(A, B, &I, &Lb);
- Matrix_Free(A);
- Matrix_Free(B);
- Matrix_Free(I);
- if (dbgCompParm) {
- show_matrix(Lb);
- }
-
- /* 2- The linear part of the validity lattice is the left HNF of Lb */
- left_hermite(Lb, &H, &Q, &U);
- Matrix_Free(Lb);
- Matrix_Free(Q);
- Matrix_Free(U);
-
- /* 3- build the validity lattice */
- ensureMatrix((*vl), b+1, b+1);
- Matrix_copySubMatrix(H, 0, 0, b, b, (*vl), 0,0);
- Matrix_Free(H);
- for (i=0; i< b; i++) {
- value_assign((*vl)->p[i][b], sol->p[0][a+i]);
- }
- Matrix_Free(sol);
- Vector_Set((*vl)->p[b],0, b);
- value_set_si((*vl)->p[b][b], 1);
-
-} /* validityLattice */
-
-
-/**
- * Eliminate the columns corresponding to a list of eliminated parameters.
- * @param M the constraints matrix whose columns are to be removed
- * @param nbVars an offset to be added to the ranks of the variables to be
- * removed
- * @param elimParms the list of ranks of the variables to be removed
- * @param newM (output) the matrix without the removed columns
- */
-void Constraints_removeElimCols(Matrix * M, unsigned int nbVars,
- unsigned int *elimParms, Matrix ** newM) {
- unsigned int i, j, k;
- if (elimParms[0]==0) {
- Matrix_clone(M, newM);
- return;
- }
- if ((*newM)==NULL) {
- (*newM) = Matrix_Alloc(M->NbRows, M->NbColumns - elimParms[0]);
- }
- else {
- assert ((*newM)->NbColumns==M->NbColumns - elimParms[0]);
- }
- for (i=0; i< M->NbRows; i++) {
- value_assign((*newM)->p[i][0], M->p[i][0]); /* kind of cstr */
- k=0;
- Vector_Copy(&(M->p[i][1]), &((*newM)->p[i][1]), nbVars);
- for (j=0; j< M->NbColumns-2-nbVars; j++) {
- if (j!=elimParms[k+1]) {
- value_assign((*newM)->p[i][j-k+nbVars+1], M->p[i][j+nbVars+1]);
- }
- else {
- k++;
- }
- }
- value_assign((*newM)->p[i][(*newM)->NbColumns-1],
- M->p[i][M->NbColumns-1]); /* cst part */
- }
-} /* Constraints_removeElimCols */
-
-
-/**
- * Eliminates all the equalities in a set of constraints and returns the set of
- * constraints defining a full-dimensional polyhedron, such that there is a
- * bijection between integer points of the original polyhedron and these of the
- * resulting (projected) polyhedron).
- * If VL is set to NULL, this funciton allocates it. Else, it assumes that
- * (*VL) points to a matrix of the right size.
- * <p> The following things are done:
- * <ol>
- * <li> remove equalities involving only parameters, and remove as many
- * parameters as there are such equalities. From that, the list of
- * eliminated parameters <i>elimParms</i> is built.
- * <li> remove equalities that involve variables. This requires a compression
- * of the parameters and of the other variables that are not eliminated.
- * The affine compresson is represented by matrix VL (for <i>validity
- * lattice</i>) and is such that (N I 1)^T = VL.(N' I' 1), where N', I'
- * are integer (they are the parameters and variables after compression).
- *</ol>
- *</p>
- */
-void Constraints_fullDimensionize(Matrix ** M, Matrix ** C, Matrix ** VL,
- Matrix ** Eqs, Matrix ** ParmEqs,
- unsigned int ** elimVars,
- unsigned int ** elimParms,
- int maxRays) {
- unsigned int i, j;
- Matrix * A=NULL, *B=NULL;
- Matrix * Ineqs=NULL;
- unsigned int nbVars = (*M)->NbColumns - (*C)->NbColumns;
- unsigned int nbParms;
- int nbElimVars;
- Matrix * fullDim = NULL;
-
- /* variables for permutations */
- unsigned int * permutation;
- Matrix * permutedEqs=NULL, * permutedIneqs=NULL;
-
- /* 1- Eliminate the equalities involving only parameters. */
- (*ParmEqs) = Constraints_removeParmEqs(M, C, 0, elimParms);
- /* if the polyehdron is empty, return now. */
- if ((*M)->NbColumns==0) return;
- /* eliminate the columns corresponding to the eliminated parameters */
- if (elimParms[0]!=0) {
- Constraints_removeElimCols(*M, nbVars, (*elimParms), &A);
- Matrix_Free(*M);
- (*M) = A;
- Constraints_removeElimCols(*C, 0, (*elimParms), &B);
- Matrix_Free(*C);
- (*C) = B;
- if (dbgCompParm) {
- printf("After false parameter elimination: \n");
- show_matrix(*M);
- show_matrix(*C);
- }
- }
- nbParms = (*C)->NbColumns-2;
-
- /* 2- Eliminate the equalities involving variables */
- /* a- extract the (remaining) equalities from the poyhedron */
- split_constraints((*M), Eqs, &Ineqs);
- nbElimVars = (*Eqs)->NbRows;
- /* if the polyhedron is already full-dimensional, return */
- if ((*Eqs)->NbRows==0) {
- Matrix_identity(nbParms+1, VL);
- return;
- }
- /* b- choose variables to be eliminated */
- permutation = find_a_permutation((*Eqs), nbParms);
-
- if (dbgCompParm) {
- printf("Permuting the vars/parms this way: [ ");
- for (i=0; i< (*Eqs)->NbColumns-2; i++) {
- printf("%d ", permutation[i]);
- }
- printf("]\n");
- }
-
- Constraints_permute((*Eqs), permutation, &permutedEqs);
- Equalities_validityLattice(permutedEqs, (*Eqs)->NbRows, VL);
-
- if (dbgCompParm) {
- printf("Validity lattice: ");
- show_matrix(*VL);
- }
- Constraints_compressLastVars(permutedEqs, (*VL));
- Constraints_permute(Ineqs, permutation, &permutedIneqs);
- if (dbgCompParmMore) {
- show_matrix(permutedIneqs);
- show_matrix(permutedEqs);
- }
- Matrix_Free(*Eqs);
- Matrix_Free(Ineqs);
- Constraints_compressLastVars(permutedIneqs, (*VL));
- if (dbgCompParm) {
- printf("After compression: ");
- show_matrix(permutedIneqs);
- }
- /* c- eliminate the first variables */
- assert(Constraints_eliminateFirstVars(permutedEqs, permutedIneqs));
- if (dbgCompParmMore) {
- printf("After elimination of the variables: ");
- show_matrix(permutedIneqs);
- }
-
- /* d- get rid of the first (zero) columns,
- which are now useless, and put the parameters back at the end */
- fullDim = Matrix_Alloc(permutedIneqs->NbRows,
- permutedIneqs->NbColumns-nbElimVars);
- for (i=0; i< permutedIneqs->NbRows; i++) {
- value_set_si(fullDim->p[i][0], 1);
- for (j=0; j< nbParms; j++) {
- value_assign(fullDim->p[i][j+fullDim->NbColumns-nbParms-1],
- permutedIneqs->p[i][j+nbElimVars+1]);
- }
- for (j=0; j< permutedIneqs->NbColumns-nbParms-2-nbElimVars; j++) {
- value_assign(fullDim->p[i][j+1],
- permutedIneqs->p[i][nbElimVars+nbParms+j+1]);
- }
- value_assign(fullDim->p[i][fullDim->NbColumns-1],
- permutedIneqs->p[i][permutedIneqs->NbColumns-1]);
- }
- Matrix_Free(permutedIneqs);
-
-} /* Constraints_fullDimensionize */
-
-
-/**
- * Given a matrix that defines a full-dimensional affine lattice, returns the
- * affine sub-lattice spanned in the k first dimensions.
- * Useful for instance when you only look for the parameters' validity lattice.
- * @param lat the original full-dimensional lattice
- * @param subLat the sublattice
- */
-void Lattice_extractSubLattice(Matrix * lat, unsigned int k, Matrix ** subLat) {
- Matrix * H, *Q, *U, *linLat = NULL;
- unsigned int i;
- dbgStart(Lattice_extractSubLattice);
- /* if the dimension is already good, just copy the initial lattice */
- if (k==lat->NbRows-1) {
- if (*subLat==NULL) {
- (*subLat) = Matrix_Copy(lat);
- }
- else {
- Matrix_copySubMatrix(lat, 0, 0, lat->NbRows, lat->NbColumns, (*subLat), 0, 0);
- }
- return;
- }
- assert(k<lat->NbRows-1);
- /* 1- Make the linear part of the lattice triangular to eliminate terms from
- other dimensions */
- Matrix_subMatrix(lat, 0, 0, lat->NbRows, lat->NbColumns-1, &linLat);
- /* OPT: any integer column-vector elimination is ok indeed. */
- /* OPT: could test if the lattice is already in triangular form. */
- left_hermite(linLat, &H, &Q, &U);
- if (dbgCompParmMore) {
- show_matrix(H);
- }
- Matrix_Free(Q);
- Matrix_Free(U);
- Matrix_Free(linLat);
- /* if not allocated yet, allocate it */
- if (*subLat==NULL) {
- (*subLat) = Matrix_Alloc(k+1, k+1);
- }
- Matrix_copySubMatrix(H, 0, 0, k, k, (*subLat), 0, 0);
- Matrix_Free(H);
- Matrix_copySubMatrix(lat, 0, lat->NbColumns-1, k, 1, (*subLat), 0, k);
- for (i=0; i<k; i++) {
- value_set_si((*subLat)->p[k][i], 0);
- }
- value_set_si((*subLat)->p[k][k], 1);
- dbgEnd(Lattice_extractSubLattice);
-} /* Lattice_extractSubLattice */
-
-
-/**
- * Computes the overall period of the variables I for (MI) mod |d|, where M is
- * a matrix and |d| a vector. Produce a diagonal matrix S = (s_k) where s_k is
- * the overall period of i_k
- * @param M the set of affine functions of I (row-vectors)
- * @param d the column-vector representing the modulos
-*/
-Matrix * affine_periods(Matrix * M, Matrix * d) {
- Matrix * S;
- unsigned int i,j;
- Value tmp;
- Value * periods = (Value *)malloc(sizeof(Value) * M->NbColumns);
- value_init(tmp);
- for(i=0; i< M->NbColumns; i++) {
- value_init(periods[i]);
- value_set_si(periods[i], 1);
- }
- for (i=0; i<M->NbRows; i++) {
- for (j=0; j< M->NbColumns; j++) {
- value_gcd(tmp, d->p[i][0], M->p[i][j]);
- value_divexact(tmp, d->p[i][0], tmp);
- value_lcm(periods[j], periods[j], tmp);
- }
- }
- value_clear(tmp);
-
- /* 2- build S */
- S = Matrix_Alloc(M->NbColumns, M->NbColumns);
- for (i=0; i< M->NbColumns; i++)
- for (j=0; j< M->NbColumns; j++)
- if (i==j) value_assign(S->p[i][j],periods[j]);
- else value_set_si(S->p[i][j], 0);
-
- /* 3- clean up */
- for(i=0; i< M->NbColumns; i++) value_clear(periods[i]);
- free(periods);
- return S;
-} /* affine_periods */
-
-
-/**
- * Given an integer matrix B with m rows and integer m-vectors C and d,
- * computes the basis of the integer solutions to (BN+C) mod d = 0 (1).
- * This is an affine lattice (G): (N 1)^T= G(N' 1)^T, forall N' in Z^b.
- * If there is no solution, returns NULL.
- * @param B B, a (m x b) matrix
- * @param C C, a (m x 1) integer matrix
- * @param d d, a (1 x m) integer matrix
- * @param imb the affine (b+1)x(b+1) basis of solutions, in the homogeneous
- * form. Allocated if initially set to NULL, reused if not.
-*/
-void Equalities_intModBasis(Matrix * B, Matrix * C, Matrix * d, Matrix ** imb) {
- int b = B->NbColumns;
- /* FIXME: treat the case d=0 as a regular equality B_kN+C_k = 0: */
- /* OPT: could keep only equalities for which d>1 */
- int nbEqs = B->NbRows;
- unsigned int i;
-
- /* 1- buid the problem DI+BN+C = 0 */
- Matrix * eqs = Matrix_Alloc(nbEqs, nbEqs+b+1);
- for (i=0; i< nbEqs; i++) {
- value_assign(eqs->p[i][i], d->p[0][i]);
- }
- Matrix_copySubMatrix(B, 0, 0, nbEqs, b, eqs, 0, nbEqs);
- Matrix_copySubMatrix(C, 0, 0, nbEqs, 1, eqs, 0, nbEqs+b);
-
- /* 2- the solution is the validity lattice of the equalities */
- Equalities_validityLattice(eqs, nbEqs, imb);
- Matrix_Free(eqs);
-} /* Equalities_intModBasis */
-
-
-/** kept here for backwards compatiblity. Wrapper to Equalities_intModBasis() */
-Matrix * int_mod_basis(Matrix * B, Matrix * C, Matrix * d) {
- Matrix * imb = NULL;
- Equalities_intModBasis(B, C, d, &imb);
- return imb;
-} /* int_mod_basis */
-
-
-/**
- * Given a parameterized constraints matrix with m equalities, computes the
- * compression matrix G such that there is an integer solution in the variables
- * space for each value of N', with N = G N' (N are the "nb_parms" parameters)
- * @param E a matrix of parametric equalities @param nb_parms the number of
- * parameters
- * <b>Note: </b>this function is mostly here for backwards
- * compatibility. Prefer the use of <tt>Equalities_validityLattice</tt>.
-*/
-Matrix * compress_parms(Matrix * E, int nbParms) {
- Matrix * vl=NULL;
- Equalities_validityLattice(E, E->NbColumns-2-nbParms, &vl);
- return vl;
-}/* compress_parms */
-
-
-/** Removes the equalities that involve only parameters, by eliminating some
- * parameters in the polyhedron's constraints and in the context.<p>
- * <b>Updates M and Ctxt.</b>
- * @param M1 the polyhedron's constraints
- * @param Ctxt1 the constraints of the polyhedron's context
- * @param renderSpace tells if the returned equalities must be expressed in the
- * parameters space (renderSpace=0) or in the combined var/parms space
- * (renderSpace = 1)
- * @param elimParms the list of parameters that have been removed: an array
- * whose 1st element is the number of elements in the list. (returned)
- * @return the system of equalities that involve only parameters.
- */
-Matrix * Constraints_Remove_parm_eqs(Matrix ** M1, Matrix ** Ctxt1,
- int renderSpace,
- unsigned int ** elimParms) {
- int i, j, k, nbEqsParms =0;
- int nbEqsM, nbEqsCtxt, allZeros, nbTautoM = 0, nbTautoCtxt = 0;
- Matrix * M = (*M1);
- Matrix * Ctxt = (*Ctxt1);
- int nbVars = M->NbColumns-Ctxt->NbColumns;
- Matrix * Eqs;
- Matrix * EqsMTmp;
-
- /* 1- build the equality matrix(ces) */
- nbEqsM = 0;
- for (i=0; i< M->NbRows; i++) {
- k = First_Non_Zero(M->p[i], M->NbColumns);
- /* if it is a tautology, count it as such */
- if (k==-1) {
- nbTautoM++;
- }
- else {
- /* if it only involves parameters, count it */
- if (k>= nbVars+1) nbEqsM++;
- }
- }
-
- nbEqsCtxt = 0;
- for (i=0; i< Ctxt->NbRows; i++) {
- if (value_zero_p(Ctxt->p[i][0])) {
- if (First_Non_Zero(Ctxt->p[i], Ctxt->NbColumns)==-1) {
- nbTautoCtxt++;
- }
- else {
- nbEqsCtxt ++;
- }
- }
- }
- nbEqsParms = nbEqsM + nbEqsCtxt;
-
- /* nothing to do in this case */
- if (nbEqsParms+nbTautoM+nbTautoCtxt==0) {
- (*elimParms) = (unsigned int*) malloc(sizeof(int));
- (*elimParms)[0] = 0;
- if (renderSpace==0) {
- return Matrix_Alloc(0,Ctxt->NbColumns);
- }
- else {
- return Matrix_Alloc(0,M->NbColumns);
- }
- }
-
- Eqs= Matrix_Alloc(nbEqsParms, Ctxt->NbColumns);
- EqsMTmp= Matrix_Alloc(nbEqsParms, M->NbColumns);
-
- /* copy equalities from the context */
- k = 0;
- for (i=0; i< Ctxt->NbRows; i++) {
- if (value_zero_p(Ctxt->p[i][0])
- && First_Non_Zero(Ctxt->p[i], Ctxt->NbColumns)!=-1) {
- Vector_Copy(Ctxt->p[i], Eqs->p[k], Ctxt->NbColumns);
- Vector_Copy(Ctxt->p[i]+1, EqsMTmp->p[k]+nbVars+1,
- Ctxt->NbColumns-1);
- k++;
- }
- }
- for (i=0; i< M->NbRows; i++) {
- j=First_Non_Zero(M->p[i], M->NbColumns);
- /* copy equalities that involve only parameters from M */
- if (j>=nbVars+1) {
- Vector_Copy(M->p[i]+nbVars+1, Eqs->p[k]+1, Ctxt->NbColumns-1);
- Vector_Copy(M->p[i]+nbVars+1, EqsMTmp->p[k]+nbVars+1,
- Ctxt->NbColumns-1);
- /* mark these equalities for removal */
- value_set_si(M->p[i][0], 2);
- k++;
- }
- /* mark the all-zero equalities for removal */
- if (j==-1) {
- value_set_si(M->p[i][0], 2);
- }
- }
-
- /* 2- eliminate parameters until all equalities are used or until we find a
- contradiction (overconstrained system) */
- (*elimParms) = (unsigned int *) malloc((Eqs->NbRows+1) * sizeof(int));
- (*elimParms)[0] = 0;
- allZeros = 0;
- for (i=0; i< Eqs->NbRows; i++) {
- /* find a variable that can be eliminated */
- k = First_Non_Zero(Eqs->p[i], Eqs->NbColumns);
- if (k!=-1) { /* nothing special to do for tautologies */
-
- /* if there is a contradiction, return empty matrices */
- if (k==Eqs->NbColumns-1) {
- printf("Contradiction in %dth row of Eqs: ",k);
- show_matrix(Eqs);
- Matrix_Free(Eqs);
- Matrix_Free(EqsMTmp);
- (*M1) = Matrix_Alloc(0, M->NbColumns);
- Matrix_Free(M);
- (*Ctxt1) = Matrix_Alloc(0,Ctxt->NbColumns);
- Matrix_Free(Ctxt);
- free(*elimParms);
- (*elimParms) = (unsigned int *) malloc(sizeof(int));
- (*elimParms)[0] = 0;
- if (renderSpace==1) {
- return Matrix_Alloc(0,(*M1)->NbColumns);
- }
- else {
- return Matrix_Alloc(0,(*Ctxt1)->NbColumns);
- }
- }
- /* if we have something we can eliminate, do it in 3 places:
- Eqs, Ctxt, and M */
- else {
- k--; /* k is the rank of the variable, now */
- (*elimParms)[0]++;
- (*elimParms)[(*elimParms[0])]=k;
- for (j=0; j< Eqs->NbRows; j++) {
- if (i!=j) {
- eliminate_var_with_constr(Eqs, i, Eqs, j, k);
- eliminate_var_with_constr(EqsMTmp, i, EqsMTmp, j, k+nbVars);
- }
- }
- for (j=0; j< Ctxt->NbRows; j++) {
- if (value_notzero_p(Ctxt->p[i][0])) {
- eliminate_var_with_constr(Eqs, i, Ctxt, j, k);
- }
- }
- for (j=0; j< M->NbRows; j++) {
- if (value_cmp_si(M->p[i][0], 2)) {
- eliminate_var_with_constr(EqsMTmp, i, M, j, k+nbVars);
- }
- }
- }
- }
- /* if (k==-1): count the tautologies in Eqs to remove them later */
- else {
- allZeros++;
- }
- }
-
- /* elimParms may have been overallocated. Now we know how many parms have
- been eliminated so we can reallocate the right amount of memory. */
- if (!realloc((*elimParms), ((*elimParms)[0]+1)*sizeof(int))) {
- fprintf(stderr, "Constraints_Remove_parm_eqs > cannot realloc()");
- }
-
- Matrix_Free(EqsMTmp);
-
- /* 3- remove the "bad" equalities from the input matrices
- and copy the equalities involving only parameters */
- EqsMTmp = Matrix_Alloc(M->NbRows-nbEqsM-nbTautoM, M->NbColumns);
- k=0;
- for (i=0; i< M->NbRows; i++) {
- if (value_cmp_si(M->p[i][0], 2)) {
- Vector_Copy(M->p[i], EqsMTmp->p[k], M->NbColumns);
- k++;
- }
- }
- Matrix_Free(M);
- (*M1) = EqsMTmp;
-
- EqsMTmp = Matrix_Alloc(Ctxt->NbRows-nbEqsCtxt-nbTautoCtxt, Ctxt->NbColumns);
- k=0;
- for (i=0; i< Ctxt->NbRows; i++) {
- if (value_notzero_p(Ctxt->p[i][0])) {
- Vector_Copy(Ctxt->p[i], EqsMTmp->p[k], Ctxt->NbColumns);
- k++;
- }
- }
- Matrix_Free(Ctxt);
- (*Ctxt1) = EqsMTmp;
-
- if (renderSpace==0) {/* renderSpace=0: equalities in the parameter space */
- EqsMTmp = Matrix_Alloc(Eqs->NbRows-allZeros, Eqs->NbColumns);
- k=0;
- for (i=0; i<Eqs->NbRows; i++) {
- if (First_Non_Zero(Eqs->p[i], Eqs->NbColumns)!=-1) {
- Vector_Copy(Eqs->p[i], EqsMTmp->p[k], Eqs->NbColumns);
- k++;
- }
- }
- }
- else {/* renderSpace=1: equalities rendered in the combined space */
- EqsMTmp = Matrix_Alloc(Eqs->NbRows-allZeros, (*M1)->NbColumns);
- k=0;
- for (i=0; i<Eqs->NbRows; i++) {
- if (First_Non_Zero(Eqs->p[i], Eqs->NbColumns)!=-1) {
- Vector_Copy(Eqs->p[i], &(EqsMTmp->p[k][nbVars]), Eqs->NbColumns);
- k++;
- }
- }
- }
- Matrix_Free(Eqs);
- Eqs = EqsMTmp;
-
- return Eqs;
-} /* Constraints_Remove_parm_eqs */
-
-
-/** Removes equalities involving only parameters, but starting from a
- * Polyhedron and its context.
- * @param P the polyhedron
- * @param C P's context
- * @param renderSpace: 0 for the parameter space, =1 for the combined space.
- * @maxRays Polylib's usual <i>workspace</i>.
- */
-Polyhedron * Polyhedron_Remove_parm_eqs(Polyhedron ** P, Polyhedron ** C,
- int renderSpace,
- unsigned int ** elimParms,
- int maxRays) {
- Matrix * Eqs;
- Polyhedron * Peqs;
- Matrix * M = Polyhedron2Constraints((*P));
- Matrix * Ct = Polyhedron2Constraints((*C));
-
- /* if the Minkowski representation is not computed yet, do not compute it in
- Constraints2Polyhedron */
- if (F_ISSET((*P), POL_VALID | POL_INEQUALITIES) &&
- (F_ISSET((*C), POL_VALID | POL_INEQUALITIES))) {
- FL_INIT(maxRays, POL_NO_DUAL);
- }
-
- Eqs = Constraints_Remove_parm_eqs(&M, &Ct, renderSpace, elimParms);
- Peqs = Constraints2Polyhedron(Eqs, maxRays);
- Matrix_Free(Eqs);
-
- /* particular case: no equality involving only parms is found */
- if (Eqs->NbRows==0) {
- Matrix_Free(M);
- Matrix_Free(Ct);
- return Peqs;
- }
- Polyhedron_Free(*P);
- Polyhedron_Free(*C);
- (*P) = Constraints2Polyhedron(M, maxRays);
- (*C) = Constraints2Polyhedron(Ct, maxRays);
- Matrix_Free(M);
- Matrix_Free(Ct);
- return Peqs;
-} /* Polyhedron_Remove_parm_eqs */
-
-
-/**
- * Given a matrix with m parameterized equations, compress the nb_parms
- * parameters and n-m variables so that m variables are integer, and transform
- * the variable space into a n-m space by eliminating the m variables (using
- * the equalities) the variables to be eliminated are chosen automatically by
- * the function.
- * <b>Deprecated.</b> Try to use Constraints_fullDimensionize instead.
- * @param M the constraints
- * @param the number of parameters
- * @param validityLattice the the integer lattice underlying the integer
- * solutions.
-*/
-Matrix * full_dimensionize(Matrix const * M, int nbParms,
- Matrix ** validityLattice) {
- Matrix * Eqs, * Ineqs;
- Matrix * permutedEqs, * permutedIneqs;
- Matrix * Full_Dim;
- Matrix * WVL; /* The Whole Validity Lattice (vars+parms) */
- unsigned int i,j;
- int nbElimVars;
- unsigned int * permutation, * permutationInv;
- /* 0- Split the equalities and inequalities from each other */
- split_constraints(M, &Eqs, &Ineqs);
-
- /* 1- if the polyhedron is already full-dimensional, return it */
- if (Eqs->NbRows==0) {
- Matrix_Free(Eqs);
- (*validityLattice) = Identity_Matrix(nbParms+1);
- return Ineqs;
- }
- nbElimVars = Eqs->NbRows;
-
- /* 2- put the vars to be eliminated at the first positions,
- and compress the other vars/parms
- -> [ variables to eliminate / parameters / variables to keep ] */
- permutation = find_a_permutation(Eqs, nbParms);
-
-
-
-
- // DEBUG REPAIR 2: Why is there noch check if the permutation vector is valid?
- if (permutation==NULL)
- {
- // There are temporary matrices and stuff, which are NOT freed...
- return NULL;
- }
-
-
-
-
- if (dbgCompParm) {
- printf("Permuting the vars/parms this way: [ ");
- for (i=0; i< Eqs->NbColumns; i++) {
- printf("%d ", permutation[i]);
- }
- printf("]\n");
- }
- permutedEqs = mpolyhedron_permute(Eqs, permutation);
- WVL = compress_parms(permutedEqs, Eqs->NbColumns-2-Eqs->NbRows);
-
-
-
-
- // DEBUG REPAIR 1: Why is there no check if WVL is valid?
- if (WVL==NULL)
- {
- // There are temporary matrices and stuff, which are NOT freed...
- return NULL;
- }
-
-
-
-
-
- if (dbgCompParm) {
- printf("Whole validity lattice: ");
- show_matrix(WVL);
- }
- mpolyhedron_compress_last_vars(permutedEqs, WVL);
- permutedIneqs = mpolyhedron_permute(Ineqs, permutation);
- if (dbgCompParm) {
- show_matrix(permutedEqs);
- }
- Matrix_Free(Eqs);
- Matrix_Free(Ineqs);
- mpolyhedron_compress_last_vars(permutedIneqs, WVL);
- if (dbgCompParm) {
- printf("After compression: ");
- show_matrix(permutedIneqs);
- }
- /* 3- eliminate the first variables */
- if (!mpolyhedron_eliminate_first_variables(permutedEqs, permutedIneqs)) {
- fprintf(stderr,"full-dimensionize > variable elimination failed. \n");
- return NULL;
- }
- if (dbgCompParm) {
- printf("After elimination of the variables: ");
- show_matrix(permutedIneqs);
- }
-
- /* 4- get rid of the first (zero) columns,
- which are now useless, and put the parameters back at the end */
- Full_Dim = Matrix_Alloc(permutedIneqs->NbRows,
- permutedIneqs->NbColumns-nbElimVars);
- for (i=0; i< permutedIneqs->NbRows; i++) {
- value_set_si(Full_Dim->p[i][0], 1);
- for (j=0; j< nbParms; j++)
- value_assign(Full_Dim->p[i][j+Full_Dim->NbColumns-nbParms-1],
- permutedIneqs->p[i][j+nbElimVars+1]);
- for (j=0; j< permutedIneqs->NbColumns-nbParms-2-nbElimVars; j++)
- value_assign(Full_Dim->p[i][j+1],
- permutedIneqs->p[i][nbElimVars+nbParms+j+1]);
- value_assign(Full_Dim->p[i][Full_Dim->NbColumns-1],
- permutedIneqs->p[i][permutedIneqs->NbColumns-1]);
- }
- Matrix_Free(permutedIneqs);
-
- /* 5- Keep only the the validity lattice restricted to the parameters */
- *validityLattice = Matrix_Alloc(nbParms+1, nbParms+1);
- for (i=0; i< nbParms; i++) {
- for (j=0; j< nbParms; j++)
- value_assign((*validityLattice)->p[i][j],
- WVL->p[i][j]);
- value_assign((*validityLattice)->p[i][nbParms],
- WVL->p[i][WVL->NbColumns-1]);
- }
- for (j=0; j< nbParms; j++)
- value_set_si((*validityLattice)->p[nbParms][j], 0);
- value_assign((*validityLattice)->p[nbParms][nbParms],
- WVL->p[WVL->NbColumns-1][WVL->NbColumns-1]);
-
- /* 6- Clean up */
- Matrix_Free(WVL);
- return Full_Dim;
-} /* full_dimensionize */
-
-#undef dbgCompParm
-#undef dbgCompParmMore
diff --git a/source/polylib_mod/ehrhart.c b/source/polylib_mod/ehrhart.c
deleted file mode 100644
index 5250825..0000000
--- a/source/polylib_mod/ehrhart.c
+++ /dev/null
@@ -1,2775 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/***********************************************************************/
-/* Ehrhart V4.20 */
-/* copyright 1997, Doran Wilde */
-/* copyright 1997-2000, Vincent Loechner */
-/* Permission is granted to copy, use, and distribute */
-/* for any commercial or noncommercial purpose under the terms */
-/* of the GNU General Public license, version 2, June 1991 */
-/* (see file : LICENSING). */
-/***********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-//#include <unistd.h>
-#include <assert.h>
-
-#include <polylib/polylib.h>
-#include <polylib/homogenization.h>
-
-
-/*! \class Ehrhart
-
-The following are mainly for debug purposes. You shouldn't need to
-change anything for daily usage...
-
-<p>
-
-you may define each macro independently
-<ol>
-<li> #define EDEBUG minimal debug
-<li> #define EDEBUG1 prints enumeration points
-<li> #define EDEBUG11 prints number of points
-<li> #define EDEBUG2 prints domains
-<li> #define EDEBUG21 prints more domains
-<li> #define EDEBUG3 prints systems of equations that are solved
-<li> #define EDEBUG4 prints message for degree reduction
-<li> #define EDEBUG5 prints result before simplification
-<li> #define EDEBUG6 prints domains in Preprocess
-<li> #define EDEBUG61 prints even more in Preprocess
-<li> #define EDEBUG62 prints domains in Preprocess2
-</ol>
-*/
-
-
-/**
-
-define this to print all constraints on the validity domains if not
-defined, only new constraints (not in validity domain given by the
-user) are printed
-
-*/
-#define EPRINT_ALL_VALIDITY_CONSTRAINTS
-
-/* #define EDEBUG */ /* minimal debug */
-/* #define EDEBUG1 */ /* prints enumeration points */
-/* #define EDEBUG11 */ /* prints number of points */
-/* #define EDEBUG2 */ /* prints domains */
-/* #define EDEBUG21 */ /* prints more domains */
-/* #define EDEBUG3 */ /* prints systems of equations that are solved */
-/* #define EDEBUG4 */ /* prints message for degree reduction */
-/* #define EDEBUG5 */ /* prints result before simplification */
-/* #define EDEBUG6 */ /* prints domains in Preprocess */
-/* #define EDEBUG61 */ /* prints even more in Preprocess */
-/* #define EDEBUG62 */ /* prints domains in Preprocess2 */
-
-
-/**
- Reduce the degree of resulting polynomials
-*/
-#define REDUCE_DEGREE
-
-/**
-define this to print one warning message per domain overflow these
-overflows should no longer happen since version 4.20
-*/
-#define ALL_OVERFLOW_WARNINGS
-
-/******************* -----------END USER #DEFS-------- *********************/
-
-int overflow_warning_flag = 1;
-
-/*-------------------------------------------------------------------*/
-/* EHRHART POLYNOMIAL SYMBOLIC ALGEBRA SYSTEM */
-/*-------------------------------------------------------------------*/
-/**
-
-EHRHART POLYNOMIAL SYMBOLIC ALGEBRA SYSTEM. The newly allocated enode
-can be freed with a simple free(x)
-
- at param type : enode type
- at param size : degree+1 for polynomial, period for periodic
- at param pos : 1..nb_param, position of parameter
- at return a newly allocated enode
-
-*/
-enode *new_enode(enode_type type,int size,int pos) {
-
- enode *res;
- int i;
-
- if(size == 0) {
- fprintf(stderr, "Allocating enode of size 0 !\n" );
- return NULL;
- }
- res = (enode *) malloc(sizeof(enode) + (size-1)*sizeof(evalue));
- res->type = type;
- res->size = size;
- res->pos = pos;
- for(i=0; i<size; i++) {
- value_init(res->arr[i].d);
- value_set_si(res->arr[i].d,0);
- res->arr[i].x.p = 0;
- }
- return res;
-} /* new_enode */
-
-/**
-releases all memory referenced by e. (recursive)
- at param e pointer to an evalue
-*/
-void free_evalue_refs(evalue *e) {
-
- enode *p;
- int i;
-
- if (value_notzero_p(e->d)) {
-
- /* 'e' stores a constant */
- value_clear(e->d);
- value_clear(e->x.n);
- return;
- }
- value_clear(e->d);
- p = e->x.p;
- if (!p) return; /* null pointer */
- for (i=0; i<p->size; i++) {
- free_evalue_refs(&(p->arr[i]));
- }
- free(p);
- return;
-} /* free_evalue_refs */
-
-/**
-
- at param e pointer to an evalue
- at return description
-
-*/
-enode *ecopy(enode *e) {
-
- enode *res;
- int i;
-
- res = new_enode(e->type,e->size,e->pos);
- for(i=0;i<e->size;++i) {
- value_assign(res->arr[i].d,e->arr[i].d);
- if(value_zero_p(res->arr[i].d))
- res->arr[i].x.p = ecopy(e->arr[i].x.p);
- else {
- value_init(res->arr[i].x.n);
- value_assign(res->arr[i].x.n,e->arr[i].x.n);
- }
- }
- return(res);
-} /* ecopy */
-
-/**
-
- at param DST destination file
- at param e pointer to evalue to be printed
- at param pname array of strings, name of the parameters
-
-*/
-void print_evalue(FILE *DST, evalue *e, const char **pname)
-{
- if(value_notzero_p(e->d)) {
- if(value_notone_p(e->d)) {
- value_print(DST,VALUE_FMT,e->x.n);
- fprintf(DST,"/");
- value_print(DST,VALUE_FMT,e->d);
- }
- else {
- value_print(DST,VALUE_FMT,e->x.n);
- }
- }
- else
- print_enode(DST,e->x.p,pname);
- return;
-} /* print_evalue */
-
-/** prints the enode to DST
-
- at param DST destination file
- at param p pointer to enode to be printed
- at param pname array of strings, name of the parameters
-
-*/
-void print_enode(FILE *DST, enode *p, const char **pname)
-{
- int i;
-
- if (!p) {
- fprintf(DST, "NULL");
- return;
- }
- if (p->type == evector) {
- fprintf(DST, "{ ");
- for (i=0; i<p->size; i++) {
- print_evalue(DST, &p->arr[i], pname);
- if (i!=(p->size-1))
- fprintf(DST, ", ");
- }
- fprintf(DST, " }\n");
- }
- else if (p->type == polynomial) {
- fprintf(DST, "( ");
- for (i=p->size-1; i>=0; i--) {
- print_evalue(DST, &p->arr[i], pname);
- if (i==1) fprintf(DST, " * %s + ", pname[p->pos-1]);
- else if (i>1)
- fprintf(DST, " * %s^%d + ", pname[p->pos-1], i);
- }
- fprintf(DST, " )\n");
- }
- else if (p->type == periodic) {
- fprintf(DST, "[ ");
- for (i=0; i<p->size; i++) {
- print_evalue(DST, &p->arr[i], pname);
- if (i!=(p->size-1)) fprintf(DST, ", ");
- }
- fprintf(DST," ]_%s", pname[p->pos-1]);
- }
- return;
-} /* print_enode */
-
-/**
-
- at param e1 pointers to evalues
- at param e2 pointers to evalues
- at return 1 (true) if they are equal, 0 (false) if not
-
-*/
-static int eequal(evalue *e1,evalue *e2) {
-
- int i;
- enode *p1, *p2;
-
- if (value_ne(e1->d,e2->d))
- return 0;
-
- /* e1->d == e2->d */
- if (value_notzero_p(e1->d)) {
- if (value_ne(e1->x.n,e2->x.n))
- return 0;
-
- /* e1->d == e2->d != 0 AND e1->n == e2->n */
- return 1;
- }
-
- /* e1->d == e2->d == 0 */
- p1 = e1->x.p;
- p2 = e2->x.p;
- if (p1->type != p2->type) return 0;
- if (p1->size != p2->size) return 0;
- if (p1->pos != p2->pos) return 0;
- for (i=0; i<p1->size; i++)
- if (!eequal(&p1->arr[i], &p2->arr[i]) )
- return 0;
- return 1;
-} /* eequal */
-
-/**
-
- at param e pointer to an evalue
-
-*/
-void reduce_evalue (evalue *e) {
-
- enode *p;
- int i, j, k;
-
- if (value_notzero_p(e->d))
- return; /* a rational number, its already reduced */
- if(!(p = e->x.p))
- return; /* hum... an overflow probably occured */
-
- /* First reduce the components of p */
- for (i=0; i<p->size; i++)
- reduce_evalue(&p->arr[i]);
-
- if (p->type==periodic) {
-
- /* Try to reduce the period */
- for (i=1; i<=(p->size)/2; i++) {
- if ((p->size % i)==0) {
-
- /* Can we reduce the size to i ? */
- for (j=0; j<i; j++)
- for (k=j+i; k<e->x.p->size; k+=i)
- if (!eequal(&p->arr[j], &p->arr[k])) goto you_lose;
-
- /* OK, lets do it */
- for (j=i; j<p->size; j++) free_evalue_refs(&p->arr[j]);
- p->size = i;
- break;
-
- you_lose: /* OK, lets not do it */
- continue;
- }
- }
-
- /* Try to reduce its strength */
- if (p->size == 1) {
- value_clear(e->d);
- memcpy(e,&p->arr[0],sizeof(evalue));
- free(p);
- }
- }
- else if (p->type==polynomial) {
-
- /* Try to reduce the degree */
- for (i=p->size-1;i>=1;i--) {
- if (!(value_one_p(p->arr[i].d) && value_zero_p(p->arr[i].x.n)))
- break;
- /* Zero coefficient */
- free_evalue_refs(&p->arr[i]);
- }
- if (i+1<p->size)
- p->size = i+1;
-
- /* Try to reduce its strength */
- if (p->size == 1) {
- value_clear(e->d);
- memcpy(e,&p->arr[0],sizeof(evalue));
- free(p);
- }
- }
-} /* reduce_evalue */
-
-
-/**
-
-multiplies two evalues and puts the result in res
-
- at param e1 pointer to an evalue
- at param e2 pointer to a constant evalue
- at param res pointer to result evalue = e1 * e2
-
-*/
-static void emul (evalue *e1,evalue *e2,evalue *res) {
-
- enode *p;
- int i;
- Value g;
-
- if (value_zero_p(e2->d)) {
- fprintf(stderr, "emul: ?expecting constant value\n");
- return;
- }
- value_init(g);
- if (value_notzero_p(e1->d)) {
-
- value_init(res->x.n);
- /* Product of two rational numbers */
- value_multiply(res->d,e1->d,e2->d);
- value_multiply(res->x.n,e1->x.n,e2->x.n );
- value_gcd(g, res->x.n, res->d);
- if (value_notone_p(g)) {
- value_divexact(res->d, res->d, g);
- value_divexact(res->x.n, res->x.n, g);
- }
- }
- else { /* e1 is an expression */
- value_set_si(res->d,0);
- p = e1->x.p;
- res->x.p = new_enode(p->type, p->size, p->pos);
- for (i=0; i<p->size; i++) {
- emul(&p->arr[i], e2, &(res->x.p->arr[i]) );
- }
- }
- value_clear(g);
- return;
-} /* emul */
-
-/**
-adds one evalue to evalue 'res. result = res + e1
-
- at param e1 an evalue
- at param res
-
-*/
-void eadd(evalue *e1,evalue *res) {
-
- int i;
- Value g,m1,m2;
-
- value_init(g);
- value_init(m1);
- value_init(m2);
-
- if (value_notzero_p(e1->d) && value_notzero_p(res->d)) {
-
- /* Add two rational numbers*/
- value_multiply(m1,e1->x.n,res->d);
- value_multiply(m2,res->x.n,e1->d);
- value_addto(res->x.n,m1,m2);
- value_multiply(res->d,e1->d,res->d);
- value_gcd(g, res->x.n, res->d);
- if (value_notone_p(g)) {
- value_divexact(res->d, res->d, g);
- value_divexact(res->x.n, res->x.n, g);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- else if (value_notzero_p(e1->d) && value_zero_p(res->d)) {
- if (res->x.p->type==polynomial) {
-
- /* Add the constant to the constant term */
- eadd(e1, &res->x.p->arr[0]);
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- else if (res->x.p->type==periodic) {
-
- /* Add the constant to all elements of periodic number */
- for (i=0; i<res->x.p->size; i++) {
- eadd(e1, &res->x.p->arr[i]);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- else {
- fprintf(stderr, "eadd: cannot add const with vector\n");
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- }
- else if (value_zero_p(e1->d) && value_notzero_p(res->d)) {
- fprintf(stderr,"eadd: cannot add evalue to const\n");
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- else { /* ((e1->d==0) && (res->d==0)) */
- if ((e1->x.p->type != res->x.p->type) ||
- (e1->x.p->pos != res->x.p->pos )) {
- fprintf(stderr, "eadd: ?cannot add, incompatible types\n");
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- if (e1->x.p->size == res->x.p->size) {
- for (i=0; i<res->x.p->size; i++) {
- eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
-
- /* Sizes are different */
- if (res->x.p->type==polynomial) {
-
- /* VIN100: if e1-size > res-size you have to copy e1 in a */
- /* new enode and add res to that new node. If you do not do */
- /* that, you lose the the upper weight part of e1 ! */
-
- if(e1->x.p->size > res->x.p->size) {
- enode *tmp;
- tmp = ecopy(e1->x.p);
- for(i=0;i<res->x.p->size;++i) {
- eadd(&res->x.p->arr[i], &tmp->arr[i]);
- free_evalue_refs(&res->x.p->arr[i]);
- }
- res->x.p = tmp;
- }
- else {
- for (i=0; i<e1->x.p->size ; i++) {
- eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- }
- else if (res->x.p->type==periodic) {
- fprintf(stderr, "eadd: ?addition of different sized periodic nos\n");
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- else { /* evector */
- fprintf(stderr, "eadd: ?cannot add vectors of different length\n");
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
-} /* eadd */
-
-/**
-
-computes the inner product of two vectors. Result = result (evalue) =
-v1.v2 (dot product)
-
- at param v1 an enode (vector)
- at param v2 an enode (vector of constants)
- at param res result (evalue)
-
-*/
-void edot(enode *v1,enode *v2,evalue *res) {
-
- int i;
- evalue tmp;
-
- if ((v1->type != evector) || (v2->type != evector)) {
- fprintf(stderr, "edot: ?expecting vectors\n");
- return;
- }
- if (v1->size != v2->size) {
- fprintf(stderr, "edot: ? vector lengths do not agree\n");
- return;
- }
- if (v1->size<=0) {
- value_set_si(res->d,1); /* set result to 0/1 */
- value_init(res->x.n);
- value_set_si(res->x.n,0);
- return;
- }
-
- /* vector v2 is expected to have only rational numbers in */
- /* the array. No pointers. */
- emul(&v1->arr[0],&v2->arr[0],res);
- for (i=1; i<v1->size; i++) {
- value_init(tmp.d);
-
- /* res = res + v1[i]*v2[i] */
- emul(&v1->arr[i],&v2->arr[i],&tmp);
- eadd(&tmp,res);
- free_evalue_refs(&tmp);
- }
- return;
-} /* edot */
-
-/**
-
-local recursive function used in the following ref contains the new
-position for each old index position
-
- at param e pointer to an evalue
- at param ref transformation Matrix
-
-*/
-static void aep_evalue(evalue *e, int *ref) {
-
- enode *p;
- int i;
-
- if (value_notzero_p(e->d))
- return; /* a rational number, its already reduced */
- if(!(p = e->x.p))
- return; /* hum... an overflow probably occured */
-
- /* First check the components of p */
- for (i=0;i<p->size;i++)
- aep_evalue(&p->arr[i],ref);
-
- /* Then p itself */
- p->pos = ref[p->pos-1]+1;
- return;
-} /* aep_evalue */
-
-/** Comments */
-static void addeliminatedparams_evalue(evalue *e,Matrix *CT) {
-
- enode *p;
- int i, j;
- int *ref;
-
- if (value_notzero_p(e->d))
- return; /* a rational number, its already reduced */
- if(!(p = e->x.p))
- return; /* hum... an overflow probably occured */
-
- /* Compute ref */
- ref = (int *)malloc(sizeof(int)*(CT->NbRows-1));
- for(i=0;i<CT->NbRows-1;i++)
- for(j=0;j<CT->NbColumns;j++)
- if(value_notzero_p(CT->p[i][j])) {
- ref[i] = j;
- break;
- }
-
- /* Transform the references in e, using ref */
- aep_evalue(e,ref);
- free( ref );
- return;
-} /* addeliminatedparams_evalue */
-
-/**
-
-This procedure finds an integer point contained in polyhedron D /
-first checks for positive values, then for negative values returns
-TRUE on success. Result is in min. returns FALSE if no integer point
-is found
-
-<p>
-
-This is the maximum number of iterations for a given parameter to find
-a integer point inside the context. Kind of weird. cherche_min should
-
-<p>
-
- at param min
- at param D
- at param pos
-
-*/
-/* FIXME: needs to be rewritten ! */
-#define MAXITER 100
-int cherche_min(Value *min,Polyhedron *D,int pos) {
-
- Value binf, bsup; /* upper & lower bound */
- Value i;
- int flag, maxiter;
-
- if(!D)
- return(1);
- if(pos > D->Dimension)
- return(1);
-
- value_init(binf); value_init(bsup);
- value_init(i);
-
-#ifdef EDEBUG61
- fprintf(stderr,"Entering Cherche min --> \n");
- fprintf(stderr,"LowerUpperBounds :\n");
- fprintf(stderr,"pos = %d\n",pos);
- fprintf(stderr,"current min = (");
- value_print(stderr,P_VALUE_FMT,min[1]);
- {int j;
- for(j=2;j<=D->Dimension ; j++) {
- fprintf(stderr,", ");
- value_print(stderr,P_VALUE_FMT,min[j]);
- }
- }
- fprintf(stderr,")\n");
-#endif
-
- flag = lower_upper_bounds(pos,D,min,&binf,&bsup);
-
-#ifdef EDEBUG61
- fprintf(stderr, "flag = %d\n", flag);
- fprintf(stderr,"binf = ");
- value_print(stderr,P_VALUE_FMT,binf);
- fprintf(stderr,"\n");
- fprintf(stderr,"bsup = ");
- value_print(stderr,P_VALUE_FMT,bsup);
- fprintf(stderr,"\n");
-#endif
-
- if(flag&LB_INFINITY)
- value_set_si(binf,0);
-
- /* Loop from 0 (or binf if positive) to bsup */
- for(maxiter=0,(((flag&LB_INFINITY) || value_neg_p(binf)) ?
- value_set_si(i,0) : value_assign(i,binf));
- ((flag&UB_INFINITY) || value_le(i,bsup)) && maxiter<MAXITER ;
- value_increment(i,i),maxiter++) {
-
- value_assign(min[pos],i);
- if(cherche_min(min,D->next,pos+1)) {
- value_clear(binf); value_clear(bsup);
- value_clear(i);
- return(1);
- }
- }
-
- /* Descending loop from -1 (or bsup if negative) to binf */
- if((flag&LB_INFINITY) || value_neg_p(binf))
- for(maxiter=0,(((flag&UB_INFINITY) || value_pos_p(bsup))?
- value_set_si(i,-1)
- :value_assign(i,bsup));
- ((flag&LB_INFINITY) || value_ge(i,binf)) && maxiter<MAXITER ;
- value_decrement(i,i),maxiter++) {
-
- value_assign(min[pos],i);
- if(cherche_min(min,D->next,pos+1)) {
- value_clear(binf); value_clear(bsup);
- value_clear(i);
- return(1);
- }
- }
- value_clear(binf); value_clear(bsup);
- value_clear(i);
-
- value_set_si(min[pos],0);
- return(0); /* not found :-( */
-} /* cherche_min */
-
-/**
-
-This procedure finds the smallest parallelepiped of size
-'<i>size[i]</i>' for every dimension i, contained in polyhedron D.
-If this is not possible, NULL is returned
-
-<p>
-
-<pre>
-written by vin100, 2000, for version 4.19
-modified 2002, version 5.10
-</pre>
-
-<p>
-
-It first finds the coordinates of the lexicographically smallest edge
-of the hypercube, obtained by transforming the constraints of D (by
-adding 'size' as many times as there are negative coeficients in each
-constraint), and finding the lexicographical min of this
-polyhedron. Then it builds the hypercube and returns it.
-
-<p>
- at param D
- at param size
- at param MAXRAYS
-
-*/
-
-Polyhedron *Polyhedron_Preprocess(Polyhedron *D,Value *size,unsigned MAXRAYS)
-{
- Matrix *M;
- int i, j, d;
- Polyhedron *T, *S, *H, *C;
- Value *min;
-
- d = D->Dimension;
- if (MAXRAYS < 2*D->NbConstraints)
- MAXRAYS = 2*D->NbConstraints;
- M = Matrix_Alloc(MAXRAYS, D->Dimension+2);
- M->NbRows = D->NbConstraints;
-
- /* Original constraints */
- for(i=0;i<D->NbConstraints;i++)
- Vector_Copy(D->Constraint[i],M->p[i],(d+2));
-
-#ifdef EDEBUG6
- fprintf(stderr,"M for PreProcess : ");
- Matrix_Print(stderr,P_VALUE_FMT,M);
- fprintf(stderr,"\nsize == ");
- for( i=0 ; i<d ; i++ )
- value_print(stderr,P_VALUE_FMT,size[i]);
- fprintf(stderr,"\n");
-#endif
-
- /* Additionnal constraints */
- for(i=0;i<D->NbConstraints;i++) {
- if(value_zero_p(D->Constraint[i][0])) {
- fprintf(stderr,"Polyhedron_Preprocess: ");
- fprintf(stderr,
- "an equality was found where I did expect an inequality.\n");
- fprintf(stderr,"Trying to continue...\n");
- continue;
- }
- Vector_Copy(D->Constraint[i],M->p[M->NbRows],(d+2));
- for(j=1;j<=d;j++)
- if(value_neg_p(D->Constraint[i][j])) {
- value_addmul(M->p[M->NbRows][d+1], D->Constraint[i][j], size[j-1]);
- }
-
- /* If anything changed, add this new constraint */
- if(value_ne(M->p[M->NbRows][d+1],D->Constraint[i][d+1]))
- M->NbRows ++ ;
- }
-
-#ifdef EDEBUG6
- fprintf(stderr,"M used to find min : ");
- Matrix_Print(stderr,P_VALUE_FMT,M);
-#endif
-
- T = Constraints2Polyhedron(M,MAXRAYS);
- Matrix_Free(M);
- if (!T || emptyQ(T)) {
- if(T)
- Polyhedron_Free(T);
- return(NULL);
- }
-
- /* Ok, now find the lexicographical min of T */
- min = (Value *) malloc(sizeof(Value) * (d+2));
- for(i=0;i<=d;i++) {
- value_init(min[i]);
- value_set_si(min[i],0);
- }
- value_init(min[i]);
- value_set_si(min[i],1);
- C = Universe_Polyhedron(0);
- S = Polyhedron_Scan(T,C,MAXRAYS);
- Polyhedron_Free(C);
- Polyhedron_Free(T);
-
-#ifdef EDEBUG6
- for(i=0;i<=(d+1);i++) {
- value_print(stderr,P_VALUE_FMT,min[i]);
- fprintf(stderr," ,");
- }
- fprintf(stderr,"\n");
- Polyhedron_Print(stderr,P_VALUE_FMT,S);
- fprintf(stderr,"\n");
-#endif
-
- if (!cherche_min(min,S,1))
- {
- for(i=0;i<=(d+1);i++)
- value_clear(min[i]);
- return(NULL);
- }
- Domain_Free(S);
-
-#ifdef EDEBUG6
- fprintf(stderr,"min = ( ");
- value_print(stderr,P_VALUE_FMT,min[1]);
- for(i=2;i<=d;i++) {
- fprintf(stderr,", ");
- value_print(stderr,P_VALUE_FMT,min[i]);
- }
- fprintf(stderr,")\n");
-#endif
-
- /* Min is the point from which we can construct the hypercube */
- M = Matrix_Alloc(d*2,d+2);
- for(i=0;i<d;i++) {
-
- /* Creates inequality 1 0..0 1 0..0 -min[i+1] */
- value_set_si(M->p[2*i][0],1);
- for(j=1;j<=d;j++)
- value_set_si(M->p[2*i][j],0);
- value_set_si(M->p[2*i][i+1],1);
- value_oppose(M->p[2*i][d+1],min[i+1]);
-
- /* Creates inequality 1 0..0 -1 0..0 min[i+1]+size -1 */
- value_set_si(M->p[2*i+1][0],1);
- for(j=1;j<=d;j++)
- value_set_si(M->p[2*i+1][j],0);
- value_set_si(M->p[2*i+1][i+1],-1);
- value_addto(M->p[2*i+1][d+1],min[i+1],size[i]);
- value_sub_int(M->p[2*i+1][d+1],M->p[2*i+1][d+1],1);
- }
-
-#ifdef EDEBUG6
- fprintf(stderr,"PolyhedronPreprocess: constraints H = ");
- Matrix_Print(stderr,P_VALUE_FMT,M);
-#endif
-
- H = Constraints2Polyhedron(M,MAXRAYS);
-
-#ifdef EDEBUG6
- Polyhedron_Print(stderr,P_VALUE_FMT,H);
- fprintf(stderr,"\n");
-#endif
-
- Matrix_Free(M);
- for(i=0;i<=(d+1);i++)
- value_clear(min[i]);
- free(min);
- assert(!emptyQ(H));
- return(H);
-} /* Polyhedron_Preprocess */
-
-
-/** This procedure finds an hypercube of size 'size', containing
-polyhedron D increases size and lcm if necessary (and not "too big")
-If this is not possible, an empty polyhedron is returned
-
-<p>
-
-<pre> written by vin100, 2001, for version 4.19</pre>
-
- at param D
- at param size
- at param lcm
- at param MAXRAYS
-
-*/
-Polyhedron *Polyhedron_Preprocess2(Polyhedron *D,Value *size,
- Value *lcm,unsigned MAXRAYS) {
-
- Matrix *c;
- Polyhedron *H;
- int i,j,r;
- Value n; /* smallest/biggest value */
- Value s; /* size in this dimension */
- Value tmp1,tmp2;
-
-#ifdef EDEBUG62
- int np;
-#endif
-
- value_init(n); value_init(s);
- value_init(tmp1); value_init(tmp2);
- c = Matrix_Alloc(D->Dimension*2,D->Dimension+2);
-
-#ifdef EDEBUG62
- fprintf(stderr,"\nPreProcess2 : starting\n");
- fprintf(stderr,"lcm = ");
- for( np=0 ; np<D->Dimension; np++ )
- value_print(stderr,VALUE_FMT,lcm[np]);
- fprintf(stderr,", size = ");
- for( np=0 ; np<D->Dimension; np++ )
- value_print(stderr,VALUE_FMT,size[np]);
- fprintf(stderr,"\n");
-#endif
-
- for(i=0;i<D->Dimension;i++) {
-
- /* Create constraint 1 0..0 1 0..0 -min */
- value_set_si(c->p[2*i][0],1);
- for(j=0;j<D->Dimension;j++)
- value_set_si(c->p[2*i][1+j],0);
- value_division(n,D->Ray[0][i+1],D->Ray[0][D->Dimension+1]);
- for(r=1;r<D->NbRays;r++) {
- value_division(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
- if(value_gt(n,tmp1)) {
-
- /* New min */
- value_division(n,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
- }
- }
- value_set_si(c->p[2*i][i+1],1);
- value_oppose(c->p[2*i][D->Dimension+1],n);
-
- /* Create constraint 1 0..0 -1 0..0 max */
- value_set_si(c->p[2*i+1][0],1);
- for(j=0;j<D->Dimension;j++)
- value_set_si(c->p[2*i+1][1+j],0);
-
- /* n = (num+den-1)/den */
- value_addto(tmp1,D->Ray[0][i+1],D->Ray[0][D->Dimension+1]);
- value_sub_int(tmp1,tmp1,1);
- value_division(n,tmp1,D->Ray[0][D->Dimension+1]);
- for(r=1;r<D->NbRays;r++) {
- value_addto(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
- value_sub_int(tmp1,tmp1,1);
- value_division(tmp1,tmp1,D->Ray[r][D->Dimension+1]);
- if (value_lt(n,tmp1)) {
-
- /* New max */
- value_addto(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
- value_sub_int(tmp1,tmp1,1);
- value_division(n,tmp1,D->Ray[r][D->Dimension+1]);
- }
- }
- value_set_si(c->p[2*i+1][i+1],-1);
- value_assign(c->p[2*i+1][D->Dimension+1],n);
- value_addto(s,c->p[2*i+1][D->Dimension+1],c->p[2*i][D->Dimension+1]);
-
- /* Now test if the dimension of the cube is greater than the size */
- if(value_gt(s,size[i])) {
-
-#ifdef EDEBUG62
- fprintf(stderr,"size on dimension %d\n",i);
- fprintf(stderr,"lcm = ");
- for( np=0 ; np<D->Dimension; np++ )
- value_print(stderr,VALUE_FMT,lcm[np]);
- fprintf(stderr,", size = ");
- for( np=0 ; np<D->Dimension; np++ )
- value_print(stderr,VALUE_FMT,size[np]);
- fprintf(stderr,"\n");
- fprintf(stderr,"required size (s) = ");
- value_print(stderr,VALUE_FMT,s);
- fprintf(stderr,"\n");
-#endif
-
- /* If the needed size is "small enough"(<=20 or less than
- twice *size),
- then increase *size, and artificially increase lcm too !*/
- value_set_si(tmp1,20);
- value_addto(tmp2,size[i],size[i]);
- if(value_le(s,tmp1)
- || value_le(s,tmp2)) {
-
- if( value_zero_p(lcm[i]) )
- value_set_si(lcm[i],1);
- /* lcm divides size... */
- value_division(tmp1,size[i],lcm[i]);
-
- /* lcm = ceil(s/h) */
- value_addto(tmp2,s,tmp1);
- value_add_int(tmp2,tmp2,1);
- value_division(lcm[i],tmp2,tmp1);
-
- /* new size = lcm*h */
- value_multiply(size[i],lcm[i],tmp1);
-
-#ifdef EDEBUG62
- fprintf(stderr,"new size = ");
- for( np=0 ; np<D->Dimension; np++ )
- value_print(stderr,VALUE_FMT,size[np]);
- fprintf(stderr,", new lcm = ");
- for( np=0 ; np<D->Dimension; np++ )
- value_print(stderr,VALUE_FMT,lcm[np]);
- fprintf(stderr,"\n");
-#endif
-
- }
- else {
-
-#ifdef EDEBUG62
- fprintf(stderr,"Failed on dimension %d.\n",i);
-#endif
- break;
- }
- }
- }
- if(i!=D->Dimension) {
- Matrix_Free(c);
- value_clear(n); value_clear(s);
- value_clear(tmp1); value_clear(tmp2);
- return(NULL);
- }
- for(i=0;i<D->Dimension;i++) {
- value_subtract(c->p[2*i+1][D->Dimension+1],size[i],
- c->p[2*i][D->Dimension+1]);
- }
-
-#ifdef EDEBUG62
- fprintf(stderr,"PreProcess2 : c =");
- Matrix_Print(stderr,P_VALUE_FMT,c);
-#endif
-
- H = Constraints2Polyhedron(c,MAXRAYS);
- Matrix_Free(c);
- value_clear(n); value_clear(s);
- value_clear(tmp1); value_clear(tmp2);
- return(H);
-} /* Polyhedron_Preprocess2 */
-
-/**
-
-This procedure adds additional constraints to D so that as each
-parameter is scanned, it will have a minimum of 'size' points If this
-is not possible, an empty polyhedron is returned
-
- at param D
- at param size
- at param MAXRAYS
-
-*/
-Polyhedron *old_Polyhedron_Preprocess(Polyhedron *D,Value size,
- unsigned MAXRAYS) {
-
- int p, p1, ub, lb;
- Value a, a1, b, b1, g, aa;
- Value abs_a, abs_b, size_copy;
- int dim, con, newi, needed;
- Value **C;
- Matrix *M;
- Polyhedron *D1;
-
- value_init(a); value_init(a1); value_init(b);
- value_init(b1); value_init(g); value_init(aa);
- value_init(abs_a); value_init(abs_b); value_init(size_copy);
-
- dim = D->Dimension;
- con = D->NbConstraints;
- M = Matrix_Alloc(MAXRAYS,dim+2);
- newi = 0;
- value_assign(size_copy,size);
- C = D->Constraint;
- for (p=1; p<=dim; p++) {
- for (ub=0; ub<con; ub++) {
- value_assign(a,C[ub][p]);
- if (value_posz_p(a)) /* a >= 0 */
- continue; /* not an upper bound */
- for (lb=0;lb<con;lb++) {
- value_assign(b,C[lb][p]);
- if (value_negz_p(b))
- continue; /* not a lower bound */
-
- /* Check if a new constraint is needed for this (ub,lb) pair */
- /* a constraint is only needed if a previously scanned */
- /* parameter (1..p-1) constrains this parameter (p) */
- needed=0;
- for (p1=1; p1<p; p1++) {
- if (value_notzero_p(C[ub][p1]) ||
- value_notzero_p(C[lb][p1])) {
- needed=1;
- break;
- }
- }
- if (!needed) continue;
- value_absolute(abs_a,a);
- value_absolute(abs_b,b);
-
- /* Create new constraint: b*UB-a*LB >= a*b*size */
- value_gcd(g, abs_a, abs_b);
- value_divexact(a1, a, g);
- value_divexact(b1, b, g);
- value_set_si(M->p[newi][0],1);
- value_oppose(abs_a,a1); /* abs_a = -a1 */
- Vector_Combine(&(C[ub][1]),&(C[lb][1]),&(M->p[newi][1]),
- b1,abs_a,dim+1);
- value_multiply(aa,a1,b1);
- value_addmul(M->p[newi][dim+1], aa, size_copy);
- Vector_Normalize(&(M->p[newi][1]),(dim+1));
- newi++;
- }
- }
- }
- D1 = AddConstraints(M->p_Init,newi,D,MAXRAYS);
- Matrix_Free(M);
-
- value_clear(a); value_clear(a1); value_clear(b);
- value_clear(b1); value_clear(g); value_clear(aa);
- value_clear(abs_a); value_clear(abs_b); value_clear(size_copy);
- return D1;
-} /* old_Polyhedron_Preprocess */
-
-/**
-
-PROCEDURES TO COMPUTE ENUMERATION. recursive procedure, recurse for
-each imbriquation
-
- at param pos index position of current loop index (1..hdim-1)
- at param P loop domain
- at param context context values for fixed indices
- at param res the number of integer points in this
-polyhedron
-
-*/
-void count_points (int pos,Polyhedron *P,Value *context, Value *res) {
-
- Value LB, UB, k, c;
-
- POL_ENSURE_FACETS(P);
- POL_ENSURE_VERTICES(P);
-
- if (emptyQ(P)) {
- value_set_si(*res, 0);
- return;
- }
-
- value_init(LB); value_init(UB); value_init(k);
- value_set_si(LB,0);
- value_set_si(UB,0);
-
- if (lower_upper_bounds(pos,P,context,&LB,&UB) !=0) {
-
- /* Problem if UB or LB is INFINITY */
- fprintf(stderr, "count_points: ? infinite domain\n");
- value_clear(LB); value_clear(UB); value_clear(k);
- value_set_si(*res, -1);
- return;
- }
-
-#ifdef EDEBUG1
- if (!P->next) {
- int i;
- for (value_assign(k,LB); value_le(k,UB); value_increment(k,k)) {
- fprintf(stderr, "(");
- for (i=1; i<pos; i++) {
- value_print(stderr,P_VALUE_FMT,context[i]);
- fprintf(stderr,",");
- }
- value_print(stderr,P_VALUE_FMT,k);
- fprintf(stderr,")\n");
- }
- }
-#endif
-
- value_set_si(context[pos],0);
- if (value_lt(UB,LB)) {
- value_clear(LB); value_clear(UB); value_clear(k);
- value_set_si(*res, 0);
- return;
- }
- if (!P->next) {
- value_subtract(k,UB,LB);
- value_add_int(k,k,1);
- value_assign(*res, k);
- value_clear(LB); value_clear(UB); value_clear(k);
- return;
- }
-
- /*-----------------------------------------------------------------*/
- /* Optimization idea */
- /* If inner loops are not a function of k (the current index) */
- /* i.e. if P->Constraint[i][pos]==0 for all P following this and */
- /* for all i, */
- /* Then CNT = (UB-LB+1)*count_points(pos+1, P->next, context) */
- /* (skip the for loop) */
- /*-----------------------------------------------------------------*/
-
- value_init(c);
- value_set_si(*res, 0);
- for (value_assign(k,LB);value_le(k,UB);value_increment(k,k)) {
- /* Insert k in context */
- value_assign(context[pos],k);
- count_points(pos+1,P->next,context,&c);
- if(value_notmone_p(c))
- value_addto(*res, *res, c);
- else {
- value_set_si(*res, -1);
- break;
- }
- }
- value_clear(c);
-
-#ifdef EDEBUG11
- fprintf(stderr,"%d\n",CNT);
-#endif
-
- /* Reset context */
- value_set_si(context[pos],0);
- value_clear(LB); value_clear(UB); value_clear(k);
- return;
-} /* count_points */
-
-/*-------------------------------------------------------------------*/
-/* enode *P_Enum(L, LQ, context, pos, nb_param, dim, lcm,param_name) */
-/* L : list of polyhedra for the loop nest */
-/* LQ : list of polyhedra for the parameter loop nest */
-/* pos : 1..nb_param, position of the parameter */
-/* nb_param : number of parameters total */
-/* dim : total dimension of the polyhedron, param incl. */
-/* lcm : denominator array [0..dim-1] of the polyhedron */
-/* param_name : name of the parameters */
-/* Returns an enode tree representing the pseudo polynomial */
-/* expression for the enumeration of the polyhedron. */
-/* A recursive procedure. */
-/*-------------------------------------------------------------------*/
-static enode *P_Enum(Polyhedron *L,Polyhedron *LQ,Value *context,int pos,
- int nb_param,int dim,Value *lcm, const char **param_name)
-{
- enode *res,*B,*C;
- int hdim,i,j,rank,flag;
- Value n,g,nLB,nUB,nlcm,noff,nexp,k1,nm,hdv,k,lcm_copy;
- Value tmp;
- Matrix *A;
-
-#ifdef EDEBUG
- fprintf(stderr,"-------------------- begin P_Enum -------------------\n");
- fprintf(stderr,"Calling P_Enum with pos = %d\n",pos);
-#endif
-
- /* Initialize all the 'Value' variables */
- value_init(n); value_init(g); value_init(nLB);
- value_init(nUB); value_init(nlcm); value_init(noff);
- value_init(nexp); value_init(k1); value_init(nm);
- value_init(hdv); value_init(k); value_init(tmp);
- value_init(lcm_copy);
-
- if( value_zero_p(lcm[pos-1]) )
- {
- hdim = 1;
- value_set_si( lcm_copy, 1 );
- }
- else
- {
- /* hdim is the degree of the polynomial + 1 */
- hdim = dim-nb_param+1; /* homogenous dim w/o parameters */
- value_assign( lcm_copy, lcm[pos-1] );
- }
-
- /* code to limit generation of equations to valid parameters only */
- /*----------------------------------------------------------------*/
- flag = lower_upper_bounds(pos,LQ,&context[dim-nb_param],&nLB,&nUB);
- if (flag & LB_INFINITY) {
- if (!(flag & UB_INFINITY)) {
-
- /* Only an upper limit: set lower limit */
- /* Compute nLB such that (nUB-nLB+1) >= (hdim*lcm) */
- value_sub_int(nLB,nUB,1);
- value_set_si(hdv,hdim);
- value_multiply(tmp,hdv,lcm_copy);
- value_subtract(nLB,nLB,tmp);
- if(value_pos_p(nLB))
- value_set_si(nLB,0);
- }
- else {
- value_set_si(nLB,0);
-
- /* No upper nor lower limit: set lower limit to 0 */
- value_set_si(hdv,hdim);
- value_multiply(nUB,hdv,lcm_copy);
- value_add_int(nUB,nUB,1);
- }
- }
-
- /* if (nUB-nLB+1) < (hdim*lcm) then we have more unknowns than equations */
- /* We can: 1. Find more equations by changing the context parameters, or */
- /* 2. Assign extra unknowns values in such a way as to simplify result. */
- /* Think about ways to scan parameter space to get as much info out of it*/
- /* as possible. */
-
-#ifdef REDUCE_DEGREE
- if (pos==1 && (flag & UB_INFINITY)==0) {
- /* only for finite upper bound on first parameter */
- /* NOTE: only first parameter because subsequent parameters may
- be artificially limited by the choice of the first parameter */
-
-#ifdef EDEBUG
- fprintf(stderr,"*************** n **********\n");
- value_print(stderr,VALUE_FMT,n);
- fprintf(stderr,"\n");
-#endif
-
- value_subtract(n,nUB,nLB);
- value_increment(n,n);
-
-#ifdef EDEBUG
- value_print(stderr,VALUE_FMT,n);
- fprintf(stderr,"\n*************** n ************\n");
-#endif
-
- /* Total number of samples>0 */
- if(value_neg_p(n))
- i=0;
- else {
- value_modulus(tmp,n,lcm_copy);
- if(value_notzero_p(tmp)) {
- value_division(tmp,n,lcm_copy);
- value_increment(tmp,tmp);
- i = VALUE_TO_INT(tmp);
- }
- else {
- value_division(tmp,n,lcm_copy);
- i = VALUE_TO_INT(tmp); /* ceiling of n/lcm */
- }
- }
-
-#ifdef EDEBUG
- value_print(stderr,VALUE_FMT,n);
- fprintf(stderr,"\n*************** n ************\n");
-#endif
-
- /* Reduce degree of polynomial based on number of sample points */
- if (i < hdim){
- hdim=i;
-
-#ifdef EDEBUG4
- fprintf(stdout,"Parameter #%d: LB=",pos);
- value_print(stdout,VALUE_FMT,nLB);
- fprintf(stdout," UB=");
- value_print(stdout,VALUE_FMT,nUB);
- fprintf(stdout," lcm=");
- value_print(stdout,VALUE_FMT,lcm_copy);
- fprintf(stdout," degree reduced to %d\n",hdim-1);
-#endif
-
- }
- }
-#endif /* REDUCE_DEGREE */
-
- /* hdim is now set */
- /* allocate result structure */
- res = new_enode(polynomial,hdim,pos);
- for (i=0;i<hdim;i++) {
- int l;
- l = VALUE_TO_INT(lcm_copy);
- res->arr[i].x.p = new_enode(periodic,l,pos);
- }
-
- /* Utility arrays */
- A = Matrix_Alloc(hdim, 2*hdim+1); /* used for Gauss */
- B = new_enode(evector, hdim, 0);
- C = new_enode(evector, hdim, 0);
-
- /* We'll create these again when we need them */
- for (j = 0; j < hdim; ++j)
- free_evalue_refs(&C->arr[j]);
-
- /*----------------------------------------------------------------*/
- /* */
- /* 0<-----+---k---------> */
- /* |---------noff----------------->-nlcm->-------lcm----> */
- /* |--- . . . -----|--------------|------+-------|------+-------|-*/
- /* 0 (q-1)*lcm q*lcm | (q+1)*lcm | */
- /* nLB nLB+lcm */
- /* */
- /*----------------------------------------------------------------*/
- if(value_neg_p(nLB)) {
- value_modulus(nlcm,nLB,lcm_copy);
- value_addto(nlcm,nlcm,lcm_copy);
- }
- else {
- value_modulus(nlcm,nLB,lcm_copy);
- }
-
- /* noff is a multiple of lcm */
- value_subtract(noff,nLB,nlcm);
- value_addto(tmp,lcm_copy,nlcm);
- for (value_assign(k,nlcm);value_lt(k,tmp);) {
-
-#ifdef EDEBUG
- fprintf(stderr,"Finding ");
- value_print(stderr,VALUE_FMT,k);
- fprintf(stderr,"-th elements of periodic coefficients\n");
-#endif
-
- value_set_si(hdv,hdim);
- value_multiply(nm,hdv,lcm_copy);
- value_addto(nm,nm,nLB);
- i=0;
- for (value_addto(n,k,noff); value_lt(n,nm);
- value_addto(n,n,lcm_copy),i++) {
-
- /* n == i*lcm + k + noff; */
- /* nlcm <= k < nlcm+lcm */
- /* n mod lcm == k1 */
-
-#ifdef ALL_OVERFLOW_WARNINGS
- if (((flag & UB_INFINITY)==0) && value_gt(n,nUB)) {
- fprintf(stdout,"Domain Overflow: Parameter #%d:",pos);
- fprintf(stdout,"nLB=");
- value_print(stdout,VALUE_FMT,nLB);
- fprintf(stdout," n=");
- value_print(stdout,VALUE_FMT,n);
- fprintf(stdout," nUB=");
- value_print(stdout,VALUE_FMT,nUB);
- fprintf(stdout,"\n");
- }
-#else
- if (overflow_warning_flag && ((flag & UB_INFINITY)==0) &&
- value_gt(n,nUB)) {
- fprintf(stdout,"\nWARNING: Parameter Domain Overflow.");
- fprintf(stdout," Result may be incorrect on this domain.\n");
- overflow_warning_flag = 0;
- }
-#endif
-
- /* Set parameter to n */
- value_assign(context[dim-nb_param+pos],n);
-
-#ifdef EDEBUG1
- if( param_name )
- {
- fprintf(stderr,"%s = ",param_name[pos-1]);
- value_print(stderr,VALUE_FMT,n);
- fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
- value_print(stderr,VALUE_FMT,lcm_copy);
- fprintf(stderr,")\n");
- }
- else
- {
- fprintf(stderr,"P%d = ",pos);
- value_print(stderr,VALUE_FMT,n);
- fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
- value_print(stderr,VALUE_FMT,lcm_copy);
- fprintf(stderr,")\n");
- }
-#endif
-
- /* Setup B vector */
- if (pos==nb_param) {
-
-#ifdef EDEBUG
- fprintf(stderr,"Yes\n");
-#endif
-
- /* call count */
- /* count can only be called when the context is fully specified */
- value_set_si(B->arr[i].d,1);
- value_init(B->arr[i].x.n);
- count_points(1,L,context,&B->arr[i].x.n);
-
-#ifdef EDEBUG3
- for (j=1; j<pos; j++) fputs(" ",stdout);
- fprintf(stdout, "E(");
- for (j=1; j<nb_param; j++) {
- value_print(stdout,VALUE_FMT,context[dim-nb_param+j]);
- fprintf(stdout,",");
- }
- value_print(stdout,VALUE_FMT,n);
- fprintf(stdout,") = ");
- value_print(stdout,VALUE_FMT,B->arr[i].x.n);
- fprintf(stdout," =");
-#endif
-
- }
- else { /* count is a function of other parameters */
- /* call P_Enum recursively */
- value_set_si(B->arr[i].d,0);
- B->arr[i].x.p = P_Enum(L,LQ->next,context,pos+1,
- nb_param,dim,lcm,param_name);
-
-#ifdef EDEBUG3
- if( param_name )
- {
- for (j=1; j<pos; j++)
- fputs(" ", stdout);
- fprintf(stdout, "E(");
- for (j=1; j<=pos; j++) {
- value_print(stdout,VALUE_FMT,context[dim-nb_param+j]);
- fprintf(stdout,",");
- }
- for (j=pos+1; j<nb_param; j++)
- fprintf(stdout,"%s,",param_name[j]);
- fprintf(stdout,"%s) = ",param_name[j]);
- print_enode(stdout,B->arr[i].x.p,param_name);
- fprintf(stdout," =");
- }
-#endif
-
- }
-
- /* Create i-th equation*/
- /* K_0 + K_1 * n**1 + ... + K_dim * n**dim | Identity Matrix */
-
- value_set_si(A->p[i][0],0); /* status bit = equality */
- value_set_si(nexp,1);
- for (j=1;j<=hdim;j++) {
- value_assign(A->p[i][j],nexp);
- value_set_si(A->p[i][j+hdim],0);
-
-#ifdef EDEBUG3
- fprintf(stdout," + ");
- value_print(stdout,VALUE_FMT,nexp);
- fprintf(stdout," c%d",j);
-#endif
- value_multiply(nexp,nexp,n);
- }
-
-#ifdef EDEBUG3
- fprintf(stdout, "\n");
-#endif
-
- value_set_si(A->p[i][i+1+hdim],1);
- }
-
- /* Assertion check */
- if (i!=hdim)
- fprintf(stderr, "P_Enum: ?expecting i==hdim\n");
-
-#ifdef EDEBUG
- if( param_name )
- {
- fprintf(stderr,"B (enode) =\n");
- print_enode(stderr,B,param_name);
- }
- fprintf(stderr,"A (Before Gauss) =\n");
- Matrix_Print(stderr,P_VALUE_FMT,A);
-#endif
-
- /* Solve hdim (=dim+1) equations with hdim unknowns, result in CNT */
- rank = Gauss(A,hdim,2*hdim);
-
-#ifdef EDEBUG
- fprintf(stderr,"A (After Gauss) =\n");
- Matrix_Print(stderr,P_VALUE_FMT,A);
-#endif
-
- /* Assertion check */
- if (rank!=hdim) {
- fprintf(stderr, "P_Enum: ?expecting rank==hdim\n");
- }
-
- /* if (rank < hdim) then set the last hdim-rank coefficients to ? */
- /* if (rank == 0) then set all coefficients to 0 */
- /* copy result as k1-th element of periodic numbers */
- if(value_lt(k,lcm_copy))
- value_assign(k1,k);
- else
- value_subtract(k1,k,lcm_copy);
-
- for (i=0; i<rank; i++) {
-
- /* Set up coefficient vector C from i-th row of inverted matrix */
- for (j=0; j<rank; j++) {
- value_gcd(g, A->p[i][i+1], A->p[i][j+1+hdim]);
- value_init(C->arr[j].d);
- value_divexact(C->arr[j].d, A->p[i][i+1], g);
- value_init(C->arr[j].x.n);
- value_divexact(C->arr[j].x.n, A->p[i][j+1+hdim], g);
- }
-
-#ifdef EDEBUG
- if( param_name )
- {
- fprintf(stderr, "C (enode) =\n");
- print_enode(stderr, C, param_name);
- }
-#endif
-
- /* The i-th enode is the lcm-periodic coefficient of term n**i */
- edot(B,C,&(res->arr[i].x.p->arr[VALUE_TO_INT(k1)]));
-
-#ifdef EDEBUG
- if( param_name )
- {
- fprintf(stderr, "B.C (evalue)=\n");
- print_evalue(stderr,&(res->arr[i].x.p->arr[VALUE_TO_INT(k1)]),
- param_name);
- fprintf(stderr,"\n");
- }
-#endif
-
- for (j = 0; j < rank; ++j)
- free_evalue_refs(&C->arr[j]);
- }
- value_addto(tmp,lcm_copy,nlcm);
-
- value_increment(k,k);
- for (i = 0; i < hdim; ++i) {
- free_evalue_refs(&B->arr[i]);
- if (value_lt(k,tmp))
- value_init(B->arr[i].d);
- }
- }
-
-#ifdef EDEBUG
- if( param_name )
- {
- fprintf(stderr,"res (enode) =\n");
- print_enode(stderr,res,param_name);
- }
- fprintf(stderr, "-------------------- end P_Enum -----------------------\n");
-#endif
-
- /* Reset context */
- value_set_si(context[dim-nb_param+pos],0);
-
- /* Release memory */
- Matrix_Free(A);
- free(B);
- free(C);
-
- /* Clear all the 'Value' variables */
- value_clear(n); value_clear(g); value_clear(nLB);
- value_clear(nUB); value_clear(nlcm); value_clear(noff);
- value_clear(nexp); value_clear(k1); value_clear(nm);
- value_clear(hdv); value_clear(k); value_clear(tmp);
- value_clear(lcm_copy);
- return res;
-} /* P_Enum */
-
-/*----------------------------------------------------------------*/
-/* Scan_Vertices(PP, Q, CT) */
-/* PP : ParamPolyhedron */
-/* Q : Domain */
-/* CT : Context transformation matrix */
-/* lcm : lcm array (output) */
-/* nbp : number of parameters */
-/* param_name : name of the parameters */
-/*----------------------------------------------------------------*/
-static void Scan_Vertices(Param_Polyhedron *PP,Param_Domain *Q,Matrix *CT,
- Value *lcm, int nbp, const char **param_name)
-{
- Param_Vertices *V;
- int i, j, ix, l, np;
- unsigned bx;
- Value k,m1;
-
- /* Compute the denominator of P */
- /* lcm = Least Common Multiple of the denominators of the vertices of P */
- /* and print the vertices */
-
- value_init(k); value_init(m1);
- for( np=0 ; np<nbp ; np++ )
- value_set_si( lcm[np], 0 );
-
- if( param_name )
- fprintf(stdout,"Vertices:\n");
-
- for(i=0,ix=0,bx=MSB,V=PP->V; V && i<PP->nbV; i++,V=V->next) {
- if (Q->F[ix] & bx) {
- if( param_name )
- {
- if(CT) {
- Matrix *v;
- v = VertexCT(V->Vertex,CT);
- Print_Vertex(stdout,v,param_name);
- Matrix_Free(v);
- }
- else
- Print_Vertex(stdout,V->Vertex,param_name);
- fprintf(stdout,"\n");
- }
-
- for(j=0;j<V->Vertex->NbRows;j++) {
- /* A matrix */
- for( l=0 ; l<V->Vertex->NbColumns-1 ; l++ )
- {
- if( value_notzero_p(V->Vertex->p[j][l]) )
- {
- value_gcd(m1, V->Vertex->p[j][V->Vertex->NbColumns-1],
- V->Vertex->p[j][l]);
- value_divexact(k, V->Vertex->p[j][V->Vertex->NbColumns-1], m1);
- if( value_notzero_p(lcm[l]) )
- {
- /* lcm[l] = lcm[l] * k / gcd(k,lcm[l]) */
- if (value_notzero_p(k) && value_notone_p(k))
- {
- value_gcd(m1, lcm[l], k);
- value_divexact(k, k, m1);
- value_multiply(lcm[l],lcm[l],k);
- }
- }
- else
- {
- value_assign(lcm[l],k);
- }
- }
- }
- }
- }
- NEXT(ix,bx);
- }
- value_clear(k); value_clear(m1);
-} /* Scan_Vertices */
-
-/**
-
-Procedure to count points in a non-parameterized polytope.
-
- at param P Polyhedron to count
- at param C Parameter Context domain
- at param CT Matrix to transform context to original
- at param CEq additionnal equalities in context
- at param MAXRAYS workspace size
- at param param_name parameter names
-
-*/
-Enumeration *Enumerate_NoParameters(Polyhedron *P,Polyhedron *C,
- Matrix *CT,Polyhedron *CEq,
- unsigned MAXRAYS, const char **param_name)
-{
- Polyhedron *L;
- Enumeration *res;
- Value *context;
- int j;
- int hdim = P->Dimension + 1;
- int r,i;
-
- /* Create a context vector size dim+2 */
- context = (Value *) malloc((hdim+1)*sizeof(Value));
- for (j=0;j<= hdim;j++)
- value_init(context[j]);
-
- res = (Enumeration *)malloc(sizeof(Enumeration));
- res->next = NULL;
- res->ValidityDomain = Universe_Polyhedron(0); /* no parameters */
- value_init(res->EP.d);
- value_set_si(res->EP.d,0);
- L = Polyhedron_Scan(P,res->ValidityDomain,MAXRAYS);
-
-#ifdef EDEBUG2
- fprintf(stderr, "L = \n");
- Polyhedron_Print(stderr, P_VALUE_FMT, L);
-#endif
-
- if(CT) {
- Polyhedron *Dt;
-
- /* Add parameters to validity domain */
- Dt = Polyhedron_Preimage(res->ValidityDomain,CT,MAXRAYS);
- Polyhedron_Free(res->ValidityDomain);
- res->ValidityDomain = DomainIntersection(Dt,CEq,MAXRAYS);
- Polyhedron_Free(Dt);
- }
-
- if( param_name )
- {
- fprintf(stdout,"---------------------------------------\n");
- fprintf(stdout,"Domain:\n");
- Print_Domain(stdout,res->ValidityDomain, param_name);
-
- /* Print the vertices */
- printf("Vertices:\n");
- for(r=0;r<P->NbRays;++r) {
- if(value_zero_p(P->Ray[r][0]))
- printf("(line) ");
- printf("[");
- if (P->Dimension > 0)
- value_print(stdout,P_VALUE_FMT,P->Ray[r][1]);
- for(i=1;i<P->Dimension;i++) {
- printf(", ");
- value_print(stdout,P_VALUE_FMT,P->Ray[r][i+1]);
- }
- printf("]");
- if(value_notone_p(P->Ray[r][P->Dimension+1])) {
- printf("/");
- value_print(stdout,P_VALUE_FMT, P->Ray[r][P->Dimension+1]);
- }
- printf("\n");
- }
- }
-
- res->EP.x.p = new_enode(polynomial,1,0);;
- value_set_si(res->EP.x.p->arr[0].d, 1);
- value_init(res->EP.x.p->arr[0].x.n);
-
- if (emptyQ(P)) {
- value_set_si(res->EP.x.p->arr[0].x.n, 0);
- } else if (!L) {
- /* Non-empty zero-dimensional domain */
- value_set_si(res->EP.x.p->arr[0].x.n, 1);
- } else {
- CATCH(overflow_error) {
- fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
- fprintf(stderr,"You should rebuild PolyLib using GNU-MP"
- " or increasing the size of integers.\n");
- overflow_warning_flag = 0;
- assert(overflow_warning_flag);
- }
- TRY {
-
- Vector_Set(context,0,(hdim+1));
-
- /* Set context[hdim] = 1 (the constant) */
- value_set_si(context[hdim],1);
- count_points(1, L, context, &res->EP.x.p->arr[0].x.n);
- UNCATCH(overflow_error);
- }
- }
-
- Domain_Free(L);
-
- /* **USELESS, there are no references to parameters in res**
- if( CT )
- addeliminatedparams_evalue(&res->EP, CT);
- */
-
- if( param_name )
- {
- fprintf(stdout,"\nEhrhart Polynomial:\n");
- print_evalue(stdout,&res->EP,param_name);
- fprintf(stdout, "\n");
- }
-
- for (j=0;j<= hdim;j++)
- value_clear(context[j]);
- free(context);
- return(res);
-} /* Enumerate_NoParameters */
-
-/** Procedure to count points in a parameterized polytope.
-
- at param Pi Polyhedron to enumerate
- at param C Context Domain
- at param MAXRAYS size of workspace
- at param param_name parameter names (array of strings), may be NULL
- at return a list of validity domains + evalues EP
-
-*/
-Enumeration *Polyhedron_Enumerate(Polyhedron *Pi,Polyhedron *C,
- unsigned MAXRAYS, const char **param_name)
-{
- Polyhedron *L, *CQ, *CQ2, *LQ, *U, *CEq, *rVD, *P, *Ph = NULL;
- Matrix *CT;
- Param_Polyhedron *PP;
- Param_Domain *Q;
- int i,hdim, dim, nb_param, np;
- Value *lcm, *m1, hdv;
- Value *context;
- Enumeration *en, *res;
-
- if (POL_ISSET(MAXRAYS, POL_NO_DUAL))
- MAXRAYS = 0;
-
- POL_ENSURE_FACETS(Pi);
- POL_ENSURE_VERTICES(Pi);
- POL_ENSURE_FACETS(C);
- POL_ENSURE_VERTICES(C);
-
- res = NULL;
- P = Pi;
-
-#ifdef EDEBUG2
- fprintf(stderr,"C = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,C);
- fprintf(stderr,"P = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,P);
-#endif
-
- hdim = P->Dimension + 1;
- dim = P->Dimension;
- nb_param = C->Dimension;
-
- /* Don't call Polyhedron2Param_Domain if there are no parameters */
- if(nb_param == 0) {
-
- return(Enumerate_NoParameters(P,C,NULL,NULL,MAXRAYS,param_name));
- }
- if(nb_param == dim) {
- res = (Enumeration *)malloc(sizeof(Enumeration));
- res->next = 0;
- res->ValidityDomain = DomainIntersection(P,C,MAXRAYS);
- value_init(res->EP.d);
- value_init(res->EP.x.n);
- value_set_si(res->EP.d,1);
- value_set_si(res->EP.x.n,1);
- if( param_name ) {
- fprintf(stdout,"---------------------------------------\n");
- fprintf(stdout,"Domain:\n");
- Print_Domain(stdout,res->ValidityDomain, param_name);
- fprintf(stdout,"\nEhrhart Polynomial:\n");
- print_evalue(stdout,&res->EP,param_name);
- fprintf(stdout, "\n");
- }
- return res;
- }
- PP = Polyhedron2Param_SimplifiedDomain(&P,C,MAXRAYS,&CEq,&CT);
- if(!PP) {
- if( param_name )
- fprintf(stdout, "\nEhrhart Polynomial:\nNULL\n");
-
- return(NULL);
- }
-
- /* CT : transformation matrix to eliminate useless ("false") parameters */
- if(CT) {
- nb_param -= CT->NbColumns-CT->NbRows;
- dim -= CT->NbColumns-CT->NbRows;
- hdim -= CT->NbColumns-CT->NbRows;
-
- /* Don't call Polyhedron2Param_Domain if there are no parameters */
- if(nb_param == 0) {
- res = Enumerate_NoParameters(P,C,CT,CEq,MAXRAYS,param_name);
- Param_Polyhedron_Free(PP);
- goto out;
- }
- }
-
- /* get memory for Values */
- lcm = (Value *)malloc((nb_param+1) * sizeof(Value));
- m1 = (Value *)malloc((nb_param+1) * sizeof(Value));
- /* Initialize all the 'Value' variables */
- for( np=0 ; np < nb_param+1; np++ )
- {
- value_init(lcm[np]); value_init(m1[np]);
- }
- value_init(hdv);
-
- for(Q=PP->D;Q;Q=Q->next) {
- int hom = 0;
- if(CT) {
- Polyhedron *Dt;
- CQ = Q->Domain;
- Dt = Polyhedron_Preimage(Q->Domain,CT,MAXRAYS);
- rVD = DomainIntersection(Dt,CEq,MAXRAYS);
-
- /* if rVD is empty or too small in geometric dimension */
- if(!rVD || emptyQ(rVD) ||
- (rVD->Dimension-rVD->NbEq < Dt->Dimension-Dt->NbEq-CEq->NbEq)) {
- if(rVD)
- Polyhedron_Free(rVD);
- Polyhedron_Free(Dt);
- Polyhedron_Free(CQ);
- continue; /* empty validity domain */
- }
- Polyhedron_Free(Dt);
- }
- else
- rVD = CQ = Q->Domain;
- en = (Enumeration *)malloc(sizeof(Enumeration));
- en->next = res;
- res = en;
- res->ValidityDomain = rVD;
-
- if( param_name ) {
- fprintf(stdout,"---------------------------------------\n");
- fprintf(stdout,"Domain:\n");
-
-#ifdef EPRINT_ALL_VALIDITY_CONSTRAINTS
- Print_Domain(stdout,res->ValidityDomain,param_name);
-#else
- {
- Polyhedron *VD;
- VD = DomainSimplify(res->ValidityDomain,C,MAXRAYS);
- Print_Domain(stdout,VD,param_name);
- Domain_Free(VD);
- }
-#endif /* EPRINT_ALL_VALIDITY_CONSTRAINTS */
- }
-
- overflow_warning_flag = 1;
-
- /* Scan the vertices and compute lcm */
- Scan_Vertices(PP,Q,CT,lcm,nb_param,param_name);
-
-#ifdef EDEBUG2
- fprintf(stderr,"Denominator = ");
- for( np=0;np<nb_param;np++)
- value_print(stderr,P_VALUE_FMT,lcm[np]);
- fprintf(stderr," and hdim == %d \n",hdim);
-#endif
-
-#ifdef EDEBUG2
- fprintf(stderr,"CQ = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
-#endif
-
- /* Before scanning, add constraints to ensure at least hdim*lcm */
- /* points in every dimension */
- value_set_si(hdv,hdim-nb_param);
-
- for( np=0;np<nb_param+1;np++) {
- if( value_notzero_p(lcm[np]) )
- value_multiply(m1[np],hdv,lcm[np]);
- else
- value_set_si(m1[np],1);
- }
-
-#ifdef EDEBUG2
- fprintf(stderr,"m1 == ");
- for( np=0;np<nb_param;np++)
- value_print(stderr,P_VALUE_FMT,m1[np]);
- fprintf(stderr,"\n");
-#endif
-
- CATCH(overflow_error) {
- fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
- CQ2 = NULL;
- }
- TRY {
- CQ2 = Polyhedron_Preprocess(CQ,m1,MAXRAYS);
-
-#ifdef EDEBUG2
- fprintf(stderr,"After preprocess, CQ2 = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
-#endif
-
- UNCATCH(overflow_error);
- }
-
- /* Vin100, Feb 2001 */
- /* in case of degenerate, try to find a domain _containing_ CQ */
- if ((!CQ2 || emptyQ(CQ2)) && CQ->NbBid==0) {
- int r;
-
-#ifdef EDEBUG2
- fprintf(stderr,"Trying to call Polyhedron_Preprocess2 : CQ = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
-#endif
-
- /* Check if CQ is bounded */
- for(r=0;r<CQ->NbRays;r++) {
- if(value_zero_p(CQ->Ray[r][0]) ||
- value_zero_p(CQ->Ray[r][CQ->Dimension+1]))
- break;
- }
- if(r==CQ->NbRays) {
-
- /* ok, CQ is bounded */
- /* now find if CQ is contained in a hypercube of size m1 */
- CQ2 = Polyhedron_Preprocess2(CQ,m1,lcm,MAXRAYS);
- }
- }
-
- if (!CQ2) {
- Polyhedron *tmp;
-#ifdef EDEBUG2
- fprintf(stderr,"Homogenize.\n");
-#endif
- hom = 1;
- tmp = homogenize(CQ, MAXRAYS);
- CQ2 = Polyhedron_Preprocess(tmp,m1,MAXRAYS);
- Polyhedron_Free(tmp);
- if (!Ph)
- Ph = homogenize(P, MAXRAYS);
- for (np=0; np < nb_param+1; np++)
- if (value_notzero_p(lcm[np]))
- value_addto(m1[np],m1[np],lcm[np]);
- }
-
- if (!CQ2 || emptyQ(CQ2)) {
-#ifdef EDEBUG2
- fprintf(stderr,"Degenerate.\n");
-#endif
- fprintf(stdout,"Degenerate Domain. Can not continue.\n");
- value_init(res->EP.d);
- value_init(res->EP.x.n);
- value_set_si(res->EP.d,1);
- value_set_si(res->EP.x.n,-1);
- }
- else {
-
-#ifdef EDEBUG2
- fprintf(stderr,"CQ2 = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
- if( ! PolyhedronIncludes(CQ, CQ2) )
- fprintf( stderr,"CQ does not include CQ2 !\n");
- else
- fprintf( stderr,"CQ includes CQ2.\n");
- if( ! PolyhedronIncludes(res->ValidityDomain, CQ2) )
- fprintf( stderr,"CQ2 is *not* included in validity domain !\n");
- else
- fprintf( stderr,"CQ2 is included in validity domain.\n");
-#endif
-
- /* L is used in counting the number of points in the base cases */
- L = Polyhedron_Scan(hom ? Ph : P,CQ2,MAXRAYS);
- U = Universe_Polyhedron(0);
-
- /* LQ is used to scan the parameter space */
- LQ = Polyhedron_Scan(CQ2,U,MAXRAYS); /* bounds on parameters */
- Domain_Free(U);
- if(CT) /* we did compute another Q->Domain */
- Domain_Free(CQ);
-
- /* Else, CQ was Q->Domain (used in res) */
- Domain_Free(CQ2);
-
-#ifdef EDEBUG2
- fprintf(stderr,"L = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,L);
- fprintf(stderr,"LQ = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,LQ);
-#endif
-#ifdef EDEBUG3
- fprintf(stdout,"\nSystem of Equations:\n");
-#endif
-
- value_init(res->EP.d);
- value_set_si(res->EP.d,0);
-
- /* Create a context vector size dim+2 */
- context = (Value *) malloc ((hdim+1+hom)*sizeof(Value));
- for(i=0;i<=(hdim+hom);i++)
- value_init(context[i]);
- Vector_Set(context,0,(hdim+1+hom));
-
- /* Set context[hdim] = 1 (the constant) */
- value_set_si(context[hdim+hom],1);
-
- CATCH(overflow_error) {
- fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
- fprintf(stderr,"You should rebuild PolyLib using GNU-MP "
- "or increasing the size of integers.\n");
- overflow_warning_flag = 0;
- assert(overflow_warning_flag);
-
- }
- TRY {
- res->EP.x.p = P_Enum(L,LQ,context,1,nb_param+hom,
- dim+hom,lcm,param_name);
- UNCATCH(overflow_error);
- }
- if (hom)
- dehomogenize_evalue(&res->EP, nb_param+1);
-
- for(i=0;i<=(hdim+hom);i++)
- value_clear(context[i]);
- free(context);
- Domain_Free(L);
- Domain_Free(LQ);
-
-#ifdef EDEBUG5
- if( param_name )
- {
- fprintf(stdout,"\nEhrhart Polynomial (before simplification):\n");
- print_evalue(stdout,&res->EP,param_name);
- }
-#endif
-
- /* Try to simplify the result */
- reduce_evalue(&res->EP);
-
- /* Put back the original parameters into result */
- /* (equalities have been eliminated) */
- if(CT)
- addeliminatedparams_evalue(&res->EP,CT);
-
- if (param_name) {
- fprintf(stdout,"\nEhrhart Polynomial:\n");
- print_evalue(stdout,&res->EP, param_name);
- fprintf(stdout,"\n");
- /* sometimes the final \n lacks (when a single constant is printed) */
- }
-
- }
- }
-
- if (Ph)
- Polyhedron_Free(Ph);
- /* Clear all the 'Value' variables */
- for (np=0; np < nb_param+1; np++)
- {
- value_clear(lcm[np]); value_clear(m1[np]);
- }
- value_clear(hdv);
- free(lcm);
- free(m1);
- /* We can't simply call Param_Polyhedron_Free because we've reused the domains */
- Param_Vertices_Free(PP->V);
- while (PP->D) {
- Q = PP->D;
- PP->D = PP->D->next;
- free(Q->F);
- free(Q);
- }
- free(PP);
-
-out:
- if (CEq)
- Polyhedron_Free(CEq);
- if (CT)
- Matrix_Free(CT);
- if( P != Pi )
- Polyhedron_Free( P );
-
- return res;
-} /* Polyhedron_Enumerate */
-
-void Enumeration_Free(Enumeration *en)
-{
- Enumeration *ee;
-
- while( en )
- {
- free_evalue_refs( &(en->EP) );
- Domain_Free( en->ValidityDomain );
- ee = en ->next;
- free( en );
- en = ee;
- }
-}
-
-/* adds by B. Meister for Ehrhart Polynomial approximation */
-
-/**
- * Divides the evalue e by the integer n<br/>
- * recursive function<br/>
- * Warning : modifies e
- * @param e an evalue (to be divided by n)
- * @param n
- */
-
-void evalue_div(evalue * e, Value n) {
- int i;
- Value gc;
- value_init(gc);
- if (value_zero_p(e->d)) {
- for (i=0; i< e->x.p->size; i++) {
- evalue_div(&(e->x.p->arr[i]), n);
- }
- }
- else {
- value_multiply(e->d, e->d, n);
- /* simplify the new rational if needed */
- value_gcd(gc, e->x.n, e->d);
- if (value_notone_p(gc)) {
- value_divexact(e->d, e->d, gc);
- value_divexact(e->x.n, e->x.n, gc);
- }
- }
- value_clear(gc);
-} /* evalue_div */
-
-
-/**
-
-Ehrhart_Quick_Apx_Full_Dim(P, C, MAXRAYS, param_names)
-
-Procedure to estimate the number of points in a parameterized polytope.
-Returns a list of validity domains + evalues EP
-B.M.
-The most rough and quick approximation by variables expansion
-Deals with the full-dimensional case.
- at param Pi : Polyhedron to enumerate (approximatively)
- at param C : Context Domain
- at param MAXRAYS : size of workspace
- at param param_name : names for the parameters (char strings)
-
-*/
-Enumeration *Ehrhart_Quick_Apx_Full_Dim(Polyhedron *Pi,Polyhedron *C,
- unsigned MAXRAYS, const char **param_name)
-{
- Polyhedron *L, *CQ, *CQ2, *LQ, *U, *CEq, *rVD, *P;
- Matrix *CT;
- Param_Polyhedron *PP;
- Param_Domain *Q;
- int i,j,hdim, dim, nb_param, np;
- Value *lcm, *m1, hdv;
- Value *context;
- Enumeration *en, *res;
- Value expansion_det;
- Polyhedron * Expanded;
-
- /* used to scan the vertices */
- Param_Vertices * V_tmp;
-
- res = NULL;
- P = Pi;
-
- value_init(expansion_det);
-
-#ifdef EDEBUG2
- fprintf(stderr,"C = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,C);
- fprintf(stderr,"P = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,P);
-#endif
-
- hdim = P->Dimension + 1;
- dim = P->Dimension;
- nb_param = C->Dimension;
-
- /* Don't call Polyhedron2Param_Domain if there are no parameters */
- if(nb_param == 0) {
-
- return(Enumerate_NoParameters(P,C,NULL,NULL,MAXRAYS, param_name));
- }
-
-#if EDEBUG2
- printf("Enumerating polyhedron : \n");
- Polyhedron_Print(stdout, P_VALUE_FMT, P);
-#endif
-
- PP = Polyhedron2Param_SimplifiedDomain(&P,C,MAXRAYS,&CEq,&CT);
- if(!PP) {
- if( param_name )
- fprintf(stdout, "\nEhrhart Polynomial:\nNULL\n");
-
- return(NULL);
- }
-
- /* CT : transformation matrix to eliminate useless ("false") parameters */
- if(CT) {
- nb_param -= CT->NbColumns-CT->NbRows;
- dim -= CT->NbColumns-CT->NbRows;
- hdim -= CT->NbColumns-CT->NbRows;
-
- /* Don't call Polyhedron2Param_Domain if there are no parameters */
- if(nb_param == 0)
- {
- res = Enumerate_NoParameters(P,C,CT,CEq,MAXRAYS,param_name);
- if( P != Pi )
- Polyhedron_Free( P );
- return( res );
- }
- }
-
- if (!PP->nbV)
- /* Leaks memory */
- return NULL;
-
- /* get memory for Values */
- lcm = (Value *)malloc( nb_param * sizeof(Value));
- m1 = (Value *)malloc( nb_param * sizeof(Value));
- /* Initialize all the 'Value' variables */
- for( np=0 ; np<nb_param ; np++ )
- {
- value_init(lcm[np]); value_init(m1[np]);
- }
- value_init(hdv);
-
-#if EDEBUG2
- Polyhedron_Print(stderr, P_VALUE_FMT, P);
-#endif
-
- Expanded = P;
- Param_Polyhedron_Scale_Integer(PP, &Expanded, &expansion_det, MAXRAYS);
-
-#if EDEBUG2
- Polyhedron_Print(stderr, P_VALUE_FMT, Expanded);
-#endif
-
- if (P != Expanded)
- Polyhedron_Free(P);
- P = Expanded;
-
- /* formerly : Scan the vertices and compute lcm
- Scan_Vertices_Quick_Apx(PP,Q,CT,lcm,nb_param); */
- /* now : lcm = 1 (by construction) */
- /* OPT : A lot among what happens after this point can be simplified by
- knowing that lcm[i] = 1 for now, we just conservatively fool the rest of
- the function with lcm = 1 */
- for (i=0; i< nb_param; i++) value_set_si(lcm[i], 1);
-
- for(Q=PP->D;Q;Q=Q->next) {
- if(CT) {
- Polyhedron *Dt;
- CQ = Q->Domain;
- Dt = Polyhedron_Preimage(Q->Domain,CT,MAXRAYS);
- rVD = DomainIntersection(Dt,CEq,MAXRAYS);
-
- /* if rVD is empty or too small in geometric dimension */
- if(!rVD || emptyQ(rVD) ||
- (rVD->Dimension-rVD->NbEq < Dt->Dimension-Dt->NbEq-CEq->NbEq)) {
- if(rVD)
- Polyhedron_Free(rVD);
- Polyhedron_Free(Dt);
- continue; /* empty validity domain */
- }
- Polyhedron_Free(Dt);
- }
- else
- rVD = CQ = Q->Domain;
- en = (Enumeration *)malloc(sizeof(Enumeration));
- en->next = res;
- res = en;
- res->ValidityDomain = rVD;
-
- if( param_name )
- {
- fprintf(stdout,"---------------------------------------\n");
- fprintf(stdout,"Domain:\n");
-
-#ifdef EPRINT_ALL_VALIDITY_CONSTRAINTS
- Print_Domain(stdout,res->ValidityDomain,param_name);
-#else
- {
- Polyhedron *VD;
- VD = DomainSimplify(res->ValidityDomain,C,MAXRAYS);
- Print_Domain(stdout,VD,param_name);
- Domain_Free(VD);
- }
-#endif /* EPRINT_ALL_VALIDITY_CONSTRAINTS */
- }
-
- overflow_warning_flag = 1;
-
-#ifdef EDEBUG2
- fprintf(stderr,"Denominator = ");
- for( np=0;np<nb_param;np++)
- value_print(stderr,P_VALUE_FMT,lcm[np]);
- fprintf(stderr," and hdim == %d \n",hdim);
-#endif
-
-#ifdef EDEBUG2
- fprintf(stderr,"CQ = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
-#endif
-
- /* Before scanning, add constraints to ensure at least hdim*lcm */
- /* points in every dimension */
- value_set_si(hdv,hdim-nb_param);
-
- for( np=0;np<nb_param;np++)
- {
- if( value_notzero_p(lcm[np]) )
- value_multiply(m1[np],hdv,lcm[np]);
- else
- value_set_si(m1[np],1);
- }
-
-#ifdef EDEBUG2
- fprintf(stderr,"m1 == ");
- for( np=0;np<nb_param;np++)
- value_print(stderr,P_VALUE_FMT,m1[np]);
- fprintf(stderr,"\n");
-#endif
-
- CATCH(overflow_error) {
- fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
- CQ2 = NULL;
- }
- TRY {
- CQ2 = Polyhedron_Preprocess(CQ,m1,MAXRAYS);
-
-#ifdef EDEBUG2
- fprintf(stderr,"After preprocess, CQ2 = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
-#endif
-
- UNCATCH(overflow_error);
- }
-
- /* Vin100, Feb 2001 */
- /* in case of degenerate, try to find a domain _containing_ CQ */
- if ((!CQ2 || emptyQ(CQ2)) && CQ->NbBid==0) {
- int r;
-
-#ifdef EDEBUG2
- fprintf(stderr,"Trying to call Polyhedron_Preprocess2 : CQ = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
-#endif
-
- /* Check if CQ is bounded */
- for(r=0;r<CQ->NbRays;r++) {
- if(value_zero_p(CQ->Ray[r][0]) ||
- value_zero_p(CQ->Ray[r][CQ->Dimension+1]))
- break;
- }
- if(r==CQ->NbRays) {
-
- /* ok, CQ is bounded */
- /* now find if CQ is contained in a hypercube of size m1 */
- CQ2 = Polyhedron_Preprocess2(CQ,m1,lcm,MAXRAYS);
- }
- }
- if (!CQ2 || emptyQ(CQ2)) {
-#ifdef EDEBUG2
- fprintf(stderr,"Degenerate.\n");
-#endif
- fprintf(stdout,"Degenerate Domain. Can not continue.\n");
- value_init(res->EP.d);
- value_init(res->EP.x.n);
- value_set_si(res->EP.d,1);
- value_set_si(res->EP.x.n,-1);
- }
- else {
-
-#ifdef EDEBUG2
- fprintf(stderr,"CQ2 = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
- if( ! PolyhedronIncludes(CQ, CQ2) )
- fprintf( stderr,"CQ does not include CQ2 !\n");
- else
- fprintf( stderr,"CQ includes CQ2.\n");
- if( ! PolyhedronIncludes(res->ValidityDomain, CQ2) )
- fprintf( stderr,"CQ2 is *not* included in validity domain !\n");
- else
- fprintf( stderr,"CQ2 is included in validity domain.\n");
-#endif
-
- /* L is used in counting the number of points in the base cases */
- L = Polyhedron_Scan(P,CQ,MAXRAYS);
- U = Universe_Polyhedron(0);
-
- /* LQ is used to scan the parameter space */
- LQ = Polyhedron_Scan(CQ2,U,MAXRAYS); /* bounds on parameters */
- Domain_Free(U);
- if(CT) /* we did compute another Q->Domain */
- Domain_Free(CQ);
-
- /* Else, CQ was Q->Domain (used in res) */
- Domain_Free(CQ2);
-
-#ifdef EDEBUG2
- fprintf(stderr,"L = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,L);
- fprintf(stderr,"LQ = \n");
- Polyhedron_Print(stderr,P_VALUE_FMT,LQ);
-#endif
-#ifdef EDEBUG3
- fprintf(stdout,"\nSystem of Equations:\n");
-#endif
-
- value_init(res->EP.d);
- value_set_si(res->EP.d,0);
-
- /* Create a context vector size dim+2 */
- context = (Value *) malloc ((hdim+1)*sizeof(Value));
- for(i=0;i<=(hdim);i++)
- value_init(context[i]);
- Vector_Set(context,0,(hdim+1));
-
- /* Set context[hdim] = 1 (the constant) */
- value_set_si(context[hdim],1);
-
- CATCH(overflow_error) {
- fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
- fprintf(stderr,"You should rebuild PolyLib using GNU-MP "
- "or increasing the size of integers.\n");
- overflow_warning_flag = 0;
- assert(overflow_warning_flag);
-
- }
- TRY {
- res->EP.x.p = P_Enum(L,LQ,context,1,nb_param,dim,lcm, param_name);
- UNCATCH(overflow_error);
- }
-
- for(i=0;i<=(hdim);i++)
- value_clear(context[i]);
- free(context);
- Domain_Free(L);
- Domain_Free(LQ);
-
-#ifdef EDEBUG5
- if( param_name )
- {
- fprintf(stdout,"\nEhrhart Polynomial (before simplification):\n");
- print_evalue(stdout,&res->EP,param_name);
- }
-
- /* BM: divide EP by denom_det, the expansion factor */
- fprintf(stdout,"\nEhrhart Polynomial (before division):\n");
- print_evalue(stdout,&(res->EP),param_name);
-#endif
-
- evalue_div(&(res->EP), expansion_det);
-
-
- /* Try to simplify the result */
- reduce_evalue(&res->EP);
-
- /* Put back the original parameters into result */
- /* (equalities have been eliminated) */
- if(CT)
- addeliminatedparams_evalue(&res->EP,CT);
-
- if( param_name )
- {
- fprintf(stdout,"\nEhrhart Polynomial:\n");
- print_evalue(stdout,&res->EP, param_name);
- fprintf(stdout,"\n");
- /* sometimes the final \n lacks (when a single constant is printed)
- */
- }
-
- }
- }
- value_clear(expansion_det);
-
- if( P != Pi )
- Polyhedron_Free( P );
- /* Clear all the 'Value' variables */
- for( np=0; np<nb_param ; np++ )
- {
- value_clear(lcm[np]); value_clear(m1[np]);
- }
- value_clear(hdv);
-
- return res;
-} /* Ehrhart_Quick_Apx_Full_Dim */
-
-
-/**
- * Computes the approximation of the Ehrhart polynomial of a polyhedron
- * (implicit form -> matrix), treating the non-full-dimensional case.
- * @param M a polyhedron under implicit form
- * @param C M's context under implicit form
- * @param Validity_Lattice a pointer to the parameter's validity lattice
- * @param MAXRAYS the needed "working space" for other polylib functions used here
- * @param param_name the names of the parameters,
- */
-Enumeration *Ehrhart_Quick_Apx(Matrix * M, Matrix * C,
- Matrix **Validity_Lattice, unsigned maxRays) {
- /* char ** param_name) {*/
-
- /* 0- compute a full-dimensional polyhedron with the same number of points,
- and its parameter's validity lattice */
- Matrix * M_full;
- Polyhedron * P, * PC;
- Enumeration *en;
-
- M_full = full_dimensionize(M, C->NbColumns-2, Validity_Lattice);
-
-
-
- // DEBUG REPAIR
- if (M_full == NULL)
- return NULL;
-
-
-
-
- /* 1- apply the same tranformation to the context that what has been applied
- to the parameters space of the polyhedron. */
- mpolyhedron_compress_last_vars(C, *Validity_Lattice);
-
-
-
-
-
-
- // OUTPUT REMOVED
- //show_matrix(M_full);
-
-
-
-
-
-
-
-
-
- P = Constraints2Polyhedron(M_full, maxRays);
- PC = Constraints2Polyhedron(C, maxRays);
- Matrix_Free(M_full);
- /* compute the Ehrhart polynomial of the "equivalent" polyhedron */
- en = Ehrhart_Quick_Apx_Full_Dim(P, PC, maxRays, NULL);
-
- /* clean up */
- Polyhedron_Free(P);
- Polyhedron_Free(PC);
- return en;
-} /* Ehrhart_Quick_Apx */
-
-
-
-/**
- * Computes the approximation of the Ehrhart polynomial of a polyhedron (implicit
- * form -> matrix), treating the non-full-dimensional case. If there are some
- * equalities involving only parameters, these are used to eliminate useless
- * parameters.
- * @param M a polyhedron under implicit form
- * @param C M's context under implicit form
- * @param validityLattice a pointer to the parameter's validity lattice
- * (returned)
- * @param parmsEqualities Equalities involving only the parameters
- * @param maxRays the needed "working space" for other polylib functions used here
- * @param elimParams array of the indices of the eliminated parameters (returned)
- */
-Enumeration *Constraints_EhrhartQuickApx(Matrix const * M, Matrix const * C,
- Matrix ** validityLattice,
- Matrix ** parmEqualities,
- unsigned int ** elimParms,
- unsigned maxRays) {
- Enumeration *EP;
- Matrix * Mp = Matrix_Copy(M);
- Matrix * Cp = Matrix_Copy(C);
- /* remove useless equalities involving only parameters, using these
- equalities to remove parameters. */
- (*parmEqualities) = Constraints_Remove_parm_eqs(&Mp, &Cp, 0, elimParms);
- if (Mp->NbRows>=0) {/* if there is no contradiction */
- EP = Ehrhart_Quick_Apx(Mp, Cp, validityLattice, maxRays);
- return EP;
- }
- else {
- /* if there are contradictions, return a zero Ehrhart polynomial */
- return NULL;
- }
-
-}
-
-
-/**
- * Returns the array of parameter names after some of them have been eliminated.
- * @param parmNames the initial names of the parameters
- * @param elimParms a list of parameters that have been eliminated from the
- * original parameters. The first element of this array is the number of
- * elements.
- * <p> Note: does not copy the parameters names themselves. </p>
- * @param nbParms the initial number of parameters
-*/
-const char **parmsWithoutElim(char const **parmNames,
- unsigned int const *elimParms,
- unsigned int nbParms)
-{
- int i=0, j=0,k;
- int newParmNb = nbParms - elimParms[0];
- const char **newParmNames = (const char **)malloc(newParmNb * sizeof(char *));
- for (k=1; k<= elimParms[0]; k++) {
- while (i!=elimParms[k]) {
- newParmNames[i-k+1] = parmNames[i];
- i++;
- }
- }
- return newParmNames;
-}
-
-
-/**
- * returns a constant Ehrhart polynomial whose value is zero for any value of
- * the parameters.
- * @param nbParms the number of parameters, i.e., the number of arguments to
- * the Ehrhart polynomial
- */
-Enumeration * Enumeration_zero(unsigned int nbParms, unsigned int maxRays) {
- Matrix * Mz = Matrix_Alloc(1, nbParms+3);
- Polyhedron * emptyP;
- Polyhedron * universe;
- Enumeration * zero;
- /* 1- build an empty polyhedron with the right dimension */
- /* here we choose to take 2i = -1 */
- value_set_si(Mz->p[0][1], 2);
- value_set_si(Mz->p[0][nbParms+2], 1);
- emptyP = Constraints2Polyhedron(Mz, maxRays);
- Matrix_Free(Mz);
- universe = Universe_Polyhedron(nbParms);
- zero = Polyhedron_Enumerate(emptyP, universe, maxRays, NULL);
- Polyhedron_Free(emptyP);
- Polyhedron_Free(universe);
- return zero;
-} /* Enumeration_zero() */
-
diff --git a/source/polylib_mod/errormsg.c b/source/polylib_mod/errormsg.c
deleted file mode 100644
index 726b3ae..0000000
--- a/source/polylib_mod/errormsg.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* errormsg.c
- COPYRIGHT
- Both this software and its documentation are
-
- Copyright 1993 by IRISA /Universite de Rennes I - France,
- Copyright 1995,1996 by BYU, Provo, Utah
- all rights reserved.
-
- Permission is granted to copy, use, and distribute
- for any commercial or noncommercial purpose under the terms
- of the GNU General Public license, version 2, June 1991
- (see file : LICENSING).
-*/
-
-#include <stdio.h>
-#include <polylib/polylib.h>
-
-extern int Pol_status;
-
-/* This function allows either error messages to be sent to Mathematica,
- or messages to be printed to stderr.
-
- If MATHLINK is defined, then a command Message[f::msgname] is sent to
- Mathematica. If not, one prints on stderr. The difference with errormsg
- is that the control should be returned immediately to Mathematica after
- the call to errormsg1. Therefore, no Compound statement is sent to
- Mathematica.
-*/
-void errormsg1(const char *f, const char *msgname, const char *msg)
-{
- Pol_status = 1;
-
-#ifdef MATHLINK
- MLPutFunction(stdlink,"Message",1);
- MLPutFunction(stdlink,"MessageName",2);
- MLPutSymbol(stdlink,f);
- MLPutString(stdlink,msgname);
-#else
-#ifndef NO_MESSAGES
- fprintf(stderr, "?%s: %s\n", f, msg);
-#endif
-#endif
-
-}
diff --git a/source/polylib_mod/errors.c b/source/polylib_mod/errors.c
deleted file mode 100644
index 0c2e608..0000000
--- a/source/polylib_mod/errors.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- $Id: errors.c,v 1.6 2006/03/15 19:59:37 verdoolaege Exp $
-
- Exception management.
- See "arithmetic_errors.h".
-
- $Log: errors.c,v $
- Revision 1.6 2006/03/15 19:59:37 verdoolaege
- arith: add some missing consts
-
- Revision 1.5 2004/08/31 18:01:56 verdoolaege
- remove warning
-
- Revision 1.4 2004/02/11 10:19:54 verdoolaege
- add const qualifier
-
- Revision 1.3 2004/02/08 21:53:27 kienhuis
- Update from Fabien Coelho, via Bart Kienhuis
-
- I've updated here in the C3/Linear library the arithmetic_error
- package that I developped (with others) to handle exceptions in C.
- It adds a simple callback feature which is needed for pips here.
- If you do not use it, it should not harm;-)
-
- Revision 1.27 2003/09/04 09:40:37 coelho
- init added.
- verbosity mask added.
-
- Revision 1.26 2003/09/03 14:05:20 coelho
- push/pop callbacks called.
-
- Revision 1.20 2003/08/18 09:55:09 coelho
- get_exception_name added...
-
- Revision 1.19 2003/06/13 13:59:07 coelho
- const out.
-
- Revision 1.18 2003/06/13 13:54:47 coelho
- hop.
-
- Revision 1.17 2002/04/02 08:44:54 coelho
- timeout_error ajoute.
-
- Revision 1.16 2000/10/27 13:26:03 ancourt
- exception_thrown -> linear_number_of_exception_thrown
-
- Revision 1.15 2000/07/27 15:21:55 coelho
- message++
-
- Revision 1.14 2000/07/27 14:59:59 coelho
- trace added.
-
- Revision 1.13 2000/07/26 08:41:23 coelho
- the_last_just_thrown_exception management added.
-
- Revision 1.12 1998/10/26 18:48:34 coelho
- message++.
-
- Revision 1.11 1998/10/26 14:38:06 coelho
- constants back in.
-
- Revision 1.10 1998/10/26 14:35:47 coelho
- constants in .h.
-
- Revision 1.9 1998/10/24 15:36:22 coelho
- better exception error messages...
-
- Revision 1.8 1998/10/24 15:19:17 coelho
- more verbose throw...
-
- Revision 1.7 1998/10/24 14:31:13 coelho
- new stack implementation.
- checks for matching catch/uncatch.
- debug mode.
-
- Revision 1.6 1998/10/24 09:31:06 coelho
- RCS headers.
- 'const' tried.
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "arithmetique.h"
-
-/* global constants to designate exceptions.
- to be put in the type field bellow.
- cproto 4.6 does not line 'const'...
-*/
-unsigned int overflow_error = 1;
-unsigned int simplex_arithmetic_error = 2;
-unsigned int user_exception_error = 4;
-unsigned int parser_exception_error = 8;
-unsigned int timeout_error = 16;
-
-/* catch all */
-unsigned int any_exception_error = ~0;
-
-
-/*
- * On a few systems, type boolean and/or its values FALSE, TRUE may appear
- * in standard header files. Or you may have conflicts with application-
- * specific header files that you want to include together with these files.
- * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
- */
-
-#ifndef HAVE_BOOLEAN
-typedef int boolean;
-#endif
-#ifndef FALSE /* in case these macros already exist */
-#define FALSE 0 /* values of boolean */
-#endif
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-const char *get_exception_name(unsigned int exception)
-{
- if (exception==overflow_error)
- return "overflow_error exception";
- if (exception==simplex_arithmetic_error)
- return "simplex_arithmetic_error exception";
- if (exception==user_exception_error)
- return "user_exception_error exception";
- if (exception==parser_exception_error)
- return "parser_exception_error exception";
- if (exception==timeout_error)
- return "timeout_error exception";
- if (exception==any_exception_error)
- return "all exceptions mask";
-
- return "unknown or mixed exception";
-}
-
-/* keep track of last thrown exception for RETHROW()
- */
-unsigned int the_last_just_thrown_exception = 0;
-
-/* whether to run in debug mode (that is to trace catch/uncatch/throw)
- */
-static int linear_exception_debug_mode = FALSE;
-static unsigned int linear_exception_verbose = 1 | 2 | 16 ;
-
-/* A structure for the exception stack.
- */
-typedef struct
-{
- /* exception type.
- */
- int what;
-
- /* where to jump to.
- */
- jmp_buf where;
-
- /* location of the CATCH to be matched against the UNCATCH.
- */
- const char * function;
- const char * file;
- int line;
-}
- linear_exception_holder;
-
-/* exception stack.
- maximum extension.
- current index (next available bucket)
- */
-#define MAX_STACKED_CONTEXTS 64
-static linear_exception_holder exception_stack[MAX_STACKED_CONTEXTS];
-static int exception_index = 0;
-
-/* callbacks...
- */
-static exception_callback_t push_callback = NULL;
-static exception_callback_t pop_callback = NULL;
-
-void set_exception_callbacks(exception_callback_t push,
- exception_callback_t pop)
-{
- if (push_callback!=NULL || pop_callback!=NULL)
- {
- fprintf(stderr, "exception callbacks already defined! (%p, %p)\n",
- push_callback, pop_callback);
- abort();
- }
-
- push_callback = push;
- pop_callback = pop;
-}
-
-/* total number of exceptions thrown, for statistics.
- */
-int linear_number_of_exception_thrown = 0;
-
-/* dump stack
- */
-void dump_exception_stack_to_file(FILE * f)
-{
- int i;
- fprintf(f, "[dump_exception_stack_to_file] size=%d\n", exception_index);
- for (i=0; i<exception_index; i++)
- {
- fprintf(f,
- "%d: [%s:%d in %s (%d)]\n",
- i,
- exception_stack[i].file,
- exception_stack[i].line,
- exception_stack[i].function,
- exception_stack[i].what);
- }
- fprintf(f, "\n");
-}
-
-void dump_exception_stack()
-{
- dump_exception_stack_to_file(stderr);
-}
-
-#define exception_debug_message(type) \
- fprintf(stderr, "%s[%s:%d %s (%d)/%d]\n", \
- type, file, line, function, what, exception_index)
-
-#define exception_debug_trace(type) \
- if (linear_exception_debug_mode) { exception_debug_message(type); }
-
-
-/* push a what exception on stack.
- */
-jmp_buf *
-push_exception_on_stack(
- int what,
- const char * function,
- const char * file,
- int line)
-{
- exception_debug_trace("PUSH ");
-
- if (exception_index==MAX_STACKED_CONTEXTS)
- {
- exception_debug_message("push");
- fprintf(stderr, "exception stack overflow\n");
- dump_exception_stack();
- abort();
- }
-
- if (push_callback) push_callback(file, function, line);
-
- the_last_just_thrown_exception = 0;
-
- exception_stack[exception_index].what = what;
- exception_stack[exception_index].function = function;
- exception_stack[exception_index].file = file;
- exception_stack[exception_index].line = line;
-
- return & exception_stack[exception_index++].where;
-}
-
-#if !defined(same_string_p)
-#define same_string_p(s1, s2) (strcmp((s1),(s2))==0)
-#endif
-
-/* pop a what exception.
- check for any mismatch!
- */
-void
-pop_exception_from_stack(
- int what,
- const char * function,
- const char * file,
- int line)
-{
- exception_debug_trace("POP ");
-
- if (exception_index==0)
- {
- exception_debug_message("pop");
- fprintf(stderr, "exception stack underflow\n");
- dump_exception_stack();
- abort();
- }
-
- if (pop_callback) pop_callback(file, function, line);
-
- exception_index--;
- the_last_just_thrown_exception = 0;
-
- if ((exception_stack[exception_index].what != what) ||
- !same_string_p(exception_stack[exception_index].file, file) ||
- !same_string_p(exception_stack[exception_index].function, function))
- {
- exception_debug_message("pop");
- fprintf(stderr,
- "exception stack mismatch at depth=%d:\n"
- " CATCH: %s:%d in %s (%d)\n"
- " UNCATCH: %s:%d in %s (%d)\n",
- exception_index,
- exception_stack[exception_index].file,
- exception_stack[exception_index].line,
- exception_stack[exception_index].function,
- exception_stack[exception_index].what,
- file, line, function, what);
- dump_exception_stack();
- abort();
- }
-}
-
-/* throws an exception of a given type by searching for
- the specified 'what' in the current exception stack.
-*/
-void throw_exception(
- int what,
- const char * function,
- const char * file,
- int line)
-{
- int i;
-
- exception_debug_trace("THROW");
-
- the_last_just_thrown_exception = what; /* for rethrow */
-
- for (i=exception_index-1; i>=0; i--)
- {
- if (pop_callback)
- /* pop with push parameters! */
- pop_callback(exception_stack[i].file,
- exception_stack[i].function,
- exception_stack[i].line);
-
- if (exception_stack[i].what & what)
- {
- exception_index = i;
- linear_number_of_exception_thrown++;
-
- if (linear_exception_debug_mode)
- fprintf(stderr, "---->[%s:%d %s (%d)/%d]\n",
- exception_stack[i].file,
- exception_stack[i].line,
- exception_stack[i].function,
- exception_stack[i].what,
- i);
-
- /* trace some exceptions... */
- if (linear_exception_verbose & what)
- fprintf(stderr, "exception %d/%d: %s(%s:%d) -> %s(%s:%d)\n",
- what, exception_stack[i].what,
- function, file, line,
- exception_stack[i].function,
- exception_stack[i].file,
- exception_stack[i].line);
-
- longjmp(exception_stack[i].where, 0);
- }
- }
-
- /* error. */
- exception_debug_message("throw");
- fprintf(stderr,
- "exception not found in stack:\n"
- "an exception was THROWN without a proper matching CATCH\n");
- dump_exception_stack();
- abort();
-}
-
-void linear_initialize_exception_stack(
- unsigned int verbose_exceptions,
- exception_callback_t push,
- exception_callback_t pop)
-{
- linear_exception_verbose = verbose_exceptions;
- set_exception_callbacks(push, pop);
-}
diff --git a/source/polylib_mod/eval_ehrhart.c b/source/polylib_mod/eval_ehrhart.c
deleted file mode 100644
index 3e86a17..0000000
--- a/source/polylib_mod/eval_ehrhart.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/************************************************/
-/* eval_ehrhart.c */
-/* functions to evaluate an Ehrhart polynomial. */
-/* written by Emmanuel Jeannot (c) 1997. */
-/* Emmanuel.Jeannot at ens-lyon.fr */
-/* http://www.ens-lyon.fr/~ejeannot */
-/* */
-/* modified 1998, 2000, Vincent Loechner */
-/* (ArithmetiqueLib, Param_Names) */
-/************************************************/
-
-#include <stdio.h>
-#include <math.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#include <polylib/polylib.h>
-
-/* #define EVAL_EHRHART_DEBUG */
-
-/********************************************************/
-/* function in domain */
-/* check if the parameters in list_args */
-/* verifies the constraints of Domain P */
-/********************************************************/
-int in_domain(Polyhedron *P, Value *list_args) {
-
- int col,row;
- Value v; /* value of the constraint of a row when
- parameters are instanciated*/
-
- if( !P )
- return( 0 );
-
- POL_ENSURE_INEQUALITIES(P);
-
- value_init(v);
-
- /* P->Constraint constraint matrice of polyhedron P */
- for(row=0;row<P->NbConstraints;row++) {
- value_assign(v,P->Constraint[row][P->Dimension+1]); /*constant part*/
- for(col=1;col<P->Dimension+1;col++) {
- value_addmul(v, P->Constraint[row][col], list_args[col-1]);
- }
- if (value_notzero_p(P->Constraint[row][0])) {
-
- /*if v is not >=0 then this constraint is not respected */
- if (value_neg_p(v)) {
- value_clear(v);
- return( in_domain(P->next, list_args) );
- }
- }
- else {
-
- /*if v is not = 0 then this constraint is not respected */
- if (value_notzero_p(v)) {
- value_clear(v);
- return( in_domain(P->next, list_args) );
- }
- }
- }
-
- /* if not return before this point => all the constraints are respected */
- value_clear(v);
- return 1;
-} /* in_domain */
-
-/****************************************************/
-/* function compute enode */
-/* compute the value of enode p with parameters */
-/* list "list_args */
-/* compute the polynomial or the periodic */
-/****************************************************/
-
-static double compute_enode(enode *p, Value *list_args) {
-
- int i;
- Value m, param;
- double res=0.0;
-
- if (!p)
- return(0.);
-
- value_init(m);
- value_init(param);
-
- if (p->type == polynomial) {
- if (p->size > 1)
- value_assign(param,list_args[p->pos-1]);
-
- /* Compute the polynomial using Horner's rule */
- for (i=p->size-1;i>0;i--) {
- res +=compute_evalue(&p->arr[i],list_args);
- res *=VALUE_TO_DOUBLE(param);
- }
- res +=compute_evalue(&p->arr[0],list_args);
- }
- else if (p->type == periodic) {
- value_assign(m,list_args[p->pos-1]);
-
- /* Choose the right element of the periodic */
- value_set_si(param,p->size);
- value_pmodulus(m,m,param);
- res = compute_evalue(&p->arr[VALUE_TO_INT(m)],list_args);
- }
- value_clear(m);
- value_clear(param);
- return res;
-} /* compute_enode */
-
-/*************************************************/
-/* return the value of Ehrhart Polynomial */
-/* It returns a double, because since it is */
-/* a recursive function, some intermediate value */
-/* might not be integral */
-/*************************************************/
-
-double compute_evalue(evalue *e,Value *list_args) {
-
- double res;
-
- if (value_notzero_p(e->d)) {
- if (value_notone_p(e->d))
- res = VALUE_TO_DOUBLE(e->x.n) / VALUE_TO_DOUBLE(e->d);
- else
- res = VALUE_TO_DOUBLE(e->x.n);
- }
- else
- res = compute_enode(e->x.p,list_args);
- return res;
-} /* compute_evalue */
-
-
-/****************************************************/
-/* function compute_poly : */
-/* Check for the good validity domain */
-/* return the number of point in the Polyhedron */
-/* in allocated memory */
-/* Using the Ehrhart pseudo-polynomial */
-/****************************************************/
-Value *compute_poly(Enumeration *en,Value *list_args) {
-
- Value *tmp;
- /* double d; int i; */
-
- tmp = (Value *) malloc (sizeof(Value));
- assert(tmp != NULL);
- value_init(*tmp);
- value_set_si(*tmp,0);
-
- if(!en)
- return(tmp); /* no ehrhart polynomial */
- if(en->ValidityDomain) {
- if(!en->ValidityDomain->Dimension) { /* no parameters */
- value_set_double(*tmp,compute_evalue(&en->EP,list_args)+.25);
- return(tmp);
- }
- }
- else
- return(tmp); /* no Validity Domain */
- while(en) {
- if(in_domain(en->ValidityDomain,list_args)) {
-
-#ifdef EVAL_EHRHART_DEBUG
- Print_Domain(stdout,en->ValidityDomain,NULL);
- print_evalue(stdout,&en->EP,NULL);
-#endif
-
- /* d = compute_evalue(&en->EP,list_args);
- i = d;
- printf("(double)%lf = %d\n", d, i ); */
- value_set_double(*tmp,compute_evalue(&en->EP,list_args)+.25);
- return(tmp);
- }
- else
- en=en->next;
- }
- value_set_si(*tmp,0);
- return(tmp); /* no compatible domain with the arguments */
-} /* compute_poly */
-
-
-
-
diff --git a/source/polylib_mod/ext_ehrhart.c b/source/polylib_mod/ext_ehrhart.c
deleted file mode 100644
index 9db47e0..0000000
--- a/source/polylib_mod/ext_ehrhart.c
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <polylib/polylib.h>
-#define WS 200
-
-/* #define UE_DEBUG */
-
-
-typedef struct _Polyhedron_union {
- Enumeration *pt;
- struct _Polyhedron_union *next;} Polyhedron_union;
-
-static int ppcm1 (int a, int b);
-Matrix *CalcBase( Matrix *R);
-
-
-/**** ker.c ****/
-
-static void Soustraire_ligne(Matrix *R, int l1, int l2, int piv );
-static int existepivot( Matrix *R, int l );
-static void swap_line(Matrix *R, int l1, int l2);
-
-
-/* Caclule une base du noyau de l'application definie
-par la matrice _carree_ R (completee par des 0..0) */
-
-/* /!\ R est alteree par cette fonction. */
-
-Matrix *CalcBase( Matrix *R )
-{
- Matrix *B/*,*BTran*/; /* matrice des vect. de la base */
- int i, j;
- Value p;
- int l; /* ligne en cours de `pivotage' */
- int lnn;
- int dimbase;
- int u; /* vecteur util en cours de calcul */
- Value som;
- int c;
- /* diagonalisation de R : algo du pivot */
- /* avec conservation des pivots nuls */
- for( l=0 ; l<R->NbRows ; ++l )
- {
- /* cherche le prochain pivot non nul */
- if( (lnn=existepivot(R,l)) != -1 )
- {
- swap_line( R, l, lnn );
-
- /* met la colonne dessous a 0 */
- for( j=l+1 ; j<R->NbRows ; ++j )
- if(value_notzero_p( R->p[j][l]) )
- Soustraire_ligne( R, l, j, l );
-
- /* et celle dessus aussi */
- for( j=0 ; j<l ; ++j )
- if( value_notzero_p(R->p[j][l]) )
- Soustraire_ligne( R, l, j, l );
-
- }
- /* s'ils sont tous nuls on passe au suivant */
- /* en laissant cette ligne inchangee. */
- }
-
- dimbase = 0;
- for( l=0 ; l<R->NbRows ; ++l )
- if( value_zero_p(R->p[l][l]) )
- ++dimbase; /* = nb de 0 dans la diagonale */
-
- B = Matrix_Alloc( dimbase, R->NbRows );
-
- l=0;
- for( u=0 ; u<dimbase ; ++u )
- {
- while(value_notzero_p( R->p[l][l]) )
- ++l;
-
- /* calcul effectif de ce vecteur : chaque coord en commencant par le bas */
- for( i=R->NbRows-1 ; i>l ; --i )
- value_set_si(B->p[u][i], 0);
- value_set_si(B->p[u][l], 1);
- for( i=l-1 ; i>=0 ; --i ) /* i=chaque coord du vecteur */
- {
- if(value_zero_p( R->p[i][i]) )
- /* on a deux 0... un seul dans */
- /* ce vect util suffit */
- value_set_si(B->p[u][i],0);
- else
- {
- /* somme des coef deja calcules * coef dans la matrice */
- value_set_si(som,0);
- for( c=l ; c>i ; --c )
- {
- value_addmul(som, R->p[i][c], B->p[u][c]);
- value_multiply(B->p[u][c] ,B->p[u][c] , R->p[i][i]);
- }
- value_oppose(B->p[u][i] , som );
- }
- }
- /* reste a faire le pgcd du vecteur et a l'orienter */
- value_set_si(p,0);
- for( i=0 ; i<R->NbRows ; ++i )
- value_gcd(p, p, B->p[u][i]);
- if( value_zero_p(p))
- value_set_si(p,1);
- for( i=0 ; i<R->NbRows && value_zero_p(B->p[u][i]); ++i )
- ;
- if( i<R->NbRows )
- if( value_neg_p(B->p[u][i]) )
- value_oppose( p,p );
-
- for( i=0 ; i<R->NbRows ; ++i )
- value_divexact(B->p[u][i], B->p[u][i], p);
-
- /* incrementer le compteur de lignes */
- ++l;
- }
- return B;
-}
-
-
-/* fonction qui calcule les vect generateurs de l'espace vectoriel
- contenant le polyhedre P */
-/*
-Matrix *CalcPolyhedronBase( Polyhedron *P )
-{
- Matrix *R;
- Matrix *B;
- int n, lines;
-
- if( emptyQ(P) )
- return( Matrix_Alloc( 0, P->Dimension ) ); */ /* pas de vect. gen */ /*
-
- R = Matrix_Alloc( P->Dimension, P->Dimension );
-
- */ /* recopie le 'lineality space' du polyedre dans la matrice R */ /*
- for( lines=0,n=0 ; n<P->NbConstraints ; ++n )
- {
- if( P->Constraint[n][0]==0 )
- */ /* c'est une direction definissant un ss-espace */ /*
- {
- memcpy( &R->p[lines][0], &P->Constraint[n][1],
- sizeof(int)*P->Dimension );
- ++lines;
- }
- }
- */ /* remplit le reste de 0..0 */ /*
- for( ; lines<R->NbRows ; ++lines )
- memset( &R->p[lines][0], 0, sizeof(int)*P->Dimension );
-
- B = CalcBase( R );
- Matrix_Free( R );
-
- return( B );
-}*/
-
-
-/* fonction qui calcule l'espace vectoriel non parametre de dimension dim
- contenant le polyhedre parametre P */
-/* les _egalites_ sont stockees par la polylib sous forme triangulaire
-superieure donc il suffit de prendre les premieres. */
-
-/*Matrix *CalcEVPolyhedronNP( Polyhedron *P, int dim )
-{
- Matrix *R;
- Matrix *B;
- int n, lines;
-
- if( emptyQ(P) ) */ /* pas de vect. gen */ /*
- {
- B = Matrix_Alloc( 1, dim ); */ /* on ne peut pas allouer 0 lignes ! */ /*
- B->NbRows = 0;
- return( B );
- }
-
- R = Matrix_Alloc( dim, dim );
-
-*/ /* recopie le 'lineality space' du polyedre dans la matrice R */ /*
- for( lines=0,n=0 ; n<P->NbConstraints && lines<dim ; ++n )
- {
- if( P->Constraint[n][0]==0 )
- */ /* c'est une direction definissant un ss-espace */ /*
- {
- memcpy( &R->p[lines][0], &P->Constraint[n][1],
- sizeof(int)*P->Dimension );
- ++lines;
- }
- }
-*/ /* remplit le reste de 0..0 */ /*
- for( ; lines<R->NbRows ; ++lines )
- memset( &R->p[lines][0], 0, sizeof(int)*dim );
-
- B = CalcBase( R );
- Matrix_Free( R );
-
- return( B );
-}*/
-
-
-/* renvoie la ligne sur laquelle on a trouve un coef non nul */
-/* pareil mais cherche dans toutes les lignes */
-/* et -1 s'il n'y en a pas. */
-static int existepivot( Matrix *R, int l )
-{
- int j, c;
-
- for( j=l ; j<R->NbRows ; ++j )
- if(value_notzero_p( R->p[j][l]) )
- return( j );
-
- /* on ne l'a pas trouve pour l'instant... on cherche au dessus */
- /* les lignes ayant que des 0 jusqu'a la position l */
- for( j=0 ; j<l ; ++j )
- {
- for( c=0 ; c<l && value_zero_p(R->p[j][c]) ; c++ )
- ;
- if( c==l && value_notzero_p(R->p[j][l]) )
- return( j );
- }
-
- return( -1 );
-}
-
-
-/* echange les lignes l1 et l2 dans la matrice R */
-static void swap_line(Matrix *R, int l1, int l2)
-{
- int i;
- Value tmp;
-
- if( l1 != l2 )
- for(i = 0;i < R->NbColumns;i ++)
- {
- value_assign(tmp , R->p[l1][i]);
- value_assign(R->p[l1][i] , R->p[l2][i]);
- value_assign(R->p[l2][i] , tmp);
- }
-}
-
-
-
-int pgcd1( int a, int b)
-{
- int r;
- if( a== 0 )
- return( abs(b) );
- if(b==0 )
- return(abs(a) );
- do
- {
- r= a % b;
- a= b;
- b = r;
- }
- while ( r!=0 );
- return(abs(a));
-}
-
-
-
-
-/* Soustraire la ligne l1 de l2 */
-/* On effectue l2 = (l1[piv]/pgcd)*l2 - l1 * (l2[piv]/pgcd) */
-static void Soustraire_ligne(Matrix *R, int l1, int l2, int piv )
-{
- int i;
- Value a, b, p, t;
- /* l2 = a*l2 - b*l1 */
-
- if (value_zero_p(R->p[l2][piv] )) /* c'est deja fait ! */
- return;
-
- value_init(a);
- value_init(b);
- value_init(p);
- value_init(t);
-
- value_gcd(p, R->p[l1][piv], R->p[l2][piv]);
- value_divexact(a, R->p[l1][piv], p);
- value_divexact(b, R->p[l2][piv], p);
-
- value_set_si(R->p[l2][piv] , 0);
- value_set_si(p,0);
- for(i = piv + 1;i < R->NbColumns;i ++)
- {
- value_multiply(t,b,R->p[l1][i]);
- value_multiply(R->p[l2][i],a,R->p[l2][i]);
- value_subtract(R->p[l2][i],R->p[l2][i],t);
- value_gcd(p, p, R->p[l2][i]);
- }
- /* Simplification par le pgcd de toute la ligne */
- for( i=piv+1 ; i<R->NbColumns && p!=0 ; i++ )
- value_divexact(R->p[l2][i], R->p[l2][i], p);
-
- value_clear(a);
- value_clear(b);
- value_clear(p);
- value_clear(t);
-}
-
-
-/*** ext_ehrhart.c ****/
-
-
-void new_eadd(evalue *e1,evalue *res) {
-int i, p, x, y;
-
-evalue *ne;
-Value g,m1,m2;
-
- value_init(g);
- value_init(m1);
- value_init(m2);
- if (value_notzero_p(e1->d) && value_notzero_p(res->d)) {
- /* Add two rational numbers*/
- value_multiply(m1,e1->x.n,res->d);
- value_multiply(m2,res->x.n,e1->d);
- value_addto(res->x.n,m1,m2);
- value_multiply(res->d,e1->d,res->d);
- value_gcd(g, res->x.n,res->d);
- if (value_notone_p(g)) {
- value_divexact(res->d, res->d, g);
- value_divexact(res->x.n, res->x.n, g);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return ;
- }
- else if (value_notzero_p(e1->d) && value_zero_p(res->d)) {
- if (res->x.p->type==polynomial) {
- /* Add the constant to the constant term of a polynomial*/
- new_eadd(e1, &res->x.p->arr[0]);
- value_clear(g); value_clear(m1); value_clear(m2);
- return ;
- }
- else if (res->x.p->type==periodic) {
- /* Add the constant to all elements of a periodic number */
- for (i=0; i<res->x.p->size; i++) {
- new_eadd(e1, &res->x.p->arr[i]);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
-
- return ;
- }
- else {
- fprintf(stderr, "eadd: cannot add const with vector\n");
- value_clear(g); value_clear(m1); value_clear(m2);
-
- return;
- }
- }
- /* ######### add polynomial or periodic to constant #############
- you have to exchange e1 and res, before doing addition */
-
- else if (value_zero_p(e1->d) && value_notzero_p(res->d)) {
- enode *tmp;
- evalue x;
- x=*res;
- tmp= ecopy(e1->x.p);
- value_init(res->d);
- value_set_si( res->d, 0 );
- res->x.p=tmp;
-
- new_eadd(&x,res);
- value_clear(g); value_clear(m1); value_clear(m2);
- return ;
- }
- else { /* ((e1->d==0) && (res->d==0)) */
- if ((e1->x.p->type != res->x.p->type) ) {
- /* ##### adding to evalues of different type. two cases are possible ####
-
- #### res is periodic and e1 is polynomial, you have to exchange
- e1 and res then to add e1 to the constant term of res #### */
- if ((res->x.p->type == periodic)&&(e1->x.p->type == polynomial)) {
-
- evalue eval;
- value_set_si( eval.d, 0 );
- eval.x.p=ecopy(res->x.p);
- res->x.p= ecopy(e1->x.p);
- new_eadd(&eval,&res->x.p->arr[0]);
-
- }
- else if ((res->x.p->type == polynomial)&&(e1->x.p->type == periodic)) {
- /* #### res is polynomial and e1 is periodic,
- add e1 to the constant term of res #### */
-
- new_eadd(e1,&res->x.p->arr[0]);
- }
-
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- else if (e1->x.p->pos != res->x.p->pos ) {
- /* ### adding evalues of different position (i.e function of different unknowns
- to case are possible ### */
-
- if (res->x.p->type == polynomial) {/* ### res and e1 are polynomials
- add e1 to the constant term of res */
-
- new_eadd(e1,&res->x.p->arr[0]);
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
- else { /* ### res and e1 are pointers to periodic numbers
- add e1 to all elements of res */
-
- for (i=0;i<res->x.p->size;i++) {
- new_eadd(e1,&res->x.p->arr[i]);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return;
- }
-
-
- } /* ### */
-
-
- /* same type , same pos and same size */
- if (e1->x.p->size == res->x.p->size) {
- /* add any element in e1 to the corresponding element in res */
- for (i=0; i<res->x.p->size; i++) {
- new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return ;
- }
-
- /* Sizes are different */
- if (res->x.p->type==polynomial) {
- /* VIN100: if e1-size > res-size you have to copy e1 in a */
- /* new enode and add res to that new node. If you do not do */
- /* that, you lose the the upper weight part of e1 ! */
-
- if(e1->x.p->size > res->x.p->size) {
- enode *tmp;
- tmp = ecopy(e1->x.p);
- for(i=0;i<res->x.p->size;++i) {
- new_eadd(&res->x.p->arr[i], &tmp->arr[i]);
- /* free_evalue_refs(&res->x.p->arr[i]); */
- }
- res->x.p = tmp;
-
- }
- else {
-
- for (i=0; i<e1->x.p->size ; i++) {
- new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
- }
- value_clear(g); value_clear(m1); value_clear(m2);
-
- return ;
- }
- }
-
- /* ### add two periodics of the same pos (unknown) but whith different sizes (periods) ### */
- else if (res->x.p->type==periodic) {
- /* you have to create a new evalue 'ne' in whitch size equals to the scm
- of the sizes of e1 and res, then to copy res periodicaly in ne, after
- to add periodicaly elements of e1 to elements of ne, and finaly to
- return ne. */
-
- x=e1->x.p->size;
- y= res->x.p->size;
- p=ppcm1(x,y);
- ne= (evalue *) malloc (sizeof(evalue));
- value_init(ne->d);
- value_set_si( ne->d,0);
-
- ne->x.p=new_enode(res->x.p->type,p, res->x.p->pos);
- for(i=0;i<p;i++) {
- value_assign(ne->x.p->arr[i].d, res->x.p->arr[i%y].d);
- if (value_notzero_p(ne->x.p->arr[i].d)) {
- value_init(ne->x.p->arr[i].x.n);
- value_assign(ne->x.p->arr[i].x.n, res->x.p->arr[i%y].x.n);
- }
- else {
- ne->x.p->arr[i].x.p =ecopy(res->x.p->arr[i%y].x.p);
- }
- }
- for(i=0;i<p;i++) {
- new_eadd(&e1->x.p->arr[i%x], &ne->x.p->arr[i]);
- }
-
- res=ne;
-
- value_clear(g); value_clear(m1); value_clear(m2);
- return ;
- }
- else { /* evector */
- fprintf(stderr, "eadd: ?cannot add vectors of different length\n");
- value_clear(g); value_clear(m1); value_clear(m2);
- return ;
- }
- }
- value_clear(g); value_clear(m1); value_clear(m2);
- return ;
- } /* new_eadd */
-
-/* remove the last row and the last column of a matrix Mat */
-Matrix *Reduce_Matrix (Matrix *Mat) {
- int i;
- Value *p;
- p=*(Mat->p+(Mat->NbRows-1));
- for (i=0;i<Mat->NbColumns; i++) {
- value_clear(*p++);
- }
- for (i=0; i<Mat->NbRows-1; i++) {
- p=*(Mat->p+i);
- value_clear(*(p+(Mat->NbColumns-1)));
- }
- Mat->NbRows--;
- Mat->NbColumns--;
- return Mat;
- } /* Reduce_Matrix */
-
-
- /* Computes the scalar product (in euclidien space) of two vectors */
-
-void Scalar_product(Value *p1,Value *p2,unsigned length, Value *r) {
- Value *cp1, *cp2;
-
- int i;
- cp1=p1;
- cp2=p2;
- value_set_si(*r,0);
- for (i=0;i<length;i++) {
- value_addmul(*r, *cp1, *cp2);
- cp1++; cp2++;
- }
- } /* Scalar_product */
-
- /* computes the scm of two integrals */
-
- int ppcm1 (int a, int b) {
- int t;
- t = (a*b)/ pgcd1(a,b);
- return t;
- } /* ppcm1 */
-
-
-Matrix *Orthogonal_Base(Matrix *Mat) {
- Matrix *OrthMat;
- Value a,b,c,d;
- Vector *q,*p,*f;
- unsigned length;
- int i,j,k;
- value_init(a);
- value_init(b);
- value_init(c);
- value_init(d);
- OrthMat= Matrix_Alloc(Mat->NbRows,Mat->NbColumns);
- length=Mat->NbColumns;
- for(k=0; k<length; k++) {
- value_assign(OrthMat->p[0][k],Mat->p[0][k]);
- }
- f=Vector_Alloc(length);
- p=Vector_Alloc(length);
- q=Vector_Alloc(length);
- for(i=1; i<Mat->NbRows; i++) {
- for(k=0;k<length;k++) {
- value_assign(f->p[k],Mat->p[i][k]);
- value_assign(q->p[k],Mat->p[i][k]);
- }
- value_set_si(d,1);
- for(j=0; j<i; j++) {
- for(k=0;k<length;k++) {
- value_assign(p->p[k],OrthMat->p[j][k]);
- }
-
- Scalar_product(p->p,f->p,length,&a);
- Scalar_product(p->p,p->p,length,&b);
- value_gcd(c, a, b);
- value_divexact(a, a, c);
- value_divexact(b, b, c);
- for(k=0;k<length;k++) {
- value_multiply(p->p[k],p->p[k],a);
- }
-
- if(value_notone_p(d)|value_notone_p(b)) {
- value_lcm(c, d, b);
- value_divexact(a, c, b);
- value_divexact(b, c, d);
- value_assign(d,c);
- for(k=0;k<length;k++) {
- value_multiply(p->p[k],p->p[k],a);
- value_multiply(q->p[k],q->p[k],b);
- }
-
- }
-
- for(k=0;k<length;k++) {
- value_subtract(q->p[k],q->p[k],p->p[k]);
- }
-
- }
- Vector_Gcd(q->p,length,&c);
- Vector_AntiScale(q->p, OrthMat->p[i], c, length);
- }
- value_clear(a);
- value_clear(b);
- value_clear(c);
- value_clear(d);
- return OrthMat;
-} /* Orthogonal_Base */
-
-
-/* Remove an element of a list */
-void Remove_Element(Enumeration *en,Enumeration **re, Enumeration *prev) {
- if (en== *re) {
- *re= (*re)->next;
- }
- else {
- prev->next=en->next;
- }
-} /* Remove_Element */
-
- /* Remove validite domains and correspending ehrhart polynomials whitch are redundant after
- the enumeration of a polyhedron */
-
- void Remove_RedundantDomains (Enumeration **Ures) {
- Enumeration *ren1, *ren2, *previous=NULL;
- int red;
- for (ren1=*Ures; ren1; ren1=ren1->next) {
- red=0;
- for (ren2=*Ures; ren2; ren2=ren2->next) {
- if (ren1!=ren2) {
-
- if (PolyhedronIncludes(ren2->ValidityDomain, ren1->ValidityDomain)) {
- red= 1;
- break;
-
- }
-
- }
- }
- if (red) {
- Remove_Element(ren1,Ures,previous);
- }
- previous=ren1;
- }
- }/*Remove_RedendentDomains */
-
-
-int IncludeInRes (Polyhedron *p, Enumeration *e, unsigned MR) {
- Enumeration *en;
- for (en=e; en; en=en->next) {
-
- if (PolyhedronIncludes(e->ValidityDomain,p))
- return 1;
- }
- return 0;
-}
-
-Polyhedron *DMUnion(Enumeration *en, unsigned MR) {
- Enumeration *e1;
- Polyhedron *d;
- e1=en;
- d=e1->ValidityDomain;
- for (e1=en->next; e1; e1=e1->next) {
- d= DomainUnion( d, e1->ValidityDomain, MR);
- }
- return d;
- }
-
-
-void AffConstraints(Polyhedron *Poldisj)
-{
- Polyhedron *p;
-
- for(p=Poldisj;p;p=p->next)
- {
- Polyhedron_PrintConstraints( stdout, P_VALUE_FMT, p);
- printf("\n");
- }
-}
-int Degenerate (Enumeration *en) {
- if(value_notzero_p(en->EP.d)) {
-
- if(value_mone_p(en->EP.x.n )) {
- return 1;
- }
- }
- return 0;
-}
-
-/* Enumeration of a domain D */
-
-Enumeration *Domain_Enumerate(Polyhedron *D, Polyhedron *C, unsigned MAXRAYS,
- const char **pn)
-{ Polyhedron_union *Polun,*pu;
- Polyhedron *lp, *lp1, *lp1next;
- Polyhedron *d1,*d2,*d;
- Enumeration *e,*pr,*en,*en1, *en2,*tmp, *res, *sen;
- Polun=NULL;
-
- for (d = D; d; d = d->next) {
- POL_ENSURE_FACETS(d);
- POL_ENSURE_VERTICES(d);
- }
- POL_ENSURE_FACETS(C);
- POL_ENSURE_VERTICES(C);
-
- lp = Disjoint_Domain( D, 0, MAXRAYS );
-
-#ifdef UE_DEBUG
- printf("##############################################################\n");
- printf("\n###### DISJOINT UNION ######\n\n");
- AffConstraints(lp);
- printf("##############################################################\n");
-#endif
-
- for (lp1=lp ; lp1; lp1=lp1->next)
- {
- Enumeration *enext;
- lp1next = lp1->next;
- lp1->next = NULL;
- en= Polyhedron_Enumerate(lp1, C, MAXRAYS,NULL);
- lp1->next = lp1next;
- sen= NULL;
- for (e=en;e;e=enext) {
- enext = e->next;
- if (!Degenerate(e)) {
- e->next = sen;
- sen=e;
- } else {
- free_evalue_refs(&e->EP);
- Domain_Free(e->ValidityDomain);
- free(e);
- }
- }
-
- if(sen!= NULL)
- {
- pu = (Polyhedron_union *)malloc(sizeof(Polyhedron_union));
- pu->pt=sen;
- pu->next = Polun;
- Polun = pu;
- }
- }
- if(!Polun)
- {
-#ifdef UE_DEBUG
- fprintf(stdout,"Empty Polun\n");
-#endif
- return ((Enumeration *) 0);
- }
-
- while(Polun->next != NULL) {
- Enumeration *enext;
- res=NULL;
- en1=Polun->pt;
- en2=(Polun->next)->pt;
-
- d1=DMUnion(en1, MAXRAYS);
- d2=DMUnion(en2, MAXRAYS);
-
- for (en1=Polun->pt;en1;en1=enext) {
- enext = en1->next;
- for(en2=(Polun->next)->pt;en2;en2=en2->next)
- {
- d = DomainIntersection(en1->ValidityDomain,en2->ValidityDomain,MAXRAYS);
- if( d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS)) {
- tmp = (Enumeration *)malloc(sizeof(Enumeration));
- value_init(tmp->EP.d);
- value_assign( tmp->EP.d, en2->EP.d );
- if(value_zero_p(tmp->EP.d))
- tmp->EP.x.p=ecopy(en2->EP.x.p);
- else
- {
- value_init(tmp->EP.x.n);
- value_assign( tmp->EP.x.n, en2->EP.x.n );
- }
-
- new_eadd(&en1->EP,&tmp->EP);
- tmp->ValidityDomain =d;
- tmp->next= res;
- res=tmp;
- }
- }
- d=DomainDifference(en1->ValidityDomain,d2 ,MAXRAYS);
- if (d && !emptyQ(d) && !IncludeInRes(d,res,MAXRAYS)) {
- en1->ValidityDomain = d;
- en1->next= res;
- res=en1;
- } else {
- free_evalue_refs(&en1->EP);
- free(en1);
- }
- }
- for (en2=(Polun->next)->pt; en2; en2 = enext) {
- enext = en2->next;
- d= DomainDifference(en2->ValidityDomain,d1,MAXRAYS);
- if (d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS)) {
- en2->ValidityDomain = d;
- en2->next = res;
- res = en2;
- } else {
- free_evalue_refs(&en2->EP);
- free(en2);
- }
- }
- Domain_Free(d1);
- Domain_Free(d2);
-
- Polun->pt=res;
-
- Polun->next= (Polun->next)->next;
- }
- res=Polun->pt;
-
- Remove_RedundantDomains(&res);
- return(res);
-}
-
-
-/**********
- DO NOT USE THE FOLLOWING FUNCTION IT'S NOT WORKING PROPERLY YET.
- **********/
-
-/* Enumeration of the image by T of domain D */
-Enumeration *Polyhedron_Image_Enumerate(Polyhedron *D, Polyhedron *C, Matrix *T, unsigned MAXRAYS, const char **par_name)
-{ Polyhedron *polun,*pol;
- Enumeration *ee;
- Matrix *TCopy,*Tred, *d1,*d;
- Vector *v1,*v2;
- Value h;
- int i,j,k;
-
- POL_ENSURE_FACETS(D);
- POL_ENSURE_VERTICES(D);
- POL_ENSURE_FACETS(C);
- POL_ENSURE_VERTICES(C);
-
- value_init(h);
- if(!D) {
- fprintf(stdout," Error: in reading input domain \n");
- value_clear(h);
- return ((Enumeration *) 0);
- }
- else {
- printf("\n ################ INPUT POLYHEDRON #######################\n\n");
- AffConstraints(D);
- }
-
-#ifdef DOMAIN_IMAGE
- fpol=DomainImage(D,T,MAXRAYS);
- printf("\n $$$$$$$$$$$$$ THE DOMAIN IMAGE $$$$$$$$$$$$$\n\n");
- AffConstraints(fpol);
- if(emptyQ(fpol)) {
- value_clear(h);
- return ((Enumeration *) 0);
- }
- ee = Domain_Enumerate(fpol,C,MAXRAYS,par_name);
- value_clear(h);
- return (ee);
-#endif
-
- TCopy= Matrix_Copy(T);
- Tred= Reduce_Matrix(TCopy);
- printf("\n ################## INPUT REDUCED TRANSFORMATION MATRIX ##################\n" );
- Matrix_Print(stdout,P_VALUE_FMT,Tred);
-
- if (Tred->NbRows <Tred->NbColumns) {
- d1=(Matrix *) Matrix_Alloc(Tred->NbColumns,Tred->NbColumns);
- for (i=0;i<Tred->NbRows;i++) {
- for (j=0; j<Tred->NbColumns;j++) {
- value_assign( d1->p[i][j], Tred->p[i][j] );
- }
- }
- for(i=Tred->NbRows;i<Tred->NbColumns;i++) {
- for (j=0;j<Tred->NbColumns;j++) {
- value_set_si( d1->p[i][j], 0 );
- }
- }
- d= (Matrix *) CalcBase(d1);
- Matrix_Free(Tred);
- Matrix_Free(d1);
-
- }
- else {
- d=(Matrix *) CalcBase(Tred);
- Matrix_Free(Tred);
- }
- if(d->NbRows==0) {
- if(emptyQ(D)) {
- value_clear(h);
- return ((Enumeration *) 0);
- }
- else {
- printf( " Ker(A)=0 implys directly Enumeration on input polyhedron\n\n");
- ee=Domain_Enumerate(D,C,MAXRAYS,par_name);
- value_clear(h);
- return ee;
- }
- }
-
- d1=Transpose(d);
- Matrix_Free(d);
-
- if(d1->NbRows!=D->Dimension) {
- fprintf(stdout," \n Error: incompatible dimension \n");
- value_clear(h);
- return ((Enumeration *) 0);
- }
- if(d1->NbColumns > 1) {
- fprintf(stdout," \n Error: Can not compute integral points : More then vector in ker(A)! \n");
- value_clear(h);
- return ((Enumeration *) 0);
-
- }
- printf( " \n Ker(A)=1 implys adding constraints befor Enumeration\n");
- v1=Vector_Alloc(d1->NbRows);
- v2=Vector_Alloc(d1->NbRows);
-
- polun=(Polyhedron *) NULL;
- for (k=0;k<d1->NbRows;k++) {
- value_assign(v1->p[k],d1->p[k][0]) ;
- }
- /* adding a new constraint for all constraints of D in which the scalar product of the*/
- /* normal whith vector v1 is greter then zero*/
-
- for (j=0;j<D->NbConstraints;j++) {
- for (k=0;k<=D->Dimension-1;k++) {
- value_assign(v2->p[k],D->Constraint[j][k+1]) ;
- }
- Scalar_product(v1->p,v2->p,D->Dimension,&h);
-
- if(value_pos_p(h)&&!value_zero_p(D->Constraint[j][0])) {
- Vector *NCont;
- Value val;
- value_init( val );
- /* Create a new contraint whitch is added to the polyhedron*/
-
- NCont=Vector_Alloc(d1->NbRows+2);
- value_set_si( NCont->p[0],1); /* the constraint is an inequality */
-
- for (k=1;k<=D->Dimension;k++) {
- value_oppose( NCont->p[k], D->Constraint[j][k]);
- }
- value_decrement(val,h);
- value_subtract(val,val,D->Constraint[j][D->Dimension+1]);
- value_assign (NCont->p[D->Dimension+1],val);
- value_clear(val);
- /* add the new constraint to polyhedron D */
- pol=AddConstraints(NCont->p,1,D,MAXRAYS);
- POL_ENSURE_VERTICES(pol);
- polun=AddPolyToDomain(Polyhedron_Copy(pol),polun);
- Polyhedron_Free(pol);
- Vector_Free(NCont);
- value_clear( val );
- }
- }
- if(polun==NULL) { /* No constraint is added to input polyhedron */
- if(emptyQ(D)) {
- value_clear(h);
- return ((Enumeration *) 0);
- }
- else {
- ee= Domain_Enumerate(D,C,MAXRAYS,par_name);
- }
- }
- else { /* some constraintes are added to input polyhedron */
- if(emptyQ(polun)){
- value_clear(h);
- return ((Enumeration *) 0);
- }
- else {
- printf("\n ##################################################################");
- printf("\n ****** THE RESULT OF ADDING CONSTRAINTS TO THE INPUT POLYHEDRON ****** \n");
- AffConstraints(polun);
- ee= Domain_Enumerate(polun,C,MAXRAYS,par_name);
- value_clear(h);
- return (ee );
- }
- }
-
-
- return( NULL );
-}
-
-
diff --git a/source/polylib_mod/homogenization.c b/source/polylib_mod/homogenization.c
deleted file mode 100644
index 603ea12..0000000
--- a/source/polylib_mod/homogenization.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/** homogenization.c
- copyright 2004-2005 Bavo Nootaert
-**/
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <polylib/polylib.h>
-#include <polylib/homogenization.h>
-
-static evalue *dehomogenize_periodic(enode *en);
-static evalue *dehomogenize_polynomial(enode *en);
-
-Polyhedron *homogenize(Polyhedron *P, unsigned MAXRAYS)
-{
- Matrix M, *M2;
- /* Pretend P is a Matrix for a second */
- M.NbRows = P->NbConstraints;
- M.NbColumns = P->Dimension+2;
- M.p_Init = P->p_Init;
- M.p = P->Constraint;
- M2 = AddANullColumn(&M);
- P = Constraints2Polyhedron(M2, MAXRAYS);
- Matrix_Free(M2);
- return P;
-}
-
-/** dehomogenize an evalue. The last parameter (nb_param) is replaced by 1.
- This function is mutually recursive with dehomogenize_enode.
-**/
-void dehomogenize_evalue(evalue *ep, int nb_param){
- evalue *w;
-
- /** cannot dehomogenize rationals **/
- if (value_zero_p(ep->d)){
-
- /** we need to replace the last parameter **/
- if (ep->x.p->pos == nb_param){
- if (ep->x.p->type == periodic && ep->x.p->size > 1){
- w = dehomogenize_periodic(ep->x.p);
- }
- else{
- w = dehomogenize_polynomial(ep->x.p);
- }
- free_evalue_refs(ep);
- memcpy(ep, w, sizeof(evalue));
- free(w);
- }
- else{
- /** Not the last parameter. Recurse **/
- dehomogenize_enode(ep->x.p, nb_param);
- }
-
- }
-}
-
-/** dehomogenize all evalues in an enode.
- This function is mutually recursive with dehomogenize_evalue.
-**/
-void dehomogenize_enode(enode *p, int nb_param){
- evalue *temp;
- int i;
- for (i = 0; i < p->size; i++){
- dehomogenize_evalue(&p->arr[i], nb_param);
- }
-}
-
-
-/** return the 1st element of an enode representing a periodic **/
-static evalue *dehomogenize_periodic(enode *en){
- evalue *w;
- assert(en->type == periodic);
- assert(en->size > 1);
- assert(value_notzero_p(en->arr[1].d));
- w = (evalue*)malloc(sizeof(evalue));
- value_init(w->d); value_init(w->x.n);
- value_assign(w->d, en->arr[1].d); value_assign(w->x.n, en->arr[1].x.n);
- return w;
-}
-
-/** dehomogenize a polynomial. Assume the enode contains a polynomial in
- one variable, the homogenous parameter.
- Returns an new evalue, representing a rational.
- **/
-static evalue *dehomogenize_polynomial(enode *en){
- evalue *enn;
- evalue *ev;
- int i;
- double som;
- Value num, den, gcd, f1, f2;
- assert(en->type == polynomial);
- som = 0;
- value_init(num); value_init(den); value_init(gcd);
- value_init(f1); value_init(f2);
- value_set_si(den, 1);
-
- /** enumerate over all coefficients (which are either periodic or rational,
- but not polynomial) **/
- for (i = 0; i < en->size; i++){
- if (value_zero_p(en->arr[i].d)){
- if (en->arr[i].x.p->size > 1)
- ev = &en->arr[i].x.p->arr[1];
- else
- ev = &en->arr[i].x.p->arr[0];
- }
- else{
- ev = &en->arr[i];
- }
- /** add ev (fraction) to num/den **/
- value_multiply(f1, den, ev->x.n);
- value_multiply(f2, num, ev->d);
- value_addto(num, f1, f2);
- value_multiply(den, den, ev->d);
- }
-
- /** simplify num/den **/
- value_gcd(gcd, num, den);
- value_divexact(num, num, gcd);
- value_divexact(den, den, gcd);
-
- /** create new evalue representing num/den**/
- enn = (evalue*)malloc(sizeof(evalue));
- value_init(enn->d); value_init(enn->x.n);
- value_assign(enn->d, den);
- value_assign(enn->x.n, num);
-
- /** cleanup **/
- value_clear(gcd);
- value_clear(f1); value_clear(f2);
- value_clear(num); value_clear(den);
-
- return enn;
-}
-
-/** dehomogenize a polyhedron. Assume the polyhedron p is homogenous.
- Returns a new polyhedron.
-**/
-Polyhedron *dehomogenize_polyhedron(Polyhedron *p, int maxRays){
- Matrix *constr, *constrh;
- Polyhedron *ph;
- int i;
- constr = Polyhedron2Constraints(p);
- constrh = Matrix_Alloc(constr->NbRows, constr->NbColumns - 1);
- for (i = 0; i < constr->NbRows; i++){
- Vector_Copy(constr->p[i], constrh->p[i], constr->NbColumns - 1);
- }
- ph = Constraints2Polyhedron(constrh, maxRays);
- Matrix_Free(constr); Matrix_Free(constrh);
- return ph;
-}
-
-/** dehomogenize an enumeration. Replaces each validity domain and
- Ehrhart polynomial in the Enumeration en with the dehomogenized form.
- **/
-void dehomogenize_enumeration(Enumeration* en, int nb_params, int maxRays){
- Enumeration *en2;
- Polyhedron *vd;
- for (en2 = en; en2; en2 = en2->next) {
- vd = dehomogenize_polyhedron(en2->ValidityDomain, maxRays);
- Polyhedron_Free(en2->ValidityDomain);
- en2->ValidityDomain = vd;
- dehomogenize_evalue(&en2->EP, nb_params);
- }
-}
diff --git a/source/polylib_mod/matrix.c b/source/polylib_mod/matrix.c
deleted file mode 100644
index 1d84800..0000000
--- a/source/polylib_mod/matrix.c
+++ /dev/null
@@ -1,1041 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* matrix.c
- COPYRIGHT
- Both this software and its documentation are
-
- Copyright 1993 by IRISA /Universite de Rennes I -
- France, Copyright 1995,1996 by BYU, Provo, Utah
- all rights reserved.
-
- Permission is granted to copy, use, and distribute
- for any commercial or noncommercial purpose under the terms
- of the GNU General Public license, version 2, June 1991
- (see file : LICENSING).
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <polylib/polylib.h>
-
-#ifdef mac_os
- #define abs __abs
-#endif
-
-/*
- * Allocate space for matrix dimensioned by 'NbRows X NbColumns'.
- */
-Matrix *Matrix_Alloc(unsigned NbRows,unsigned NbColumns) {
-
- Matrix *Mat;
- Value *p, **q;
- int i,j;
-
- Mat=(Matrix *)malloc(sizeof(Matrix));
- if(!Mat) {
- errormsg1("Matrix_Alloc", "outofmem", "out of memory space");
- return 0;
- }
- Mat->NbRows=NbRows;
- Mat->NbColumns=NbColumns;
- if (NbRows==0 || NbColumns==0) {
- Mat->p = (Value **)0;
- Mat->p_Init= (Value *)0;
- Mat->p_Init_size = 0;
- } else {
- q = (Value **)malloc(NbRows * sizeof(*q));
- if(!q) {
- free(Mat);
- errormsg1("Matrix_Alloc", "outofmem", "out of memory space");
- return 0;
- }
- p = value_alloc(NbRows * NbColumns, &Mat->p_Init_size);
- if(!p) {
- free(q);
- free(Mat);
- errormsg1("Matrix_Alloc", "outofmem", "out of memory space");
- return 0;
- }
- Mat->p = q;
- Mat->p_Init = p;
- for (i=0;i<NbRows;i++) {
- *q++ = p;
- p += NbColumns;
- }
- }
- p = NULL;
- q = NULL;
-
- return Mat;
-} /* Matrix_Alloc */
-
-/*
- * Free the memory space occupied by Matrix 'Mat'
- */
-void Matrix_Free(Matrix *Mat)
-{
- if (Mat->p_Init)
- value_free(Mat->p_Init, Mat->p_Init_size);
-
- if (Mat->p)
- free(Mat->p);
- free(Mat);
-
-} /* Matrix_Free */
-
-void Matrix_Extend(Matrix *Mat, unsigned NbRows)
-{
- Value *p, **q;
- int i,j;
-
- q = (Value **)realloc(Mat->p, NbRows * sizeof(*q));
- if(!q) {
- errormsg1("Matrix_Extend", "outofmem", "out of memory space");
- return;
- }
- Mat->p = q;
- if (Mat->p_Init_size < NbRows * Mat->NbColumns) {
- p = (Value *)realloc(Mat->p_Init, NbRows * Mat->NbColumns * sizeof(Value));
- if(!p) {
- errormsg1("Matrix_Extend", "outofmem", "out of memory space");
- return;
- }
- Mat->p_Init = p;
- Vector_Set(Mat->p_Init + Mat->NbRows*Mat->NbColumns, 0,
- Mat->p_Init_size - Mat->NbRows*Mat->NbColumns);
- for (i = Mat->p_Init_size; i < Mat->NbColumns*NbRows; ++i)
- value_init(Mat->p_Init[i]);
- Mat->p_Init_size = Mat->NbColumns*NbRows;
- } else
- Vector_Set(Mat->p_Init + Mat->NbRows*Mat->NbColumns, 0,
- (NbRows - Mat->NbRows) * Mat->NbColumns);
- for (i=0;i<NbRows;i++) {
- Mat->p[i] = Mat->p_Init + (i * Mat->NbColumns);
- }
- Mat->NbRows = NbRows;
-}
-
-/*
- * Print the contents of the Matrix 'Mat'
- */
-void Matrix_Print(FILE *Dst, const char *Format, Matrix *Mat)
-{
- Value *p;
- int i, j;
- unsigned NbRows, NbColumns;
-
- fprintf(Dst,"%d %d\n", NbRows=Mat->NbRows, NbColumns=Mat->NbColumns);
- if (NbColumns ==0) {
- fprintf(Dst, "\n");
- return;
- }
- for (i=0;i<NbRows;i++) {
- p=*(Mat->p+i);
- for (j=0;j<NbColumns;j++) {
- if (!Format) {
- value_print(Dst," "P_VALUE_FMT" ",*p++);
- }
- else {
- value_print(Dst,Format,*p++);
- }
- }
- fprintf(Dst, "\n");
- }
-} /* Matrix_Print */
-
-/*
- * Read the contents of the Matrix 'Mat'
- */
-void Matrix_Read_Input(Matrix *Mat) {
-
- Value *p;
- int i,j,n;
- char *c, s[1024],str[1024];
-
- p = Mat->p_Init;
- for (i=0;i<Mat->NbRows;i++) {
- do {
- c = fgets(s, 1024, stdin);
- while(isspace(*c) && *c!='\n')
- ++c;
- } while(c && (*c =='#' || *c== '\n'));
-
- if (!c) {
- errormsg1( "Matrix_Read", "baddim", "not enough rows" );
- break;
- }
- for (j=0;j<Mat->NbColumns;j++) {
- if(!c || *c=='\n' || *c=='#') {
- errormsg1("Matrix_Read", "baddim", "not enough columns");
- break;
- }
- if (sscanf(c,"%s%n",str,&n) == 0) {
- errormsg1( "Matrix_Read", "baddim", "not enough columns" );
- break;
- }
- value_read(*(p++),str);
- c += n;
- }
- }
-} /* Matrix_Read_Input */
-
-/*
- * Read the contents of the matrix 'Mat' from standard input.
- * A '#' in the first column is a comment line
- */
-Matrix *Matrix_Read(void) {
-
- Matrix *Mat;
- unsigned NbRows, NbColumns;
- char s[1024];
-
- if (fgets(s, 1024, stdin) == NULL)
- return NULL;
- while ((*s=='#' || *s=='\n') ||
- (sscanf(s, "%d %d", &NbRows, &NbColumns)<2)) {
- if (fgets(s, 1024, stdin) == NULL)
- return NULL;
- }
- Mat = Matrix_Alloc(NbRows,NbColumns);
- if(!Mat) {
- errormsg1("Matrix_Read", "outofmem", "out of memory space");
- return(NULL);
- }
- Matrix_Read_Input(Mat);
- return Mat;
-} /* Matrix_Read */
-
-/*
- * Basic hermite engine
- */
-static int hermite(Matrix *H,Matrix *U,Matrix *Q) {
-
- int nc, nr, i, j, k, rank, reduced, pivotrow;
- Value pivot,x,aux;
- Value *temp1, *temp2;
-
- /* T -1 T */
- /* Computes form: A = Q H and U A = H and U = Q */
-
- if (!H) {
- errormsg1("Domlib", "nullH", "hermite: ? Null H");
- return -1;
- }
- nc = H->NbColumns;
- nr = H->NbRows;
- temp1 = (Value *) malloc(nc * sizeof(Value));
- temp2 = (Value *) malloc(nr * sizeof(Value));
- if (!temp1 ||!temp2) {
- errormsg1("Domlib", "outofmem", "out of memory space");
- return -1;
- }
-
- /* Initialize all the 'Value' variables */
- value_init(pivot); value_init(x);
- value_init(aux);
- for(i=0;i<nc;i++)
- value_init(temp1[i]);
- for(i=0;i<nr;i++)
- value_init(temp2[i]);
-
-#ifdef DEBUG
- fprintf(stderr,"Start -----------\n");
- Matrix_Print(stderr,0,H);
-#endif
- for (k=0, rank=0; k<nc && rank<nr; k=k+1) {
- reduced = 1; /* go through loop the first time */
-#ifdef DEBUG
- fprintf(stderr, "Working on col %d. Rank=%d ----------\n", k+1, rank+1);
-#endif
- while (reduced) {
- reduced=0;
-
- /* 1. find pivot row */
- value_absolute(pivot,H->p[rank][k]);
-
- /* the kth-diagonal element */
- pivotrow = rank;
-
- /* find the row i>rank with smallest nonzero element in col k */
- for (i=rank+1; i<nr; i++) {
- value_absolute(x,H->p[i][k]);
- if (value_notzero_p(x) &&
- (value_lt(x,pivot) || value_zero_p(pivot))) {
- value_assign(pivot,x);
- pivotrow = i;
- }
- }
-
- /* 2. Bring pivot to diagonal (exchange rows pivotrow and rank) */
- if (pivotrow != rank) {
- Vector_Exchange(H->p[pivotrow],H->p[rank],nc);
- if (U)
- Vector_Exchange(U->p[pivotrow],U->p[rank],nr);
- if (Q)
- Vector_Exchange(Q->p[pivotrow],Q->p[rank],nr);
-
-#ifdef DEBUG
- fprintf(stderr,"Exchange rows %d and %d -----------\n", rank+1, pivotrow+1);
- Matrix_Print(stderr,0,H);
-#endif
- }
- value_assign(pivot,H->p[rank][k]); /* actual ( no abs() ) pivot */
-
- /* 3. Invert the row 'rank' if pivot is negative */
- if (value_neg_p(pivot)) {
- value_oppose(pivot,pivot); /* pivot = -pivot */
- for (j=0; j<nc; j++)
- value_oppose(H->p[rank][j],H->p[rank][j]);
-
- /* H->p[rank][j] = -(H->p[rank][j]); */
- if (U)
- for (j=0; j<nr; j++)
- value_oppose(U->p[rank][j],U->p[rank][j]);
-
- /* U->p[rank][j] = -(U->p[rank][j]); */
- if (Q)
- for (j=0; j<nr; j++)
- value_oppose(Q->p[rank][j],Q->p[rank][j]);
-
- /* Q->p[rank][j] = -(Q->p[rank][j]); */
-#ifdef DEBUG
- fprintf(stderr,"Negate row %d -----------\n", rank+1);
- Matrix_Print(stderr,0,H);
-#endif
-
- }
- if (value_notzero_p(pivot)) {
-
- /* 4. Reduce the column modulo the pivot */
- /* This eventually zeros out everything below the */
- /* diagonal and produces an upper triangular matrix */
-
- for (i=rank+1;i<nr;i++) {
- value_assign(x,H->p[i][k]);
- if (value_notzero_p(x)) {
- value_modulus(aux,x,pivot);
-
- /* floor[integer division] (corrected for neg x) */
- if (value_neg_p(x) && value_notzero_p(aux)) {
-
- /* x=(x/pivot)-1; */
- value_division(x,x,pivot);
- value_decrement(x,x);
- }
- else
- value_division(x,x,pivot);
- for (j=0; j<nc; j++) {
- value_multiply(aux,x,H->p[rank][j]);
- value_subtract(H->p[i][j],H->p[i][j],aux);
- }
-
- /* U->p[i][j] -= (x * U->p[rank][j]); */
- if (U)
- for (j=0; j<nr; j++) {
- value_multiply(aux,x,U->p[rank][j]);
- value_subtract(U->p[i][j],U->p[i][j],aux);
- }
-
- /* Q->p[rank][j] += (x * Q->p[i][j]); */
- if (Q)
- for(j=0;j<nr;j++) {
- value_addmul(Q->p[rank][j], x, Q->p[i][j]);
- }
- reduced = 1;
-
-#ifdef DEBUG
- fprintf(stderr,
- "row %d = row %d - %d row %d -----------\n", i+1, i+1, x, rank+1);
- Matrix_Print(stderr,0,H);
-#endif
-
- } /* if (x) */
- } /* for (i) */
- } /* if (pivot != 0) */
- } /* while (reduced) */
-
- /* Last finish up this column */
- /* 5. Make pivot column positive (above pivot row) */
- /* x should be zero for i>k */
-
- if (value_notzero_p(pivot)) {
- for (i=0; i<rank; i++) {
- value_assign(x,H->p[i][k]);
- if (value_notzero_p(x)) {
- value_modulus(aux,x,pivot);
-
- /* floor[integer division] (corrected for neg x) */
- if (value_neg_p(x) && value_notzero_p(aux)) {
- value_division(x,x,pivot);
- value_decrement(x,x);
-
- /* x=(x/pivot)-1; */
- }
- else
- value_division(x,x,pivot);
-
- /* H->p[i][j] -= x * H->p[rank][j]; */
- for (j=0; j<nc; j++) {
- value_multiply(aux,x,H->p[rank][j]);
- value_subtract(H->p[i][j],H->p[i][j],aux);
- }
-
- /* U->p[i][j] -= x * U->p[rank][j]; */
- if (U)
- for (j=0; j<nr; j++) {
- value_multiply(aux,x,U->p[rank][j]);
- value_subtract(U->p[i][j],U->p[i][j],aux);
- }
-
- /* Q->p[rank][j] += x * Q->p[i][j]; */
- if (Q)
- for (j=0; j<nr; j++) {
- value_addmul(Q->p[rank][j], x, Q->p[i][j]);
- }
-#ifdef DEBUG
- fprintf(stderr,
- "row %d = row %d - %d row %d -----------\n", i+1, i+1, x, rank+1);
- Matrix_Print(stderr,0,H);
-#endif
- } /* if (x) */
- } /* for (i) */
- rank++;
- } /* if (pivot!=0) */
- } /* for (k) */
-
- /* Clear all the 'Value' variables */
- value_clear(pivot); value_clear(x);
- value_clear(aux);
- for(i=0;i<nc;i++)
- value_clear(temp1[i]);
- for(i=0;i<nr;i++)
- value_clear(temp2[i]);
- free(temp2);
- free(temp1);
- return rank;
-} /* Hermite */
-
-void right_hermite(Matrix *A,Matrix **Hp,Matrix **Up,Matrix **Qp) {
-
- Matrix *H, *Q, *U;
- int i, j, nr, nc, rank;
- Value tmp;
-
- /* Computes form: A = QH , UA = H */
- nc = A->NbColumns;
- nr = A->NbRows;
-
- /* H = A */
- *Hp = H = Matrix_Alloc(nr,nc);
- if (!H) {
- errormsg1("DomRightHermite", "outofmem", "out of memory space");
- return;
- }
-
- /* Initialize all the 'Value' variables */
- value_init(tmp);
-
- Vector_Copy(A->p_Init,H->p_Init,nr*nc);
-
- /* U = I */
- if (Up) {
- *Up = U = Matrix_Alloc(nr, nr);
- if (!U) {
- errormsg1("DomRightHermite", "outofmem", "out of memory space");
- value_clear(tmp);
- return;
- }
- Vector_Set(U->p_Init,0,nr*nr); /* zero's */
- for(i=0;i<nr;i++) /* with diagonal of 1's */
- value_set_si(U->p[i][i],1);
- }
- else
- U = (Matrix *)0;
-
- /* Q = I */
- /* Actually I compute Q transpose... its easier */
- if (Qp) {
- *Qp = Q = Matrix_Alloc(nr,nr);
- if (!Q) {
- errormsg1("DomRightHermite", "outofmem", "out of memory space");
- value_clear(tmp);
- return;
- }
- Vector_Set(Q->p_Init,0,nr*nr); /* zero's */
- for (i=0;i<nr;i++) /* with diagonal of 1's */
- value_set_si(Q->p[i][i],1);
- }
- else
- Q = (Matrix *)0;
-
- rank = hermite(H,U,Q);
-
- /* Q is returned transposed */
- /* Transpose Q */
- if (Q) {
- for (i=0; i<nr; i++) {
- for (j=i+1; j<nr; j++) {
- value_assign(tmp,Q->p[i][j]);
- value_assign(Q->p[i][j],Q->p[j][i] );
- value_assign(Q->p[j][i],tmp);
- }
- }
- }
- value_clear(tmp);
- return;
-} /* right_hermite */
-
-void left_hermite(Matrix *A,Matrix **Hp,Matrix **Qp,Matrix **Up) {
-
- Matrix *H, *HT, *Q, *U;
- int i, j, nc, nr, rank;
- Value tmp;
-
- /* Computes left form: A = HQ , AU = H ,
- T T T T T T
- using right form A = Q H , U A = H */
-
- nr = A->NbRows;
- nc = A->NbColumns;
-
- /* HT = A transpose */
- HT = Matrix_Alloc(nc, nr);
- if (!HT) {
- errormsg1("DomLeftHermite", "outofmem", "out of memory space");
- return;
- }
- value_init(tmp);
- for (i=0; i<nr; i++)
- for (j=0; j<nc; j++)
- value_assign(HT->p[j][i],A->p[i][j]);
-
- /* U = I */
- if (Up) {
- *Up = U = Matrix_Alloc(nc,nc);
- if (!U) {
- errormsg1("DomLeftHermite", "outofmem", "out of memory space");
- value_clear(tmp);
- return;
- }
- Vector_Set(U->p_Init,0,nc*nc); /* zero's */
- for (i=0;i<nc;i++) /* with diagonal of 1's */
- value_set_si(U->p[i][i],1);
- }
- else U=(Matrix *)0;
-
- /* Q = I */
- if (Qp) {
- *Qp = Q = Matrix_Alloc(nc, nc);
- if (!Q) {
- errormsg1("DomLeftHermite", "outofmem", "out of memory space");
- value_clear(tmp);
- return;
- }
- Vector_Set(Q->p_Init,0,nc*nc); /* zero's */
- for (i=0;i<nc;i++) /* with diagonal of 1's */
- value_set_si(Q->p[i][i],1);
- }
- else Q=(Matrix *)0;
- rank = hermite(HT,U,Q);
-
- /* H = HT transpose */
- *Hp = H = Matrix_Alloc(nr,nc);
- if (!H) {
- errormsg1("DomLeftHermite", "outofmem", "out of memory space");
- value_clear(tmp);
- return;
- }
- for (i=0; i<nr; i++)
- for (j=0;j<nc;j++)
- value_assign(H->p[i][j],HT->p[j][i]);
- Matrix_Free(HT);
-
- /* Transpose U */
- if (U) {
- for (i=0; i<nc; i++) {
- for (j=i+1; j<nc; j++) {
- value_assign(tmp,U->p[i][j]);
- value_assign(U->p[i][j],U->p[j][i] );
- value_assign(U->p[j][i],tmp);
- }
- }
- }
- value_clear(tmp);
-} /* left_hermite */
-
-/*
- * Given a integer matrix 'Mat'(k x k), compute its inverse rational matrix
- * 'MatInv' k x (k+1). The last column of each row in matrix MatInv is used
- * to store the common denominator of the entries in a row. The output is 1,
- * if 'Mat' is non-singular (invertible), otherwise the output is 0. Note::
- * (1) Matrix 'Mat' is modified during the inverse operation.
- * (2) Matrix 'MatInv' must be preallocated before passing into this function.
- */
-int MatInverse(Matrix *Mat,Matrix *MatInv ) {
-
- int i, k, j, c;
- Value x, gcd, piv;
- Value m1,m2;
-
- if(Mat->NbRows != Mat->NbColumns) {
- fprintf(stderr,"Trying to invert a non-square matrix !\n");
- return 0;
- }
-
- /* Initialize all the 'Value' variables */
- value_init(x); value_init(gcd); value_init(piv);
- value_init(m1); value_init(m2);
-
- k = Mat->NbRows;
-
- /* Initialise MatInv */
- Vector_Set(MatInv->p[0],0,k*(k+1));
-
- /* Initialize 'MatInv' to Identity matrix form. Each diagonal entry is set*/
- /* to 1. Last column of each row (denominator of each entry in a row) is */
- /* also set to 1. */
- for(i=0;i<k;++i) {
- value_set_si(MatInv->p[i][i],1);
- value_set_si(MatInv->p[i][k],1); /* denum */
- }
- /* Apply Gauss-Jordan elimination method on the two matrices 'Mat' and */
- /* 'MatInv' in parallel. */
- for(i=0;i<k;++i) {
-
- /* Check if the diagonal entry (new pivot) is non-zero or not */
- if(value_zero_p(Mat->p[i][i])) {
-
- /* Search for a non-zero pivot down the column(i) */
- for(j=i;j<k;++j)
- if(value_notzero_p(Mat->p[j][i]))
- break;
-
- /* If no non-zero pivot is found, the matrix 'Mat' is non-invertible */
- /* Return 0. */
- if(j==k) {
-
- /* Clear all the 'Value' variables */
- value_clear(x); value_clear(gcd); value_clear(piv);
- value_clear(m1); value_clear(m2);
- return 0;
- }
-
- /* Exchange the rows, row(i) and row(j) so that the diagonal element */
- /* Mat->p[i][i] (pivot) is non-zero. Repeat the same operations on */
- /* matrix 'MatInv'. */
- for(c=0;c<k;++c) {
-
- /* Interchange rows, row(i) and row(j) of matrix 'Mat' */
- value_assign(x,Mat->p[j][c]);
- value_assign(Mat->p[j][c],Mat->p[i][c]);
- value_assign(Mat->p[i][c],x);
-
- /* Interchange rows, row(i) and row(j) of matrix 'MatInv' */
- value_assign(x,MatInv->p[j][c]);
- value_assign(MatInv->p[j][c],MatInv->p[i][c]);
- value_assign(MatInv->p[i][c],x);
- }
- }
-
- /* Make all the entries in column(i) of matrix 'Mat' zero except the */
- /* diagonal entry. Repeat the same sequence of operations on matrix */
- /* 'MatInv'. */
- for(j=0;j<k;++j) {
- if (j==i) continue; /* Skip the pivot */
- value_assign(x,Mat->p[j][i]);
- if(value_notzero_p(x)) {
- value_assign(piv,Mat->p[i][i]);
- value_gcd(gcd, x, piv);
- if (value_notone_p(gcd) ) {
- value_divexact(x, x, gcd);
- value_divexact(piv, piv, gcd);
- }
- for(c=((j>i)?i:0);c<k;++c) {
- value_multiply(m1,piv,Mat->p[j][c]);
- value_multiply(m2,x,Mat->p[i][c]);
- value_subtract(Mat->p[j][c],m1,m2);
- }
- for(c=0;c<k;++c) {
- value_multiply(m1,piv,MatInv->p[j][c]);
- value_multiply(m2,x,MatInv->p[i][c]);
- value_subtract(MatInv->p[j][c],m1,m2);
- }
-
- /* Simplify row(j) of the two matrices 'Mat' and 'MatInv' by */
- /* dividing the rows with the common GCD. */
- Vector_Gcd(&MatInv->p[j][0],k,&m1);
- Vector_Gcd(&Mat->p[j][0],k,&m2);
- value_gcd(gcd, m1, m2);
- if(value_notone_p(gcd)) {
- for(c=0;c<k;++c) {
- value_divexact(Mat->p[j][c], Mat->p[j][c], gcd);
- value_divexact(MatInv->p[j][c], MatInv->p[j][c], gcd);
- }
- }
- }
- }
- }
-
- /* Simplify every row so that 'Mat' reduces to Identity matrix. Perform */
- /* the same sequence of operations on the matrix 'MatInv'. */
- for(j=0;j<k;++j) {
- value_assign(MatInv->p[j][k],Mat->p[j][j]);
-
- /* Make the last column (denominator of each entry) of every row greater */
- /* than zero. */
- Vector_Normalize_Positive(&MatInv->p[j][0],k+1,k);
- }
-
- /* Clear all the 'Value' variables */
- value_clear(x); value_clear(gcd); value_clear(piv);
- value_clear(m1); value_clear(m2);
-
- return 1;
-} /* Mat_Inverse */
-
-/*
- * Given (m x n) integer matrix 'X' and n x (k+1) rational matrix 'P', compute
- * the rational m x (k+1) rational matrix 'S'. The last column in each row of
- * the rational matrices is used to store the common denominator of elements
- * in a row.
- */
-void rat_prodmat(Matrix *S,Matrix *X,Matrix *P) {
-
- int i,j,k;
- int last_column_index = P->NbColumns - 1;
- Value lcm, old_lcm,gcd,last_column_entry,s1;
- Value m1,m2;
-
- /* Initialize all the 'Value' variables */
- value_init(lcm); value_init(old_lcm); value_init(gcd);
- value_init(last_column_entry); value_init(s1);
- value_init(m1); value_init(m2);
-
- /* Compute the LCM of last column entries (denominators) of rows */
- value_assign(lcm,P->p[0][last_column_index]);
- for(k=1;k<P->NbRows;++k) {
- value_assign(old_lcm,lcm);
- value_assign(last_column_entry,P->p[k][last_column_index]);
- value_gcd(gcd, lcm, last_column_entry);
- value_divexact(m1, last_column_entry, gcd);
- value_multiply(lcm,lcm,m1);
- }
-
- /* S[i][j] = Sum(X[i][k] * P[k][j] where Sum is extended over k = 1..nbrows*/
- for(i=0;i<X->NbRows;++i)
- for(j=0;j<P->NbColumns-1;++j) {
-
- /* Initialize s1 to zero. */
- value_set_si(s1,0);
- for(k=0;k<P->NbRows;++k) {
-
- /* If the LCM of last column entries is one, simply add the products */
- if(value_one_p(lcm)) {
- value_addmul(s1, X->p[i][k], P->p[k][j]);
- }
-
- /* Numerator (num) and denominator (denom) of S[i][j] is given by :- */
- /* numerator = Sum(X[i][k]*P[k][j]*lcm/P[k][last_column_index]) and */
- /* denominator= lcm where Sum is extended over k = 1..nbrows. */
- else {
- value_multiply(m1,X->p[i][k],P->p[k][j]);
- value_division(m2,lcm,P->p[k][last_column_index]);
- value_addmul(s1, m1, m2);
- }
- }
- value_assign(S->p[i][j],s1);
- }
-
- for(i=0;i<S->NbRows;++i) {
- value_assign(S->p[i][last_column_index],lcm);
-
- /* Normalize the rows so that last element >=0 */
- Vector_Normalize_Positive(&S->p[i][0],S->NbColumns,S->NbColumns-1);
- }
-
- /* Clear all the 'Value' variables */
- value_clear(lcm); value_clear(old_lcm); value_clear(gcd);
- value_clear(last_column_entry); value_clear(s1);
- value_clear(m1); value_clear(m2);
-
- return;
-} /* rat_prodmat */
-
-/*
- * Given a matrix 'Mat' and vector 'p1', compute the matrix-vector product
- * and store the result in vector 'p2'.
- */
-void Matrix_Vector_Product(Matrix *Mat,Value *p1,Value *p2) {
-
- int NbRows, NbColumns, i, j;
- Value **cm, *q, *cp1, *cp2;
-
- NbRows=Mat->NbRows;
- NbColumns=Mat->NbColumns;
-
- cm = Mat->p;
- cp2 = p2;
- for(i=0;i<NbRows;i++) {
- q = *cm++;
- cp1 = p1;
- value_multiply(*cp2,*q,*cp1);
- q++;
- cp1++;
-
- /* *cp2 = *q++ * *cp1++ */
- for(j=1;j<NbColumns;j++) {
- value_addmul(*cp2, *q, *cp1);
- q++;
- cp1++;
- }
- cp2++;
- }
- return;
-} /* Matrix_Vector_Product */
-
-/*
- * Given a vector 'p1' and a matrix 'Mat', compute the vector-matrix product
- * and store the result in vector 'p2'
- */
-void Vector_Matrix_Product(Value *p1,Matrix *Mat,Value *p2) {
-
- int NbRows, NbColumns, i, j;
- Value **cm, *cp1, *cp2;
-
- NbRows=Mat->NbRows;
- NbColumns=Mat->NbColumns;
- cp2 = p2;
- cm = Mat->p;
- for (j=0;j<NbColumns;j++) {
- cp1 = p1;
- value_multiply(*cp2,*(*cm+j),*cp1);
- cp1++;
-
- /* *cp2= *(*cm+j) * *cp1++; */
- for (i=1;i<NbRows;i++) {
- value_addmul(*cp2, *(*(cm+i)+j), *cp1);
- cp1++;
- }
- cp2++;
- }
- return;
-} /* Vector_Matrix_Product */
-
-/*
- * Given matrices 'Mat1' and 'Mat2', compute the matrix product and store in
- * matrix 'Mat3'
- */
-void Matrix_Product(Matrix *Mat1,Matrix *Mat2,Matrix *Mat3) {
-
- int Size, i, j, k;
- unsigned NbRows, NbColumns;
- Value **q1, **q2, *p1, *p3,sum;
-
- NbRows = Mat1->NbRows;
- NbColumns = Mat2->NbColumns;
-
- Size = Mat1->NbColumns;
- if(Mat2->NbRows!=Size||Mat3->NbRows!=NbRows||Mat3->NbColumns!=NbColumns) {
- fprintf(stderr, "? Matrix_Product : incompatable matrix dimension\n");
- return;
- }
- value_init(sum);
- p3 = Mat3->p_Init;
- q1 = Mat1->p;
- q2 = Mat2->p;
-
- /* Mat3[i][j] = Sum(Mat1[i][k]*Mat2[k][j] where sum is over k = 1..nbrows */
- for (i=0;i<NbRows;i++) {
- for (j=0;j<NbColumns;j++) {
- p1 = *(q1+i);
- value_set_si(sum,0);
- for (k=0;k<Size;k++) {
- value_addmul(sum, *p1, *(*(q2+k)+j));
- p1++;
- }
- value_assign(*p3,sum);
- p3++;
- }
- }
- value_clear(sum);
- return;
-} /* Matrix_Product */
-
-/*
- * Given a rational matrix 'Mat'(k x k), compute its inverse rational matrix
- * 'MatInv' k x k.
- * The output is 1,
- * if 'Mat' is non-singular (invertible), otherwise the output is 0. Note::
- * (1) Matrix 'Mat' is modified during the inverse operation.
- * (2) Matrix 'MatInv' must be preallocated before passing into this function.
- */
-int Matrix_Inverse(Matrix *Mat,Matrix *MatInv ) {
-
- int i, k, j, c;
- Value x, gcd, piv;
- Value m1,m2;
- Value *den;
-
- if(Mat->NbRows != Mat->NbColumns) {
- fprintf(stderr,"Trying to invert a non-square matrix !\n");
- return 0;
- }
-
- /* Initialize all the 'Value' variables */
- value_init(x); value_init(gcd); value_init(piv);
- value_init(m1); value_init(m2);
-
- k = Mat->NbRows;
-
- /* Initialise MatInv */
- Vector_Set(MatInv->p[0],0,k*k);
-
- /* Initialize 'MatInv' to Identity matrix form. Each diagonal entry is set*/
- /* to 1. Last column of each row (denominator of each entry in a row) is */
- /* also set to 1. */
- for(i=0;i<k;++i) {
- value_set_si(MatInv->p[i][i],1);
- /* value_set_si(MatInv->p[i][k],1); /* denum */
- }
- /* Apply Gauss-Jordan elimination method on the two matrices 'Mat' and */
- /* 'MatInv' in parallel. */
- for(i=0;i<k;++i) {
-
- /* Check if the diagonal entry (new pivot) is non-zero or not */
- if(value_zero_p(Mat->p[i][i])) {
-
- /* Search for a non-zero pivot down the column(i) */
- for(j=i;j<k;++j)
- if(value_notzero_p(Mat->p[j][i]))
- break;
-
- /* If no non-zero pivot is found, the matrix 'Mat' is non-invertible */
- /* Return 0. */
- if(j==k) {
-
- /* Clear all the 'Value' variables */
- value_clear(x); value_clear(gcd); value_clear(piv);
- value_clear(m1); value_clear(m2);
- return 0;
- }
-
- /* Exchange the rows, row(i) and row(j) so that the diagonal element */
- /* Mat->p[i][i] (pivot) is non-zero. Repeat the same operations on */
- /* matrix 'MatInv'. */
- for(c=0;c<k;++c) {
-
- /* Interchange rows, row(i) and row(j) of matrix 'Mat' */
- value_assign(x,Mat->p[j][c]);
- value_assign(Mat->p[j][c],Mat->p[i][c]);
- value_assign(Mat->p[i][c],x);
-
- /* Interchange rows, row(i) and row(j) of matrix 'MatInv' */
- value_assign(x,MatInv->p[j][c]);
- value_assign(MatInv->p[j][c],MatInv->p[i][c]);
- value_assign(MatInv->p[i][c],x);
- }
- }
-
- /* Make all the entries in column(i) of matrix 'Mat' zero except the */
- /* diagonal entry. Repeat the same sequence of operations on matrix */
- /* 'MatInv'. */
- for(j=0;j<k;++j) {
- if (j==i) continue; /* Skip the pivot */
- value_assign(x,Mat->p[j][i]);
- if(value_notzero_p(x)) {
- value_assign(piv,Mat->p[i][i]);
- value_gcd(gcd, x, piv);
- if (value_notone_p(gcd) ) {
- value_divexact(x, x, gcd);
- value_divexact(piv, piv, gcd);
- }
- for(c=((j>i)?i:0);c<k;++c) {
- value_multiply(m1,piv,Mat->p[j][c]);
- value_multiply(m2,x,Mat->p[i][c]);
- value_subtract(Mat->p[j][c],m1,m2);
- }
- for(c=0;c<k;++c) {
- value_multiply(m1,piv,MatInv->p[j][c]);
- value_multiply(m2,x,MatInv->p[i][c]);
- value_subtract(MatInv->p[j][c],m1,m2);
- }
-
- /* Simplify row(j) of the two matrices 'Mat' and 'MatInv' by */
- /* dividing the rows with the common GCD. */
- Vector_Gcd(&MatInv->p[j][0],k,&m1);
- Vector_Gcd(&Mat->p[j][0],k,&m2);
- value_gcd(gcd, m1, m2);
- if(value_notone_p(gcd)) {
- for(c=0;c<k;++c) {
- value_divexact(Mat->p[j][c], Mat->p[j][c], gcd);
- value_divexact(MatInv->p[j][c], MatInv->p[j][c], gcd);
- }
- }
- }
- }
- }
-
- /* Find common denom for each row */
- den = (Value *)malloc(k*sizeof(Value));
- value_set_si(x,1);
- for(j=0 ; j<k ; ++j) {
- value_init(den[j]);
- value_assign(den[j],Mat->p[j][j]);
-
- /* gcd is always positive */
- Vector_Gcd(&MatInv->p[j][0],k,&gcd);
- value_gcd(gcd, gcd, den[j]);
- if (value_neg_p(den[j]))
- value_oppose(gcd,gcd); /* make denominator positive */
- if (value_notone_p(gcd)) {
- for (c=0; c<k; c++)
- value_divexact(MatInv->p[j][c], MatInv->p[j][c], gcd); /* normalize */
- value_divexact(den[j], den[j], gcd);
- }
- value_gcd(gcd, x, den[j]);
- value_divexact(m1, den[j], gcd);
- value_multiply(x,x,m1);
- }
- if (value_notone_p(x))
- for(j=0 ; j<k ; ++j) {
- for (c=0; c<k; c++) {
- value_division(m1,x,den[j]);
- value_multiply(MatInv->p[j][c],MatInv->p[j][c],m1); /* normalize */
- }
- }
-
- /* Clear all the 'Value' variables */
- for(j=0 ; j<k ; ++j) {
- value_clear(den[j]);
- }
- value_clear(x); value_clear(gcd); value_clear(piv);
- value_clear(m1); value_clear(m2);
- free(den);
-
- return 1;
-} /* Matrix_Inverse */
-
-
-
-
-
-
-
-
diff --git a/source/polylib_mod/matrix_addon.c b/source/polylib_mod/matrix_addon.c
deleted file mode 100644
index 5728e51..0000000
--- a/source/polylib_mod/matrix_addon.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * $Id: matrix_addon.c,v 1.17 2007/03/18 18:49:08 skimo Exp $
- *
- * Polylib matrix addons
- * Mainly, deals with polyhedra represented as a matrix (implicit form)
- * @author Benoit Meister <meister at icps.u-strasbg.fr>
- *
- */
-
-#include <stdlib.h>
-#include<polylib/polylib.h>
-#include <polylib/matrix_addon.h>
-
-/** Creates a view of the constraints of a polyhedron as a Matrix * */
-Matrix * constraintsView(Polyhedron * P) {
- Matrix * view = (Matrix *)malloc(sizeof(Matrix));
- view->NbRows = P->NbConstraints;
- view->NbColumns = P->Dimension+2;
- view->p = P->Constraint;
- return view;
-}
-
-/** "Frees" a view of the constraints of a polyhedron */
-void constraintsView_Free(Matrix * M) {
- free(M);
-}
-
-/**
- * splits a matrix of constraints M into a matrix of equalities Eqs and a
- * matrix of inequalities Ineqs allocs the new matrices.
- * Allocates Eqs and Ineqs.
-*/
-void split_constraints(Matrix const * M, Matrix ** Eqs, Matrix **Ineqs) {
- unsigned int i, j, k_eq, k_ineq, nb_eqs=0;
-
- /* 1- count the number of equations */
- for (i=0; i< M->NbRows; i++)
- if (value_zero_p(M->p[i][0])) nb_eqs++;
-
- /* 2- extract the two matrices of equations */
- (*Eqs) = Matrix_Alloc(nb_eqs, M->NbColumns);
- (*Ineqs) = Matrix_Alloc(M->NbRows-nb_eqs, M->NbColumns);
-
- k_eq = k_ineq = 0;
- for(i=0; i< M->NbRows; i++) {
- if (value_zero_p(M->p[i][0]))
- {
- for(j=0; j< M->NbColumns; j++)
- value_assign((*Eqs)->p[k_eq][j], M->p[i][j]);
- k_eq++;
- }
- else
- {
- for(j=0; j< M->NbColumns; j++)
- value_assign((*Ineqs)->p[k_ineq][j], M->p[i][j]);
- k_ineq++;
- }
- }
-}
-
-
-/* returns the dim-dimensional identity matrix */
-Matrix * Identity_Matrix(unsigned int dim) {
- Matrix * ret = Matrix_Alloc(dim, dim);
- unsigned int i,j;
- for (i=0; i< dim; i++) {
- for (j=0; j< dim; j++) {
- if (i==j)
- { value_set_si(ret->p[i][j], 1); }
- else value_set_si(ret->p[i][j], 0);
- }
- }
- return ret;
-} /* Identity_Matrix */
-
-
-/**
- * returns the dim-dimensional identity matrix.
- * If I is set to NULL, allocates it first.
- * Else, assumes an existing, allocated Matrix.
-*/
-void Matrix_identity(unsigned int dim, Matrix ** I) {
- int i,j;
- if (*I==NULL) {
- (*I) = Identity_Matrix(dim);
- }
- else {
- assert((*I)->NbRows>=dim && (*I)->NbColumns>=dim);
- for (i=0; i< dim; i++) {
- for (j=0; j< dim; j++) {
- if (i==j) {
- value_set_si((*I)->p[i][j], 1);
- }
- else {
- value_set_si((*I)->p[i][j], 0);
- }
- }
- }
- }
-} /* Matrix_identity */
-
-
-/** given a n x n integer transformation matrix transf, compute its inverse
- M/g, where M is a nxn integer matrix. g is a common denominator for
- elements of (transf^{-1}) */
-void mtransformation_inverse(Matrix * transf, Matrix ** inverse, Value * g) {
- Value factor;
- unsigned int i,j;
- Matrix *tmp, *inv;
-
- value_init(*g);
- value_set_si(*g,1);
-
- /* a - compute the inverse as usual (n x (n+1) matrix) */
- tmp = Matrix_Copy(transf);
- inv = Matrix_Alloc(transf->NbRows, transf->NbColumns+1);
- MatInverse(tmp, inv);
- Matrix_Free(tmp);
-
- /* b - as it is rational, put it to the same denominator*/
- (*inverse) = Matrix_Alloc(transf->NbRows, transf->NbRows);
- for (i=0; i< inv->NbRows; i++)
- value_lcm(*g, *g, inv->p[i][inv->NbColumns-1]);
- for (i=0; i< inv->NbRows; i++) {
- value_division(factor, *g, inv->p[i][inv->NbColumns-1]);
- for (j=0; j< (*inverse)->NbColumns; j++)
- value_multiply((*inverse)->p[i][j], inv->p[i][j], factor);
- }
-
- /* c- clean up */
- value_clear(factor);
- Matrix_Free(inv);
-} /* mtransformation_inverse */
-
-
-/** takes a transformation matrix, and expands it to a higher dimension with
- the identity matrix regardless of it homogeneousness */
-Matrix * mtransformation_expand_left_to_dim(Matrix * M, int new_dim) {
- Matrix * ret = Identity_Matrix(new_dim);
- int offset = new_dim-M->NbRows;
- unsigned int i,j;
-
- assert(new_dim>=M->NbColumns);
- assert(M->NbRows==M->NbColumns);
-
- for (i=0; i< M->NbRows; i++)
- for (j=0; j< M->NbRows; j++)
- value_assign(ret->p[offset+i][offset+j], M->p[i][j]);
- return ret;
-} /* mtransformation_expand_left_to_dim */
-
-
-/** simplify a matrix seen as a polyhedron, by dividing its rows by the gcd of
- their elements. */
-void mpolyhedron_simplify(Matrix * polyh) {
- int i, j;
- Value cur_gcd;
- value_init(cur_gcd);
- for (i=0; i< polyh->NbRows; i++) {
- Vector_Gcd(polyh->p[i]+1, polyh->NbColumns-1, &cur_gcd);
- printf(" gcd[%d] = ", i);
- value_print(stdout, VALUE_FMT, cur_gcd);printf("\n");
- Vector_AntiScale(polyh->p[i]+1, polyh->p[i]+1, cur_gcd, polyh->NbColumns-1);
- }
- value_clear(cur_gcd);
-} /* mpolyhedron_simplify */
-
-
-/** inflates a polyhedron (represented as a matrix) P, so that the apx of its
- Ehrhart Polynomial is an upper bound of the Ehrhart polynomial of P
- WARNING: this inflation is supposed to be applied on full-dimensional
- polyhedra. */
-void mpolyhedron_inflate(Matrix * polyh, unsigned int nb_parms) {
- unsigned int i,j;
- unsigned nb_vars = polyh->NbColumns-nb_parms-2;
- Value infl;
- value_init(infl);
- /* subtract the sum of the negative coefficients of each inequality */
- for (i=0; i< polyh->NbRows; i++) {
- value_set_si(infl, 0);
- for (j=0; j< nb_vars; j++) {
- if (value_neg_p(polyh->p[i][1+j]))
- value_addto(infl, infl, polyh->p[i][1+j]);
- }
- /* here, we subtract a negative value */
- value_subtract(polyh->p[i][polyh->NbColumns-1],
- polyh->p[i][polyh->NbColumns-1], infl);
- }
- value_clear(infl);
-} /* mpolyhedron_inflate */
-
-
-/** deflates a polyhedron (represented as a matrix) P, so that the apx of its
- Ehrhart Polynomial is a lower bound of the Ehrhart polynomial of P WARNING:
- this deflation is supposed to be applied on full-dimensional polyhedra. */
-void mpolyhedron_deflate(Matrix * polyh, unsigned int nb_parms) {
- unsigned int i,j;
- unsigned nb_vars = polyh->NbColumns-nb_parms-2;
- Value defl;
- value_init(defl);
- /* substract the sum of the negative coefficients of each inequality */
- for (i=0; i< polyh->NbRows; i++) {
- value_set_si(defl, 0);
- for (j=0; j< nb_vars; j++) {
- if (value_pos_p(polyh->p[i][1+j]))
- value_addto(defl, defl, polyh->p[i][1+j]);
- }
- /* here, we substract a negative value */
- value_subtract(polyh->p[i][polyh->NbColumns-1],
- polyh->p[i][polyh->NbColumns-1], defl);
- }
- value_clear(defl);
-} /* mpolyhedron_deflate */
-
-
-/** use an eliminator row to eliminate a variable in a victim row (without
- * changing the sign of the victim row -> important if it is an inequality).
- * @param Eliminator the matrix containing the eliminator row
- * @param eliminator_row the index of the eliminator row in <tt>Eliminator</tt>
- * @param Victim the matrix containing the row to be eliminated
- * @param victim_row the row to be eliminated in <tt>Victim</tt>
- * @param var_to_elim the variable to be eliminated.
- */
-void eliminate_var_with_constr(Matrix * Eliminator,
- unsigned int eliminator_row, Matrix * Victim,
- unsigned int victim_row,
- unsigned int var_to_elim) {
- Value cur_lcm, mul_a, mul_b;
- Value tmp, tmp2;
- int k;
-
- value_init(cur_lcm);
- value_init(mul_a);
- value_init(mul_b);
- value_init(tmp);
- value_init(tmp2);
- /* if the victim coefficient is not zero */
- if (value_notzero_p(Victim->p[victim_row][var_to_elim+1])) {
- value_lcm(cur_lcm, Eliminator->p[eliminator_row][var_to_elim+1],
- Victim->p[victim_row][var_to_elim+1]);
- /* multiplication factors */
- value_division(mul_a, cur_lcm,
- Eliminator->p[eliminator_row][var_to_elim+1]);
- value_division(mul_b, cur_lcm,
- Victim->p[victim_row][var_to_elim+1]);
- /* the multiplicator for the vitim row has to be positive */
- if (value_pos_p(mul_b)) {
- value_oppose(mul_a, mul_a);
- }
- else {
- value_oppose(mul_b, mul_b);
- }
- value_clear(cur_lcm);
- /* now we have a.mul_a = -(b.mul_b) and mul_a > 0 */
- for (k=1; k<Victim->NbColumns; k++) {
- value_multiply(tmp, Eliminator->p[eliminator_row][k], mul_a);
- value_multiply(tmp2, Victim->p[victim_row][k], mul_b);
- value_addto(Victim->p[victim_row][k], tmp, tmp2);
- }
- }
- value_clear(mul_a);
- value_clear(mul_b);
- value_clear(tmp);
- value_clear(tmp2);
-}
-/* eliminate_var_with_constr */
-
-
-/* STUFF WITH PARTIAL MAPPINGS (Mappings to a subset of the
- variables/parameters) : on the first or last variables/parameters */
-
-/** compress the last vars/pars of the polyhedron M expressed as a polylib
- matrix
- - adresses the full-rank compressions only
- - modfies M */
-void mpolyhedron_compress_last_vars(Matrix * M, Matrix * compression) {
- unsigned int i, j, k;
- unsigned int offset = M->NbColumns - compression->NbRows;
- /* the computations on M will begin on column "offset" */
-
- Matrix * M_tmp = Matrix_Alloc(1, M->NbColumns);
- assert(compression->NbRows==compression->NbColumns);
- /* basic matrix multiplication (using a temporary row instead of a whole
- temporary matrix), but with a column offset */
- for(i=0; i< M->NbRows; i++) {
- for (j=0; j< compression->NbRows; j++) {
- value_set_si(M_tmp->p[0][j], 0);
- for (k=0; k< compression->NbRows; k++) {
- value_addmul(M_tmp->p[0][j], M->p[i][k+offset],compression->p[k][j]);
- }
- }
- for (j=0; j< compression->NbRows; j++)
- value_assign(M->p[i][j+offset], M_tmp->p[0][j]);
- }
- Matrix_Free(M_tmp);
-} /* mpolyhedron_compress_last_vars */
-
-
-/** use a set of m equalities Eqs to eliminate m variables in the polyhedron
- Ineqs represented as a matrix
- eliminates the m first variables
- - assumes that Eqs allow to eliminate the m equalities
- - modifies Eqs and Ineqs */
-unsigned int mpolyhedron_eliminate_first_variables(Matrix * Eqs,
- Matrix *Ineqs) {
- unsigned int i, j, k;
- /* eliminate one variable (index i) after each other */
- for (i=0; i< Eqs->NbRows; i++) {
- /* find j, the first (non-marked) row of Eqs with a non-zero coefficient */
- for (j=0; j<Eqs->NbRows && (Eqs->p[j][i+1]==0 ||
- ( !value_cmp_si(Eqs->p[j][0],2) ));
- j++);
- /* if no row is found in Eqs that allows to eliminate variable i, return an
- error code (0) */
- if (j==Eqs->NbRows) return 0;
- /* else, eliminate variable i in Eqs and Ineqs with the j^th row of Eqs
- (and mark this row so we don't use it again for an elimination) */
- for (k=j+1; k<Eqs->NbRows; k++)
- eliminate_var_with_constr(Eqs, j, Eqs, k, i);
- for (k=0; k< Ineqs->NbRows; k++)
- eliminate_var_with_constr(Eqs, j, Ineqs, k, i);
- /* mark the row */
- value_set_si(Eqs->p[j][0],2);
- }
- /* un-mark all the rows */
- for (i=0; i< Eqs->NbRows; i++) value_set_si(Eqs->p[i][0],0);
- return 1;
-} /* mpolyhedron_eliminate_first_variables */
-
-
-/** returns a contiguous submatrix of a matrix.
- * @param M the input matrix
- * @param sr the index of the starting row
- * @param sc the index of the starting column
- * @param er the index ofthe ending row (excluded)
- * @param ec the ined of the ending colummn (excluded)
- * @param sub (returned), the submatrix. Allocated if set to NULL, assumed to
- * be already allocated else.
- */
-void Matrix_subMatrix(Matrix * M, unsigned int sr, unsigned int sc,
- unsigned int er, unsigned int ec, Matrix ** sub) {
- int i;
- int nbR = er-sr;
- int nbC = ec-sc;
- assert (er<=M->NbRows && ec<=M->NbColumns);
- if ((*sub)==NULL) {
- (*sub) = Matrix_Alloc(nbR, nbC);
- }
- if (nbR==0 || nbC==0) return;
- for (i=0; i< nbR; i++) {
- Vector_Copy(&(M->p[i+sr][sc]), (*sub)->p[i], nbC);
- }
-}/* Matrix_subMatrix */
-
-
-/**
- * Cloning function. Similar to Matrix_Copy() but allocates the target matrix
- * if it is set to NULL.
- */
-void Matrix_clone(Matrix * M, Matrix ** Cl) {
- Matrix_subMatrix(M, 0,0, M->NbRows, M->NbColumns, Cl);
-}
-
-
-/**
- * Copies a contiguous submatrix of M1 into M2, at the indicated position.
- * M1 and M2 are assumed t be allocated already.
- * @param M1 the source matrix
- * @param sr1 the starting source row
- * @param sc1 the starting source column
- * @param nbR the number of rows
- * @param nbC the number of columns
- * @param M2 the target matrix
- * @param sr2 the starting target row
- * @param sc2 the starting target column
-*/
-void Matrix_copySubMatrix(Matrix *M1,
- unsigned int sr1, unsigned int sc1,
- unsigned int nbR, unsigned int nbC,
- Matrix * M2,
- unsigned int sr2, unsigned int sc2) {
- int i;
- for (i=0; i< nbR; i++) {
- Vector_Copy(&(M1->p[i+sr1][sc1]), &(M2->p[i+sr2][sc2]), nbC);
- }
-} /* Matrix_copySubMatrix */
-
-
-/**
- * transforms a matrix M into -M
- */
-void Matrix_oppose(Matrix * M) {
- int i,j;
- for (i=0; i<M->NbRows; i++) {
- for (j=0; j< M->NbColumns; j++) {
- value_oppose(M->p[i][j], M->p[i][j]);
- }
- }
-}
diff --git a/source/polylib_mod/matrix_permutations.c b/source/polylib_mod/matrix_permutations.c
deleted file mode 100644
index a93bbc2..0000000
--- a/source/polylib_mod/matrix_permutations.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * $Id: matrix_permutations.c,v 1.8 2006/10/01 02:10:46 meister Exp $
- *
- * Permutations on matrices Matrices are seen either as transformations
- * (mtransformation) or as polyhedra (mpolyhedron)
- * @author B. Meister
- * LSIIT -ICPS
- * UMR 7005 CNRS
- * Louis Pasteur University (ULP), Strasbourg, France
- *
- * Permutations are just indirection vectors: the k^th element of a permutation
- * vector is the position of the k^th variable in the permuted object.
- */
-
-#include <stdlib.h>
-#include <polylib/matrix_permutations.h>
-
-/** utility function : bit count (i know, there are faster methods) */
-unsigned int nb_bits(unsigned long long int x) {
- unsigned int i,n=0;
- unsigned long long int y=x;
- for (i=0; i< 64; i++) {
- n+=y%2;
- y>>=1;
- }
- return n;
-}
-
-
-/** Gives the inverse permutation vector of a permutation vector
- * @param perm the permutation vector
- * @param
-*/
-unsigned int * permutation_inverse(unsigned int * perm, unsigned int nb_elems) {
- int i;
- unsigned int * inv_perm = (unsigned int *)malloc(sizeof(unsigned int) * nb_elems);
- for (i=0; i< nb_elems; i++) inv_perm[perm[i]] = i;
- return inv_perm;
-}
-
-
-/**
- * Given a linear tranformation on initial variables, and a variable
- * permutation, computes the tranformation for the permuted variables. perm is
- * a vector giving the new "position of the k^th variable, k \in [1..n] we can
- * call it a "permutation vector" if you wish transf[x][y] ->
- * permuted[permutation(x)][permutation(y)]
- */
-Matrix * mtransformation_permute(Matrix * transf, unsigned int * permutation) {
- Matrix * permuted;
- unsigned int i,j;
- /* the transformation is supposed to be from Q^n to Q^n, so a square matrix. */
- assert(transf->NbRows==transf->NbColumns);
- permuted = Matrix_Alloc(transf->NbRows, transf->NbRows);
- for (i= 0; i< transf->NbRows; i++) {
- for (j= 0; j< transf->NbRows; j++) {
- value_assign(permuted->p[permutation[i]][permutation[j]], transf->p[i][j]);
- }
- }
- return permuted;
-}
-
-
-/** permutes the variables of the constraints of a polyhedron
- * @param polyh the constraints of the polyhedron
- * @param permutation a permutation vector
-*/
-Matrix * mpolyhedron_permute(Matrix * polyh, unsigned int * permutation) {
- unsigned int i,j;
- Matrix * permuted = Matrix_Alloc(polyh->NbRows, polyh->NbColumns);
- for (i= 0; i< polyh->NbRows; i++) {
- value_assign(permuted->p[i][0], polyh->p[i][0]);
- for (j= 1; j< polyh->NbColumns; j++) {
- value_assign(permuted->p[i][permutation[j-1]+1], polyh->p[i][j]);
- }
- }
- return permuted;
-}
-
-
-/** permutes the variables of the constraints of a polyhedron
- * @param C the original set of constraints
- * @param perm a permutation vector
- * @param Cp (returned) the set of constraints whose variables are
- * permuted. Allocated if set to NULL, assumed to be already allocated if not.
- */
-void Constraints_permute(Matrix * C, unsigned int * perm, Matrix ** Cp) {
- unsigned int i,j;
- if ((*Cp)==NULL) {
- (*Cp) = Matrix_Alloc(C->NbRows, C->NbColumns);
- }
- else {
- assert((*Cp)->NbRows == C->NbRows && (*Cp)->NbColumns==C->NbColumns);
- }
- for (i= 0; i< C->NbRows; i++) {
- value_assign((*Cp)->p[i][0], C->p[i][0]);
- for (j= 1; j< C->NbColumns; j++) {
- value_assign((*Cp)->p[i][perm[j-1]+1], C->p[i][j]);
- }
- }
-} /* Constraints_permute */
-
-
-/** Given a set of <i>equalities</i>, find a set of variables that can be
- * eliminated using these equalities. The variables that we agree to eliminate
- * are in a zone of contiguous variables (or parameters). <p>
- * Notes:
- <ul>
- <li>brute force, surely enhanceable algorithm</li>
- <li>limited number of variables in the zone: limit = bitwidth of long long
- </ul>
- * @param Eqs the matrix of equalities.
- * @param start the rank of the first variable (inclusive) of the zone in Eqs
- * @param end the rank of the last variable (inclusive) of the zone
- * return a bitfield where bits set to one define the variables to eliminate
-*/
-unsigned long long int eliminable_vars(Matrix * Eqs, unsigned start,
- unsigned end) {
- unsigned long long int combination;
- unsigned int i,j,k;
- Matrix * M, * H, * Q, *U;
- Matrix * Square_Mat, *Eqs2;
- unsigned nb_vars = end - start + 1 ;
- Polyhedron * OverConstrained;
-
- assert (start>0 && end < Eqs->NbColumns-1);
-
- /* if the affine hull is overconstrained, return 0 */
- if (Eqs->NbRows >nb_vars) {
- /* FIXME: there is a magic maximum number of rays here */
- Eqs2 = Matrix_Copy(Eqs);
- OverConstrained = Constraints2Polyhedron(Eqs2,
- Eqs->NbColumns*Eqs->NbColumns);
- Matrix_Free(Eqs2);
- if (emptyQ(OverConstrained)) {
- Polyhedron_Free(OverConstrained);
- return 0;
- }
- Polyhedron_Free(OverConstrained);
- }
-
- /* do not accept 0 = 0 equalities */
- for (i=0; i< Eqs->NbRows; i++) {
- assert (!Vector_IsZero(Eqs->p[i], Eqs->NbColumns));
- }
-
- Square_Mat= Matrix_Alloc(Eqs->NbRows, Eqs->NbRows);
-
- /* There are Eqs->NbRows variables to eliminate.
- Generate all the combinations of Eqs->NbRows variables (-> bits to 1 in
- the word "combination") among nb_vars WARNING : we assume here that we
- have not more than 64 variables. You may convert it to use GNU MP to
- set it to an infinite number of bits
- */
- for (combination = ((unsigned long long int) 1<<(Eqs->NbRows))-1;
- (combination < ((unsigned long long int) 1 << nb_vars)) ;
- combination++) {
- if (nb_bits(combination) == Eqs->NbRows) {
- k=0;
- /* 1- put the m colums in a square matrix */
- for (j=0; j< nb_vars; j++) {
- if ((combination>>j)%2) {
- for (i=0; i< Eqs->NbRows; i++) {
- value_assign(Square_Mat->p[i][k], Eqs->p[i][j+start]);
- }
- k++;
- }
- }
- /* 2- see if the matrix is full-row-rank */
- right_hermite(Square_Mat, &H, &Q, &U);
- Matrix_Free(Q);
- Matrix_Free(U);
-
- /* if it is full-row-rank, we have found a set of variables that can be
- eliminated. */
- if ( value_notzero_p((H->p[Eqs->NbRows-1][Eqs->NbRows-1])) ) {
- Matrix_Free(Square_Mat);
- Matrix_Free(H);
- return combination;
- }
- Matrix_Free(H);
- }
- }
- Matrix_Free(Square_Mat);
- return (unsigned long long int) 0;
-} /* eliminable_vars */
-
-
-
-/**
- * finds a valid permutation : for a set of m equations, find m variables that
- * will be put at the beginning (to be eliminated).
- * Note: inherits the limited the number of variables from
- * <i>eliminable_vars</i>
- */
-unsigned int * find_a_permutation(Matrix * Eqs, unsigned int nb_parms) {
- unsigned int i, j, k;
- int nb_vars = Eqs->NbColumns-nb_parms-2;
- unsigned long long int combination;
- unsigned int * permutation = (unsigned int *)malloc(sizeof(unsigned int) *
- Eqs->NbColumns-1);
-
- /* 1- find a set of variables to eliminate */
- if ((combination = eliminable_vars(Eqs, 1, nb_vars)) == 0) {
- /* if it is impossible to eliminate enough variables, return error code */
- return NULL;
- }
-
- /* 2- make the permutation matrix
- * a- deal with the variables */
- k=0;
- for (i=0; i< nb_vars; i++) {
- /* if the variable has to be eliminated, put them at the beginning */
- if (combination%2) {
- permutation[i] = k;
- k++;
- }
- /* if not, put the variables at the end */
- else permutation[i] = Eqs->NbRows+nb_parms+ i-k;
- combination>>=1;
- }
- /* b- deal with the parameters */
- for (i=0; i< nb_parms; i++) {
- permutation[nb_vars+i] = Eqs->NbRows+i;
- }
- /* c- deal with the constant */
- permutation[Eqs->NbColumns-2] = Eqs->NbColumns-2;
-
- return permutation;
-} /* find_a_permutation */
-
-
-
-/** computes the permutation of variables and parameters, according to some
- * variables to keep. put the variables not to be kept at the beginning, then
- * the parameters and finally the variables to be kept. strongly related to
- * the function compress_to_full_dim2
- */
-unsigned int * permutation_for_full_dim2(unsigned int * vars_to_keep,
- unsigned int nb_keep,
- unsigned int nb_vars_parms,
- unsigned int nb_parms) {
- unsigned int * permutation =
- (unsigned int*)malloc(sizeof(unsigned int) * nb_vars_parms+1);
- unsigned int i;
- int cur_keep =0, cur_go = 0;/*current number of variables to eliminate/keep*/
- for (i=0; i< nb_vars_parms - nb_parms; i++) {
- if (i==vars_to_keep[cur_keep]) {
- permutation[i] = nb_vars_parms-nb_keep+cur_keep;
- cur_keep++;
- }
- else {
- permutation[i] = cur_go;
- cur_go++;
- }
- }
- /* parameters are just left-shifted */
- for (i=0; i< nb_parms; i++)
- permutation[i+nb_vars_parms-nb_parms] = i+nb_vars_parms-nb_parms-nb_keep;
-
- /* contants stay where they are */
- permutation[nb_vars_parms] = nb_vars_parms;
- return permutation;
-} /* permutation_for_full_dim2 */
diff --git a/source/polylib_mod/param.c b/source/polylib_mod/param.c
deleted file mode 100644
index ca54d74..0000000
--- a/source/polylib_mod/param.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <polylib/polylib.h>
-
-/****************************************************/
-/* Read_ParamNames() : */
-/* Reads FILE *in for the parameter names */
-/* if in==NULL or not enough parameters on input, */
-/* use default names */
-/* returns an n-array of strings */
-/****************************************************/
-const char **Read_ParamNames(FILE *in,int m)
-{
- char **param_name;
- int c, i, j, f;
- char s[1024],param[32];
-
- if(!in)
- f = 0;
- else
- do
- f = (fgets(s, 1024, in)!=NULL);
- while (f && (*s=='#' || *s=='\n'));
-
- param_name = (char **)malloc(m*sizeof(char *));
- i = 0;
- if(f) {
- c = 0;
- for(;i<m;++i) {
- j=0;
- for(;;++c) {
- if(s[c]==' ') {
- if(j==0)
- continue;
- else
- break;
- }
- if(s[c]=='\n' || s[c]==0)
- break;
- param[j++] = s[c];
- }
-
- /* Not enough parameters on input, end */
- if(j==0)
- break;
- param[j] = 0;
- param_name[i] = (char *)malloc( (j+1)*sizeof(char) );
- strcpy(param_name[i],param);
- }
- }
-
- /* Not enough parameters on input : use default names */
- if(!f || i!=m) {
- for(;i<m;++i) {
- param_name[i] = (char *) malloc(2*sizeof(char));
- sprintf(param_name[i], "%c", PCHAR+i+1);
- }
- }
- return (const char**)param_name;
-} /* Read_ParamNames */
-
-void Free_ParamNames(const char **params, int m)
-{
- while (--m >= 0)
- free((char *)params[m]);
- free(params);
-}
diff --git a/source/polylib_mod/polyhedron.c b/source/polylib_mod/polyhedron.c
deleted file mode 100644
index 30ce04d..0000000
--- a/source/polylib_mod/polyhedron.c
+++ /dev/null
@@ -1,4721 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* polyhedron.c
- COPYRIGHT
- Both this software and its documentation are
-
- Copyright 1993 by IRISA /Universite de Rennes I - France,
- Copyright 1995,1996 by BYU, Provo, Utah
- all rights reserved.
-
- Permission is granted to copy, use, and distribute
- for any commercial or noncommercial purpose under the terms
- of the GNU General Public license, version 2, June 1991
- (see file : LICENSING).
-*/
-
-/*
-
-1997/12/02 - Olivier Albiez
- Ce fichier contient les fonctions de la polylib de l'IRISA,
- passees en 64bits.
- La structure de la polylib a donc ete modifie pour permettre
- le passage aux Value. La fonction Chernikova a ete reecrite.
-
-*/
-
-/*
-
-1998/26/02 - Vincent Loechner
- Ajout de nombreuses fonctions, a la fin de ce fichier,
- pour les polyedres parametres 64 bits.
-1998/16/03
- #define DEBUG printf
- tests out of memory
- compatibilite avec la version de doran
-
-*/
-
-#undef POLY_DEBUG /* debug printf: general functions */
-#undef POLY_RR_DEBUG /* debug printf: Remove Redundants */
-#undef POLY_CH_DEBUG /* debug printf: Chernikova */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <polylib/polylib.h>
-
-#ifdef MAC_OS
- #define abs __abs
-#endif
-
-/* WSIZE is the number of bits in a word or int type */
-#define WSIZE (8*sizeof(int))
-
-#define bexchange(a, b, l)\
-{\
- char *t = (char *)malloc(l*sizeof(char));\
- memcpy((t), (char *)(a), (int)(l));\
- memcpy((char *)(a), (char *)(b), (int)(l));\
- memcpy((char *)(b), (t), (int)(l));\
- free(t); \
-}
-
-#define exchange(a, b, t)\
-{ (t)=(a); (a)=(b); (b)=(t); }
-
-/* errormsg1 is an external function which is usually supplied by the
- calling program (e.g. Domlib.c, ReadAlpha, etc...).
- See errormsg.c for an example of such a function. */
-
-void errormsg1(const char *f, const char *msgname, const char *msg);
-
-int Pol_status; /* error status after operations */
-
-/*
- * The Saturation matrix is defined to be an integer (int type) matrix.
- * It is a boolean matrix which has a row for every constraint and a column
- * for every line or ray. The bits in the binary format of each integer in
- * the stauration matrix stores the information whether the corresponding
- * constraint is saturated by ray(line) or not.
- */
-
-typedef struct {
- unsigned int NbRows;
- unsigned int NbColumns;
- int **p;
- int *p_init;
-} SatMatrix;
-
-/*
- * Allocate memory space for a saturation matrix.
- */
-static SatMatrix *SMAlloc(int rows,int cols) {
-
- int **q, *p, i;
- SatMatrix *result;
-
- result = (SatMatrix *) malloc (sizeof(SatMatrix));
- if(!result) {
- errormsg1("SMAlloc", "outofmem", "out of memory space");
- return 0;
- }
- result->NbRows = rows;
- result->NbColumns = cols;
- if(rows == 0 || cols == 0) {
- result->p = NULL;
- return result;
- }
- result->p = q = (int **)malloc(rows * sizeof(int *));
- if(!result->p) {
- errormsg1("SMAlloc", "outofmem", "out of memory space");
- return 0;
- }
- result->p_init = p = (int *)malloc (rows * cols * sizeof (int));
- if(!result->p_init) {
- errormsg1("SMAlloc", "outofmem", "out of memory space");
- return 0;
- }
- for (i=0; i<rows; i++) {
- *q++ = p;
- p += cols;
- }
- return result;
-} /* SMAlloc */
-
-/*
- * Free the memory space occupied by saturation matrix.
- */
-static void SMFree (SatMatrix **matrix) {
- SatMatrix *SM = *matrix;
-
- if (SM) {
- if (SM->p) {
- free ((char *) SM->p_init);
- free ((char *) SM->p);
- }
- free ((char *) SM);
- *matrix = NULL;
- }
-} /* SMFree */
-
-/*
- * Print the contents of a saturation matrix.
- * This function is defined only for debugging purpose.
- */
-static void SMPrint (SatMatrix *matrix) {
-
- int *p;
- int i, j;
- unsigned NbRows, NbColumns;
-
- fprintf(stderr,"%d %d\n",NbRows=matrix->NbRows, NbColumns=matrix->NbColumns);
- for (i=0;i<NbRows;i++) {
- p = *(matrix->p+i);
- for (j=0;j<NbColumns;j++)
- fprintf(stderr, " %10X ", *p++);
- fprintf(stderr, "\n");
- }
-} /* SMPrint */
-
-/*
- * Compute the bitwise OR of two saturation matrices.
- */
-static void SatVector_OR(int *p1,int *p2,int *p3,unsigned length) {
-
- int *cp1, *cp2, *cp3;
- int i;
-
- cp1=p1;
- cp2=p2;
- cp3=p3;
- for (i=0;i<length;i++) {
- *cp3 = *cp1 | *cp2;
- cp3++;
- cp1++;
- cp2++;
- }
-} /* SatVector_OR */
-
-/*
- * Copy a saturation matrix to another (macro definition).
- */
-#define SMVector_Copy(p1, p2, length) \
- memcpy((char *)(p2), (char *)(p1), (int)((length)*sizeof(int)))
-
-/*
- * Initialize a saturation matrix with zeros (macro definition)
- */
-#define SMVector_Init(p1, length) \
- memset((char *)(p1), 0, (int)((length)*sizeof(int)))
-
-/*
- * Defining operations on polyhedron --
- */
-
-/*
- * Vector p3 is a linear combination of two vectors (p1 and p2) such that
- * p3[pos] is zero. First element of each vector (p1,p2,p3) is a status
- * element and is not changed in p3. The value of 'pos' may be 0 however.
- * The parameter 'length' does not include status element one.
- */
-static void Combine(Value *p1, Value *p2, Value *p3, int pos, unsigned length) {
-
- Value a1, a2, gcd;
- Value abs_a1,abs_a2,neg_a1;
-
- /* Initialize all the 'Value' variables */
- value_init(a1); value_init(a2); value_init(gcd);
- value_init(abs_a1); value_init(abs_a2); value_init(neg_a1);
-
- /* a1 = p1[pos] */
- value_assign(a1,p1[pos]);
-
- /* a2 = p2[pos] */
- value_assign(a2,p2[pos]);
-
- /* a1_abs = |a1| */
- value_absolute(abs_a1,a1);
-
- /* a2_abs = |a2| */
- value_absolute(abs_a2,a2);
-
- /* gcd = Gcd(abs(a1), abs(a2)) */
- value_gcd(gcd, abs_a1, abs_a2);
-
- /* a1 = a1/gcd */
- value_divexact(a1, a1, gcd);
-
- /* a2 = a2/gcd */
- value_divexact(a2, a2, gcd);
-
- /* neg_a1 = -(a1) */
- value_oppose(neg_a1,a1);
-
- Vector_Combine(p1+1,p2+1,p3+1,a2,neg_a1,length);
- Vector_Normalize(p3+1,length);
-
- /* Clear all the 'Value' variables */
- value_clear(a1); value_clear(a2); value_clear(gcd);
- value_clear(abs_a1); value_clear(abs_a2); value_clear(neg_a1);
-
- return;
-} /* Combine */
-
-/*
- * Return the transpose of the saturation matrix 'Sat'. 'Mat' is a matrix
- * of constraints and 'Ray' is a matrix of ray vectors and 'Sat' is the
- * corresponding saturation matrix.
- */
-static SatMatrix *TransformSat(Matrix *Mat, Matrix *Ray, SatMatrix *Sat) {
-
- int i, j, sat_nbcolumns;
- unsigned jx1, jx2, bx1, bx2;
- SatMatrix *result;
-
- if (Mat->NbRows != 0)
- sat_nbcolumns = (Mat->NbRows-1) /(sizeof(int)*8) + 1;
- else
- sat_nbcolumns = 0;
-
- result = SMAlloc(Ray->NbRows, sat_nbcolumns);
- SMVector_Init(result->p_init, Ray->NbRows * sat_nbcolumns);
-
- for(i=0,jx1=0,bx1=MSB; i<Ray->NbRows; i++) {
- for(j=0,jx2=0,bx2=MSB; j<Mat->NbRows; j++) {
- if (Sat->p[j][jx1] & bx1)
- result->p[i][jx2] |= bx2;
- NEXT(jx2,bx2);
- }
- NEXT(jx1, bx1);
- }
- return result;
-} /* TransformSat */
-
-/*
- * Sort the rays (Ray, Sat) into three tiers as used in 'Chernikova' function:
- * NbBid <= i < equal_bound : saturates the constraint
- * equal_bound <= i < sup_bound : verifies the constraint
- * sup_bound <= i < NbRay : does not verify
- *
- * 'Ray' is the matrix of rays and 'Sat' is the corresponding saturation
- * matrix. (jx,bx) pair specify the constraint in the saturation matrix. The
- * status element of the 'Ray' matrix holds the saturation value w.r.t the
- * constraint specified by (jx,bx). Thus
- * Ray->p[i][0] = 0 -> ray(i) saturates the constraint
- * Ray->p[i][0] > 0 -> ray(i) verifies the constraint
- * Ray->p[i][0] < 0 -> ray(i) doesn't verify the constraint
- */
-static void RaySort(Matrix *Ray,SatMatrix *Sat,int NbBid,int NbRay,int *equal_bound,int *sup_bound,unsigned RowSize1, unsigned RowSize2, unsigned bx, unsigned jx) {
-
- int inf_bound;
- Value **uni_eq, **uni_sup, **uni_inf;
- int **inc_eq, **inc_sup, **inc_inf;
-
- /* 'uni_eq' points to the first ray in the ray matrix which verifies a
- * constraint, 'inc_eq' is the corresponding pointer in saturation
- * matrix. 'uni_inf' points to the first ray (from top) which doesn't
- * verify a constraint, 'inc_inf' is the corresponding pointer in
- * saturation matrix. 'uni_sup' scans the ray matrix and 'inc_sup' is
- * the corresponding pointer in saturation matrix. 'inf_bound' holds the
- * number of the first ray which does not verify the constraints.
- */
-
- *sup_bound = *equal_bound = NbBid;
- uni_sup = uni_eq = Ray->p+NbBid;
- inc_sup = inc_eq = Sat->p+NbBid;
- inf_bound = NbRay;
- uni_inf = Ray->p+NbRay;
- inc_inf = Sat->p+NbRay;
-
- while (inf_bound>*sup_bound) {
- if (value_zero_p(**uni_sup)) { /* status = satisfy */
- if (inc_eq != inc_sup) {
- Vector_Exchange(*uni_eq,*uni_sup,RowSize1);
- bexchange(*inc_eq,*inc_sup,RowSize2);
- }
- (*equal_bound)++; uni_eq++; inc_eq++;
- (*sup_bound)++; uni_sup++; inc_sup++;
- }
- else {
- *((*inc_sup)+jx)|=bx;
-
- /* if (**uni_sup<0) */
- if (value_neg_p(**uni_sup)) { /* Status != verify */
- inf_bound--; uni_inf--; inc_inf--;
- if (inc_inf != inc_sup) {
- Vector_Exchange(*uni_inf,*uni_sup,RowSize1);
- bexchange(*inc_inf,*inc_sup,RowSize2);
- }
- }
- else { /* status == verify */
- (*sup_bound)++; uni_sup++; inc_sup++;
- }
- }
- }
-} /* RaySort */
-
-static void SatMatrix_Extend(SatMatrix *Sat, Matrix* Mat, unsigned rows)
-{
- int i;
- unsigned cols;
- cols = (Mat->NbRows - 1)/(sizeof(int)*8) + 1;
-
- Sat->p = (int **)realloc(Sat->p, rows * sizeof(int *));
- if(!Sat->p) {
- errormsg1("SatMatrix_Extend", "outofmem", "out of memory space");
- return;
- }
- Sat->p_init = (int *)realloc(Sat->p_init, rows * cols * sizeof (int));
- if(!Sat->p_init) {
- errormsg1("SatMatrix_Extend", "outofmem", "out of memory space");
- return;
- }
- for (i = 0; i < rows; ++i)
- Sat->p[i] = Sat->p_init + (i * cols);
- Sat->NbRows = rows;
-}
-
-/*
- * Compute the dual of matrix 'Mat' and place it in matrix 'Ray'.'Mat'
- * contains the constraints (equalities and inequalities) in rows and 'Ray'
- * contains the ray space (lines and rays) in its rows. 'Sat' is a boolean
- * saturation matrix defined as Sat(i,j)=0 if ray(i) saturates constraint(j),
- * otherwise 1. The constraints in the 'Mat' matrix are processed starting at
- * 'FirstConstraint', 'Ray' and 'Sat' matrices are changed accordingly.'NbBid'
- * is the number of lines in the ray matrix and 'NbMaxRays' is the maximum
- * number of rows (rays) permissible in the 'Ray' and 'Sat' matrix. Return 0
- * if successful, otherwise return 1.
- */
-static int Chernikova (Matrix *Mat,Matrix *Ray,SatMatrix *Sat, unsigned NbBid, unsigned NbMaxRays, unsigned FirstConstraint,unsigned dual) {
-
- unsigned NbRay, Dimension, NbConstraints, RowSize1, RowSize2, sat_nbcolumns;
- int sup_bound, equal_bound, index_non_zero, bound;
- int i, j, k, l, redundant, rayonly, nbcommonconstraints;
- int *Temp, aux;
- int *ip1, *ip2;
- unsigned bx, m, jx;
- Value *p1, *p2, *p3;
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "[Chernikova: Input]\nRay = ");
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSat = ");
- SMPrint(Sat);
-#endif
-
- NbConstraints=Mat->NbRows;
- NbRay = Ray->NbRows;
- Dimension = Mat->NbColumns-1; /* Homogeneous Dimension */
- sat_nbcolumns=Sat->NbColumns;
-
- RowSize1=(Dimension+1);
- RowSize2=sat_nbcolumns * sizeof(int);
-
- Temp=(int *)malloc(RowSize2);
- if(!Temp) {
- errormsg1("Chernikova", "outofmem", "out of memory space");
- return 0;
- }
- CATCH(any_exception_error) {
-
- /*
- * In case of overflow, free the allocated memory!
- * Rethrow upwards the stack to forward the exception.
- */
- free(Temp);
- RETHROW();
- }
- TRY {
- jx = FirstConstraint/WSIZE;
- bx = MSB; bx >>= FirstConstraint%WSIZE;
- for (k=FirstConstraint; k<NbConstraints; k++) {
-
- /* Set the status word of each ray[i] to ray[i] dot constraint[k] */
- /* This is equivalent to evaluating each ray by the constraint[k] */
- /* 'index_non_zero' is assigned the smallest ray index which does */
- /* not saturate the constraint. */
-
- index_non_zero = NbRay;
- for (i=0; i<NbRay; i++) {
- p1 = Ray->p[i]+1;
- p2 = Mat->p[k]+1;
- p3 = Ray->p[i];
-
- /* *p3 = *p1 * *p2 */
- value_multiply(*p3,*p1,*p2);
- p1++; p2++;
- for (j=1; j<Dimension; j++) {
-
- /* *p3 += *p1 * *p2 */
- value_addmul(*p3, *p1, *p2);
- p1++; p2++;
- }
- if (value_notzero_p(*p3) && (i<index_non_zero))
- index_non_zero=i;
- }
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "[Chernikova: A]\nRay = ");
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSat = ");
- SMPrint (Sat);
-#endif
-
- /* Find a bidirectional ray z such that cz <> 0 */
- if (index_non_zero<NbBid) {
-
- /* Discard index_non_zero bidirectional ray */
- NbBid--;
- if (NbBid!=index_non_zero)
- Vector_Exchange(Ray->p[index_non_zero],Ray->p[NbBid],RowSize1);
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr,"************\n");
- for(i=0;i<RowSize1;i++) {
- value_print(stderr,P_VALUE_FMT,Ray->p[index_non_zero][i]);
- }
- fprintf(stderr,"\n******\n");
- for(i=0;i<RowSize1;i++) {
- value_print(stderr,P_VALUE_FMT,Ray->p[NbBid][i]);
- }
- fprintf(stderr,"\n*******\n");
-#endif
-
- /* Compute the new lineality space */
- for (i=0; i<NbBid; i++)
- if (value_notzero_p(Ray->p[i][0]))
- Combine(Ray->p[i],Ray->p[NbBid],Ray->p[i],0,Dimension);
-
- /* Add the positive part of index_non_zero bidirectional ray to */
- /* the set of unidirectional rays */
-
- if (value_neg_p(Ray->p[NbBid][0])) {
- p1=Ray->p[NbBid];
- for (j=0;j<Dimension+1; j++) {
-
- /* *p1 = - *p1 */
- value_oppose(*p1,*p1);
- p1++;
- }
- }
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "[Chernikova: B]\nRay = ");
- Ray->NbRows=NbRay;
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSat = ");
- SMPrint(Sat);
-#endif
-
- /* Compute the new pointed cone */
- for (i=NbBid+1; i<NbRay; i++)
- if (value_notzero_p(Ray->p[i][0]))
- Combine(Ray->p[i],Ray->p[NbBid],Ray->p[i],0,Dimension);
-
- /* Add the new ray */
- if (value_notzero_p(Mat->p[k][0])) { /* Constraint is an inequality */
- for (j=0;j<sat_nbcolumns;j++) {
- Sat->p[NbBid][j] = 0; /* Saturation vec for new ray */
- }
- /* The new ray saturates everything except last inequality */
- Sat->p[NbBid][jx] |= bx;
- }
- else { /* Constraint is an equality */
- if (--NbRay != NbBid) {
- Vector_Copy(Ray->p[NbRay],Ray->p[NbBid],Dimension+1);
- SMVector_Copy(Sat->p[NbRay],Sat->p[NbBid],sat_nbcolumns);
- }
- }
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "[Chernikova: C]\nRay = ");
- Ray->NbRows=NbRay;
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSat = ");
- SMPrint (Sat);
-#endif
-
- }
- else { /* If the new constraint satisfies all the rays */
- RaySort(Ray, Sat, NbBid, NbRay, &equal_bound, &sup_bound,
- RowSize1, RowSize2,bx,jx);
-
- /* Sort the unidirectional rays into R0, R+, R- */
- /* Ray
- NbRay-> bound-> ________
- | R- | R- ==> ray.eq < 0 (outside domain)
- sup-> |------|
- | R+ | R+ ==> ray.eq > 0 (inside domain)
- equal-> |------|
- | R0 | R0 ==> ray.eq = 0 (on face of domain)
- NbBid-> |______|
- */
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "[Chernikova: D]\nRay = ");
- Ray->NbRows=NbRay;
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSat = ");
- SMPrint (Sat);
-#endif
-
- /* Compute only the new pointed cone */
- bound=NbRay;
- for (i=equal_bound; i<sup_bound; i++) /* for all pairs of R- and R+ */
- for(j=sup_bound; j<bound; j++) {
-
- /*--------------------------------------------------------------*/
- /* Count the set of constraints saturated by R+ and R- */
- /* Includes equalities, inequalities and the positivity constraint */
- /*-----------------------------------------------------------------*/
-
- nbcommonconstraints = 0;
- for (l=0; l<jx; l++) {
- aux = Temp[l] = Sat->p[i][l] | Sat->p[j][l];
- for (m=MSB; m!=0; m>>=1)
- if (!(aux&m))
- nbcommonconstraints++;
- }
- aux = Temp[jx] = Sat->p[i][jx] | Sat->p[j][jx];
- for (m=MSB; m!=bx; m>>=1)
- if (!(aux&m))
- nbcommonconstraints++;
- rayonly = (value_zero_p(Ray->p[i][Dimension]) &&
- value_zero_p(Ray->p[j][Dimension]) &&
- (dual == 0));
- if(rayonly)
- nbcommonconstraints++; /* account for pos constr */
-
- /*-----------------------------------------------------------------*/
- /* Adjacency Test : is combination [R-,R+] a non redundant ray? */
- /*-----------------------------------------------------------------*/
-
- if (nbcommonconstraints+NbBid>=Dimension-2) { /* Dimensionality check*/
- /* Check whether a ray m saturates the same set of constraints */
- redundant=0;
- for (m=NbBid; m<bound; m++)
- if ((m!=i)&&(m!=j)) {
-
- /* Two rays (r+ r-) are never made redundant by a vertex */
- /* because the positivity constraint saturates both rays */
- /* but not the vertex */
-
- if (rayonly && value_notzero_p(Ray->p[m][Dimension]))
- continue;
-
- /* (r+ r-) is redundant if there doesn't exist an equation */
- /* which saturates both r+ and r- but not rm. */
-
- ip1 = Temp;
- ip2 = Sat->p[m];
- for (l=0; l<=jx; l++,ip2++,ip1++)
- if (*ip2 & ~*ip1)
- break;
- if (l>jx) {
- redundant=1;
- break;
- }
- }
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "[Chernikova: E]\nRay = ");
- Ray->NbRows=NbRay;
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSat = ");
- SMPrint (Sat);
-#endif
-
- /*------------------------------------------------------------*/
- /* Add new ray generated by [R+,R-] */
- /*------------------------------------------------------------*/
-
- if (!redundant) {
- if (NbRay==NbMaxRays) {
- NbMaxRays *= 2;
- Ray->NbRows = NbRay;
- Matrix_Extend(Ray, NbMaxRays);
- SatMatrix_Extend(Sat, Mat, NbMaxRays);
- }
-
- /* Compute the new ray */
- Combine(Ray->p[j],Ray->p[i],Ray->p[NbRay],0,Dimension);
- SatVector_OR(Sat->p[j],Sat->p[i],Sat->p[NbRay],sat_nbcolumns);
- Sat->p[NbRay][jx] &= ~bx;
- NbRay++;
- }
- }
- }
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr,
- "[Chernikova: F]\n"
- "sup_bound=%d\n"
- "equal_bound=%d\n"
- "bound=%d\n"
- "NbRay=%d\n"
- "Dimension = %d\n"
- "Ray = ",sup_bound,equal_bound,bound,NbRay,Dimension);
-#endif
-#ifdef POLY_CH_DEBUG
- Ray->NbRows=NbRay;
- fprintf(stderr, "[Chernikova: F]:\nRay = ");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /* Eliminates all non extremal rays */
- /* j = (Mat->p[k][0]) ? */
-
- j = (value_notzero_p(Mat->p[k][0])) ?
- sup_bound : equal_bound;
-
- i = NbRay;
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "i = %d\nj = %d \n", i, j);
-#endif
- while ((j<bound)&&(i>bound)) {
- i--;
- Vector_Copy(Ray->p[i],Ray->p[j],Dimension+1);
- SMVector_Copy(Sat->p[i],Sat->p[j],sat_nbcolumns);
- j++;
- }
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "i = %d\nj = %d \n", i, j);
- fprintf(stderr,
- "[Chernikova: F]\n"
- "sup_bound=%d\n"
- "equal_bound=%d\n"
- "bound=%d\n"
- "NbRay=%d\n"
- "Dimension = %d\n"
- "Ray = ",sup_bound,equal_bound,bound,NbRay, Dimension);
-#endif
-#ifdef POLY_CH_DEBUG
- Ray->NbRows=NbRay;
- fprintf(stderr, "[Chernikova: G]\nRay = ");
- Matrix_Print(stderr,0,Ray);
-#endif
- if (j==bound)
- NbRay=i;
- else
- NbRay=j;
- }
- NEXT(jx,bx);
- }
- Ray->NbRows=NbRay;
- Sat->NbRows=NbRay;
-
- } /* End of TRY */
-
- UNCATCH(any_exception_error);
- free(Temp);
-
-#ifdef POLY_CH_DEBUG
- fprintf(stderr, "[Chernikova: Output]\nRay = ");
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSat = ");
- SMPrint (Sat);
-#endif
-
- return 0;
-} /* Chernikova */
-
-static int Gauss4(Value **p, int NbEq, int NbRows, int Dimension)
-{
- int i, j, k, pivot, Rank;
- int *column_index = NULL;
- Value gcd;
-
- value_init(gcd);
- column_index=(int *)malloc(Dimension * sizeof(int));
- if(!column_index) {
- errormsg1("Gauss","outofmem","out of memory space");
- value_clear(gcd);
- return 0;
- }
- Rank=0;
-
- CATCH(any_exception_error) {
- if (column_index)
- free(column_index);
- value_clear(gcd);
- RETHROW();
- }
- TRY {
-
- for (j=1; j<=Dimension; j++) { /* for each column (except status) */
- for (i=Rank; i<NbEq; i++) /* starting at diagonal, look down */
-
- /* if (Mat->p[i][j] != 0) */
- if (value_notzero_p(p[i][j]))
- break; /* Find the first non zero element */
- if (i!=NbEq) { /* If a non-zero element is found? */
- if (i!=Rank) /* If it is found below the diagonal*/
- Vector_Exchange(p[Rank]+1,p[i]+1,Dimension);
-
- /* Normalize the pivot row by dividing it by the gcd */
- /* gcd = Vector_Gcd(p[Rank]+1,Dimension) */
- Vector_Gcd(p[Rank]+1,Dimension,&gcd);
-
- if (value_cmp_si(gcd, 2) >= 0)
- Vector_AntiScale(p[Rank]+1, p[Rank]+1, gcd, Dimension);
-
- if (value_neg_p(p[Rank][j]))
- Vector_Oppose(p[Rank]+1, p[Rank]+1, Dimension);
-
- pivot=i;
- for (i=pivot+1; i<NbEq; i++) { /* Zero out the rest of the column */
-
- /* if (Mat->p[i][j] != 0) */
- if (value_notzero_p(p[i][j]))
- Combine(p[i],p[Rank],p[i],j,Dimension);
- }
-
- /* For each row with non-zero entry Mat->p[Rank], store the column */
- /* number 'j' in 'column_index[Rank]'. This information will be */
- /* useful in performing Gaussian elimination backward step. */
-
- column_index[Rank]=j;
- Rank++;
- }
- } /* end of Gaussian elimination forward step */
-
- /* Back Substitution -- normalize the system of equations */
- for (k=Rank-1; k>=0; k--) {
- j = column_index[k];
-
- /* Normalize the equations */
- for (i=0; i<k; i++) {
-
- /* if (Mat->p[i][j] != 0) */
- if (value_notzero_p(p[i][j]))
- Combine(p[i],p[k],p[i],j,Dimension);
- }
-
- /* Normalize the inequalities */
- for (i=NbEq;i<NbRows;i++) {
-
- /* if (Mat->p[i][j] != 0) */
- if (value_notzero_p(p[i][j]))
- Combine(p[i],p[k],p[i],j,Dimension);
- }
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- free(column_index), column_index = NULL;
-
- value_clear(gcd);
- return Rank;
-} /* Gauss */
-
-/*
- * Compute a minimal system of equations using Gausian elimination method.
- * 'Mat' is a matrix of constraints in which the first 'Nbeq' constraints
- * are equations. The dimension of the homogenous system is 'Dimension'.
- * The function returns the rank of the matrix 'Mat'.
- */
-int Gauss(Matrix *Mat, int NbEq, int Dimension)
-{
- int Rank;
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "[Gauss : Input]\nRay =");
- Matrix_Print(stderr,0,Mat);
-#endif
-
- Rank = Gauss4(Mat->p, NbEq, Mat->NbRows, Dimension);
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "[Gauss : Output]\nRay =");
- Matrix_Print(stderr,0,Mat);
-#endif
-
- return Rank;
-}
-
-/*
- * Given 'Mat' - a matrix of equations and inequalities, 'Ray' - a matrix of
- * lines and rays, 'Sat' - the corresponding saturation matrix, and 'Filter'
- * - an array to mark (with 1) the non-redundant equalities and inequalities,
- * compute a polyhedron composed of 'Mat' as constraint matrix and 'Ray' as
- * ray matrix after reductions. This function is usually called as a follow
- * up to 'Chernikova' to remove redundant constraints or rays.
- * Note: (1) 'Chernikova' ensures that there are no redundant lines and rays.
- * (2) The same function can be used with constraint and ray matrix used
- interchangbly.
- */
-static Polyhedron *Remove_Redundants(Matrix *Mat,Matrix *Ray,SatMatrix *Sat,unsigned *Filter) {
-
- int i, j, k;
- unsigned Dimension, sat_nbcolumns, NbRay, NbConstraints, RowSize2,
- *Trace = NULL, *bx = NULL, *jx = NULL, Dim_RaySpace, b;
- unsigned NbBid, NbUni, NbEq, NbIneq;
- unsigned NbBid2, NbUni2, NbEq2, NbIneq2;
- int Redundant;
- int aux, *temp2 = NULL;
- Polyhedron *Pol = NULL;
- Vector *temp1 = NULL;
- unsigned Status;
-
- Dimension = Mat->NbColumns-1; /* Homogeneous Dimension */
- NbRay = Ray->NbRows;
- sat_nbcolumns = Sat->NbColumns;
- NbConstraints = Mat->NbRows;
- RowSize2=sat_nbcolumns * sizeof(int);
-
- temp1 = Vector_Alloc(Dimension+1);
- if (!temp1) {
- errormsg1("Remove_Redundants", "outofmem", "out of memory space");
- return 0;
- }
-
- if (Filter) {
- temp2 = (int *)calloc(sat_nbcolumns, sizeof(int));
- if (!temp2)
- goto oom;
- }
-
- /* Introduce indirections into saturation matrix 'Sat' to simplify */
- /* processing with 'Sat' and allow easy exchanges of columns. */
- bx = (unsigned *)malloc(NbConstraints * sizeof(unsigned));
- if (!bx)
- goto oom;
- jx = (unsigned *)malloc(NbConstraints * sizeof(unsigned));
- if (!jx)
- goto oom;
- CATCH(any_exception_error) {
-
- Vector_Free(temp1);
- if (temp2) free(temp2);
- if (bx) free(bx);
- if (jx) free(jx);
- if (Trace) free(Trace);
- if (Pol) Polyhedron_Free(Pol);
-
- RETHROW();
- }
- TRY {
-
- /* For each constraint 'j' following mapping is defined to facilitate */
- /* data access from saturation matrix 'Sat' :- */
- /* (1) jx[j] -> floor[j/(8*sizeof(int))] */
- /* (2) bx[j] -> bin(00..10..0) where position of 1 = j%(8*sizeof(int)) */
-
- i = 0;
- b = MSB;
- for (j=0; j<NbConstraints; j++) {
- jx[j] = i;
- bx[j] = b;
- NEXT(i,b);
- }
-
- /*
- * STEP(0): Count the number of vertices among the rays while initializing
- * the ray status count to 0. If no vertices are found, quit the procedure
- * and return an empty polyhedron as the result.
- */
-
- /* Reset the status element of each ray to zero. Store the number of */
- /* vertices in 'aux'. */
- aux = 0;
- for (i=0; i<NbRay; i++) {
-
- /* Ray->p[i][0] = 0 */
- value_set_si(Ray->p[i][0],0);
-
- /* If ray(i) is a vertex of the Inhomogenous system */
- if (value_notzero_p(Ray->p[i][Dimension]))
- aux++;
- }
-
- /* If no vertices, return an empty polyhedron. */
- if (!aux)
- goto empty;
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Init]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRays =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(1): Compute status counts for both rays and inequalities. For each
- * constraint, count the number of vertices/rays saturated by that
- * constraint, and put the result in the status words. At the same time,
- * for each vertex/ray, count the number of constraints saturated by it.
- * Delete any positivity constraints, but give rays credit in their status
- * counts for saturating the positivity constraint.
- */
-
- NbEq=0;
-
-#ifdef POLY_RR_DEBUG
- fprintf (stderr, " j = ");
-#endif
-
- for (j=0; j<NbConstraints; j++) {
-
-#ifdef POLY_RR_DEBUG
- fprintf (stderr, " %i ", j);
- fflush (stderr);
-#endif
-
- /* If constraint(j) is an equality, mark '1' in array 'temp2' */
- if (Filter && value_zero_p(Mat->p[j][0]))
- temp2[jx[j]] |= bx[j];
- /* Reset the status element of each constraint to zero */
- value_set_si(Mat->p[j][0],0);
-
- /* Identify and remove the positivity constraint 1>=0 */
- i = First_Non_Zero(Mat->p[j]+1, Dimension-1);
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : IntoStep1]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf (stderr, " j = %i \n", j);
-#endif
-
- /* Check if constraint(j) is a positivity constraint, 1 >= 0, or if it */
- /* is 1==0. If constraint(j) saturates all the rays of the matrix 'Ray'*/
- /* then it is an equality. in this case, return an empty polyhedron. */
-
- if (i == -1) {
- for (i=0; i<NbRay; i++)
- if (!(Sat->p[i][jx[j]]&bx[j])) {
-
- /* Mat->p[j][0]++ */
- value_increment(Mat->p[j][0],Mat->p[j][0]);
- }
-
- /* if ((Mat->p[j][0] == NbRay) && : it is an equality
- (Mat->p[j][Dimension] != 0)) : and its not 0=0 */
- if ((value_cmp_si(Mat->p[j][0], NbRay) == 0) &&
- (value_notzero_p(Mat->p[j][Dimension])))
- goto empty;
-
- /* Delete the positivity constraint */
- NbConstraints--;
- if (j==NbConstraints) continue;
- Vector_Exchange(Mat->p[j], Mat->p[NbConstraints], temp1->Size);
- exchange(jx[j], jx[NbConstraints], aux);
- exchange(bx[j], bx[NbConstraints], aux);
- j--; continue;
- }
-
- /* Count the number of vertices/rays saturated by each constraint. At */
- /* the same time, count the number of constraints saturated by each ray*/
- for (i=0; i<NbRay; i++)
- if (!(Sat->p[i][jx[j]]&bx[j])) {
-
- /* Mat->p[j][0]++ */
- value_increment(Mat->p[j][0],Mat->p[j][0]);
-
- /* Ray->p[i][0]++ */
- value_increment (Ray->p[i][0],Ray->p[i][0]);
- }
-
- /* if (Mat->p[j][0]==NbRay) then increment the number of eq. count */
- if (value_cmp_si(Mat->p[j][0], NbRay) == 0)
- NbEq++; /* all vertices/rays are saturated */
- }
- Mat->NbRows = NbConstraints;
-
- NbBid=0;
- for (i=0; i<NbRay; i++) {
-
- /* Give rays credit for saturating the positivity constraint */
- if (value_zero_p(Ray->p[i][Dimension]))
-
- /* Ray->p[i][0]++ */
- value_increment(Ray->p[i][0],Ray->p[i][0]);
-
- /* If ray(i) saturates all the constraints including positivity */
- /* constraint then it is a bi-directional ray or line. Increment */
- /* 'NbBid' by one. */
-
- /* if (Ray->p[i][0]==NbConstraints+1) */
- if (value_cmp_si(Ray->p[i][0], NbConstraints+1) == 0)
- NbBid++;
- }
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step1]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(2): Sort equalities to the top of constraint matrix 'Mat'. Detect
- * implicit equations such as y>=3; y<=3. Keep Inequalities in same
- * relative order. (Note: Equalities are constraints which saturate all of
- * the rays)
- */
-
- for (i=0; i<NbEq; i++) {
-
- /* If constraint(i) doesn't saturate some ray, then it is an inequality*/
- if (value_cmp_si(Mat->p[i][0], NbRay) != 0) {
-
- /* Skip over inequalities and find an equality */
- for (k=i+1; value_cmp_si(Mat->p[k][0], NbRay) != 0 && k < NbConstraints; k++)
- ;
- if (k==NbConstraints) /* If none found then error */ break;
-
- /* Slide inequalities down the array 'Mat' and move equality up to */
- /* position 'i'. */
- Vector_Copy(Mat->p[k], temp1->p, temp1->Size);
- aux = jx[k];
- j = bx[k];
- for (;k>i;k--) {
- Vector_Copy(Mat->p[k-1], Mat->p[k], temp1->Size);
- jx[k] = jx[k-1];
- bx[k] = bx[k-1];
- }
- Vector_Copy(temp1->p, Mat->p[i], temp1->Size);
- jx[i] = aux;
- bx[i] = j;
- }
- }
-
- /* for SIMPLIFY */
- if (Filter) {
- Value mone;
- value_init(mone);
- value_set_si(mone, -1);
- /* Normalize equalities to have lexpositive coefficients to
- * be able to detect identical equalities.
- */
- for (i = 0; i < NbEq; i++) {
- int pos = First_Non_Zero(Mat->p[i]+1, Dimension);
- if (pos == -1)
- continue;
- if (value_neg_p(Mat->p[i][1+pos]))
- Vector_Scale(Mat->p[i]+1, Mat->p[i]+1, mone, Dimension);
- }
- value_clear(mone);
- for (i=0; i<NbEq; i++) {
-
- /* Detect implicit constraints such as y>=3 and y<=3 */
- Redundant = 0;
- for (j=i+1; j<NbEq; j++) {
- /* Only check equalities, i.e., 'temp2' has entry 1 */
- if (!(temp2[jx[j]] & bx[j]))
- continue;
- /* Redundant if both are same `and' constraint(j) was equality. */
- if (Vector_Equal(Mat->p[i]+1, Mat->p[j]+1, Dimension)) {
- Redundant=1;
- break;
- }
- }
-
- /* Set 'Filter' entry to 1 corresponding to the irredundant equality*/
- if (!Redundant) Filter[jx[i]] |= bx[i]; /* set flag */
- }
- }
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step2]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(3): Perform Gaussian elimiation on the list of equalities. Obtain
- * a minimal basis by solving for as many variables as possible. Use this
- * solution to reduce the inequalities by eliminating as many variables as
- * possible. Set NbEq2 to the rank of the system of equalities.
- */
-
- NbEq2 = Gauss(Mat,NbEq,Dimension);
-
- /* If number of equalities is not less then the homogenous dimension, */
- /* return an empty polyhedron. */
-
- if (NbEq2 >= Dimension)
- goto empty;
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step3]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(4): Sort lines to the top of ray matrix 'Ray', leaving rays
- * afterwards. Detect implicit lines such as ray(1,2) and ray(-1,-2).
- * (Note: Lines are rays which saturate all of the constraints including
- * the positivity constraint 1>=0.
- */
-
-
- for (i=0, k=NbRay; i<NbBid && k>i; i++) {
- /* If ray(i) doesn't saturate some constraint then it is not a line */
- if (value_cmp_si(Ray->p[i][0], NbConstraints+1) != 0) {
-
- /* Skip over rays and vertices and find a line (bi-directional rays) */
- while (--k > i && value_cmp_si(Ray->p[k][0], NbConstraints+1) != 0)
- ;
-
- /* Exchange positions of ray(i) and line(k), thus sorting lines to */
- /* the top of matrix 'Ray'. */
- Vector_Exchange(Ray->p[i], Ray->p[k], temp1->Size);
- bexchange(Sat->p[i], Sat->p[k], RowSize2);
- }
- }
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step4]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(5): Perform Gaussian elimination on the lineality space to obtain
- * a minimal basis of lines. Use this basis to reduce the representation
- * of the uniderectional rays. Set 'NbBid2' to the rank of the system of
- * lines.
- */
-
- NbBid2 = Gauss(Ray, NbBid, Dimension);
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : After Gauss]\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /* If number of lines is not less then the homogenous dimension, return */
- /* an empty polyhedron. */
- if (NbBid2>=Dimension) {
- errormsg1("RemoveRedundants", "rmrdt", "dimension error");
- goto empty;
- }
-
- /* Compute dimension of non-homogenous ray space */
- Dim_RaySpace = Dimension-1-NbEq2-NbBid2;
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step5]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(6): Do a first pass filter of inequalities and equality identifi-
- * cation. New positivity constraints may have been created by step(3).
- * Check for and eliminate them. Count the irredundant inequalities and
- * store count in 'NbIneq'.
- */
-
- NbIneq=0;
- for (j=0; j<NbConstraints; j++) {
-
- /* Identify and remove the positivity constraint 1>=0 */
- i = First_Non_Zero(Mat->p[j]+1, Dimension-1);
-
- /* Check if constraint(j) is a positivity constraint, 1>= 0, or if it */
- /* is 1==0. */
- if (i == -1) {
- /* if ((Mat->p[j][0]==NbRay) && : it is an equality
- (Mat->p[j][Dimension]!=0)) : and its not 0=0 */
- if ((value_cmp_si(Mat->p[j][0], NbRay) == 0) &&
- (value_notzero_p(Mat->p[j][Dimension])))
- goto empty;
-
- /* Set the positivity constraint redundant by setting status element */
- /* equal to 2. */
- value_set_si(Mat->p[j][0],2);
- continue;
- }
-
- Status = VALUE_TO_INT(Mat->p[j][0]);
-
- if (Status == 0)
- value_set_si(Mat->p[j][0], 2); /* constraint is redundant */
- else if (Status < Dim_RaySpace)
- value_set_si(Mat->p[j][0], 2); /* constraint is redundant */
- else if (Status == NbRay)
- value_set_si(Mat->p[j][0], 0); /* constraint is an equality */
- else {
- NbIneq++; /* constraint is an irredundant inequality */
- value_set_si(Mat->p[j][0], 1); /* inequality */
- }
- }
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step6]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(7): Do a first pass filter of rays and identification of lines.
- * Count the irredundant Rays and store count in 'NbUni'.
- */
-
- NbUni=0;
- for (j=0; j<NbRay; j++) {
- Status = VALUE_TO_INT(Ray->p[j][0]);
-
- if (Status < Dim_RaySpace)
- value_set_si(Ray->p[j][0], 2); /* ray is redundant */
- else if (Status == NbConstraints+1)
- value_set_si(Ray->p[j][0], 0); /* ray is a line */
- else {
- NbUni++; /* an irredundant unidirectional ray. */
- value_set_si(Ray->p[j][0], 1); /* ray */
- }
- }
-
- /*
- * STEP(8): Create the polyhedron (using approximate sizes).
- * Number of constraints = NbIneq + NbEq2 + 1
- * Number of rays = NbUni + NbBid2
- * Partially fill the polyhedron structure with the lines computed in step
- * 3 and the equalities computed in step 5.
- */
-
- Pol = Polyhedron_Alloc(Dimension-1, NbIneq+NbEq2+1, NbUni+NbBid2);
- if (!Pol) {
- UNCATCH(any_exception_error);
- goto oom;
- }
- Pol->NbBid = NbBid2;
- Pol->NbEq = NbEq2;
-
- /* Partially fill the polyhedron structure */
- if (NbBid2) Vector_Copy(Ray->p[0], Pol->Ray[0], (Dimension+1)*NbBid2);
- if (NbEq2) Vector_Copy(Mat->p[0], Pol->Constraint[0], (Dimension+1)*NbEq2);
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step7]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * STEP(9): Final Pass filter of inequalities and detection of redundant
- * inequalities. Redundant inequalities include:
- * (1) Inequalities which are always true, such as 1>=0,
- * (2) Redundant inequalities such as y>=4 given y>=3, or x>=1 given x=2.
- * (3) Redundant inequalities such as x+y>=5 given x>=3 and y>=2.
- * Every 'good' inequality must saturate at least 'Dimension' rays and be
- * unique.
- */
-
- /* 'Trace' is a (1 X sat_nbcolumns) row matrix to hold the union of all */
- /* rows (corresponding to irredundant rays) of saturation matrix 'Sat' */
- /* which saturate some constraint 'j'. See figure below:- */
- Trace=(unsigned *)malloc(sat_nbcolumns * sizeof(unsigned));
- if(!Trace) {
- UNCATCH(any_exception_error);
- goto oom;
- }
-
- /* NbEq NbConstraints
- |----------->
- ___________j____
- | | |
- | Mat | |
- |___________|___|
- |
- NbRay ^ ________ ____________|____
- | |-------|--------|-----------0---|t1
- |i|-------|--------|-----------0---|t2
- | | Ray | | Sat |
- NbBid - |-------|--------|-----------0---|tk
- |_______| |_______________|
- |
- |
- -OR- (of rows t1,t2,...,tk)
- ________|___|____
- |_____Trace_0___|
-
- */
-
- NbIneq2 = 0;
- for (j=NbEq; j<NbConstraints; j++) {
-
- /* if (Mat->p[j][0]==1) : non-redundant inequality */
- if (value_one_p (Mat->p[j][0])) {
- for (k=0; k<sat_nbcolumns; k++) Trace[k]=0; /* init Trace */
-
- /* Compute Trace: the union of all rows of Sat where constraint(j) */
- /* is saturated. */
- for (i=NbBid; i<NbRay; i++)
-
- /* if (Ray->p[i][0]==1) */
- if (value_one_p(Ray->p[i][0])) {
- if (!(Sat->p[i][jx[j]]&bx[j]))
- for (k=0; k<sat_nbcolumns; k++) Trace[k] |= Sat->p[i][k];
- }
-
- /* Only constraint(j) should saturate this set of vertices/rays. */
- /* If another non-redundant constraint also saturates this set, */
- /* then constraint(j) is redundant */
- Redundant=0;
- for (i=NbEq; i<NbConstraints; i++) {
-
- /* if ((Mat->p[i][0] ==1) && (i!=j) && !(Trace[jx[i]] & bx[i]) ) */
- if (value_one_p(Mat->p[i][0]) && (i!=j) && !(Trace[jx[i]] & bx[i])) {
- Redundant=1;
- break;
- }
- }
- if (Redundant) {
- value_set_si(Mat->p[j][0],2);
- }
- else {
- Vector_Copy(Mat->p[j], Pol->Constraint[NbEq2+NbIneq2], Dimension+1);
- if (Filter) Filter[jx[j]] |= bx[j]; /* for SIMPLIFY */
- NbIneq2++;
- }
- }
- }
- free(Trace), Trace = NULL;
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step8]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- /*
- * Step(10): Final pass filter of rays and detection of redundant rays.
- * The final list of rays is written to polyhedron.
- */
-
- /* Trace is a (NbRay x 1) column matrix to hold the union of all columns */
- /* (corresponding to irredundant inequalities) of saturation matrix 'Sat'*/
- /* which saturate some ray 'i'. See figure below:- */
-
- Trace=(unsigned *)malloc(NbRay * sizeof(unsigned));
- if(!Trace) {
- UNCATCH(any_exception_error);
- goto oom;
- }
-
- /* NbEq NbConstraints
- |---------->
- ___________j_____
- | | | | |
- | Mat | |
- |______|_|___|__|
- | | |
-NbRay ^ _________ _______|_|___|__ ___
- | | | | | | | | |T|
- | | Ray | | Sat| | | | |r|
- | | | | | | | | |a| Trace = Union[col(t1,t2,..,tk)]
- |i|-------|------>i 0 0 0 | |c|
-NbBid - | | | | | | | |e|
- |_______| |______|_|___|__| |_|
- t1 t2 tk
- */
-
- NbUni2 = 0;
-
- /* Let 'aux' be the number of rays not vertices */
- aux = 0;
- for (i=NbBid; i<NbRay; i++) {
-
- /* if (Ray->p[i][0]==1) */
- if (value_one_p (Ray->p[i][0])) {
-
- /* if (Ray->p[i][Dimension]!=0) : vertex */
- if (value_notzero_p (Ray->p[i][Dimension]))
- for (k=NbBid; k<NbRay; k++) Trace[k]=0; /* init Trace */
- else /* for ray */
-
- /* Include the positivity constraint incidences for rays. The */
- /* positivity constraint saturates all rays and no vertices */
-
- for (k=NbBid; k<NbRay; k++)
-
- /* Trace[k]=(Ray->p[k][Dimension]!=0); */
- Trace[k] = (value_notzero_p (Ray->p[k][Dimension]));
-
- /* Compute Trace: the union of all columns of Sat where ray(i) is */
- /* saturated. */
- for (j=NbEq; j<NbConstraints; j++)
-
- /* if (Mat->p[j][0]==1) : inequality */
- if (value_one_p (Mat->p[j][0])) {
- if (!(Sat->p[i][jx[j]]&bx[j]))
- for (k=NbBid; k<NbRay; k++) Trace[k] |= Sat->p[k][jx[j]]&bx[j];
- }
-
- /* If ray i does not saturate any inequalities (other than the */
- /* the positivity constraint, then it is the case that there is */
- /* only one inequality and that ray is its orthogonal */
-
- /* only ray(i) should saturate this set of inequalities. If */
- /* another non-redundant ray also saturates this set, then ray(i)*/
- /* is redundant */
-
- Redundant = 0;
- for (j=NbBid; j<NbRay; j++) {
-
- /* if ( (Ray->p[j][0]==1) && (i!=j) && !Trace[j] ) */
- if (value_one_p (Ray->p[j][0]) && (i!=j) && !Trace[j]) {
- Redundant=1;
- break;
- }
- }
- if (Redundant)
- value_set_si(Ray->p[i][0],2);
- else {
- Vector_Copy(Ray->p[i], Pol->Ray[NbBid2+NbUni2], Dimension+1);
- NbUni2++; /* Increment number of uni-directional rays */
-
- /* if (Ray->p[i][Dimension]==0) */
- if (value_zero_p (Ray->p[i][Dimension]))
- aux++; /* Increment number of rays which are not vertices */
- }
- }
- }
-
- /* Include the positivity constraint */
- if (aux>=Dim_RaySpace) {
- Vector_Set(Pol->Constraint[NbEq2+NbIneq2],0,Dimension+1);
- value_set_si(Pol->Constraint[NbEq2+NbIneq2][0],1);
- value_set_si(Pol->Constraint[NbEq2+NbIneq2][Dimension],1);
- NbIneq2++;
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
-
-#ifdef POLY_RR_DEBUG
- fprintf(stderr, "[Remove_redundants : Step9]\nConstraints =");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nRay =");
- Matrix_Print(stderr,0,Ray);
-#endif
-
- free(Trace);
- free(bx);
- free(jx);
- if (temp2)
- free(temp2);
-
- Pol->NbConstraints = NbEq2 + NbIneq2;
- Pol->NbRays = NbBid2 + NbUni2;
-
- Vector_Free(temp1);
- F_SET(Pol,
- POL_VALID | POL_INEQUALITIES | POL_FACETS | POL_POINTS | POL_VERTICES);
- return Pol;
-
-oom:
- errormsg1("Remove_Redundants", "outofmem", "out of memory space");
-
- Vector_Free(temp1);
- if (temp2)
- free(temp2);
- if (bx)
- free(bx);
- if (jx)
- free(jx);
- return NULL;
-
-empty:
- Vector_Free(temp1);
- if (temp2)
- free(temp2);
- if (bx)
- free(bx);
- if (jx)
- free(jx);
- UNCATCH(any_exception_error);
- return Empty_Polyhedron(Dimension-1);
-} /* Remove_Redundants */
-
-/*
- * Allocate memory space for polyhedron.
- */
-Polyhedron* Polyhedron_Alloc(unsigned Dimension,unsigned NbConstraints,unsigned NbRays) {
-
- Polyhedron *Pol;
- unsigned NbRows,NbColumns;
- int i,j;
- Value *p, **q;
-
- Pol=(Polyhedron *)malloc(sizeof(Polyhedron));
- if(!Pol) {
- errormsg1("Polyhedron_Alloc", "outofmem", "out of memory space");
- return 0;
- }
-
- Pol->next = (Polyhedron *)0;
- Pol->Dimension = Dimension;
- Pol->NbConstraints = NbConstraints;
- Pol->NbRays = NbRays;
- Pol->NbEq = 0;
- Pol->NbBid = 0;
- Pol->flags = 0;
- NbRows = NbConstraints + NbRays;
- NbColumns = Dimension + 2;
-
- q = (Value **)malloc(NbRows * sizeof(Value *));
- if(!q) {
- errormsg1("Polyhedron_Alloc", "outofmem", "out of memory space");
- return 0;
- }
- p = value_alloc(NbRows*NbColumns, &Pol->p_Init_size);
- if(!p) {
- free(q);
- errormsg1("Polyhedron_Alloc", "outofmem", "out of memory space");
- return 0;
- }
- Pol->Constraint = q;
- Pol->Ray = q + NbConstraints;
- Pol->p_Init = p;
- for (i=0;i<NbRows;i++) {
- *q++ = p;
- p += NbColumns;
- }
- return Pol;
-} /* Polyhedron_Alloc */
-
-/*
- * Free the memory space occupied by the single polyhedron.
- */
-void Polyhedron_Free(Polyhedron *Pol)
-{
- if(!Pol)
- return;
- value_free(Pol->p_Init, Pol->p_Init_size);
- free(Pol->Constraint);
- free(Pol);
- return;
-} /* Polyhedron_Free */
-
-/*
- * Free the memory space occupied by the domain.
- */
-void Domain_Free(Polyhedron *Pol)
-{
- Polyhedron *Next;
-
- for (; Pol; Pol = Next) {
- Next = Pol->next;
- Polyhedron_Free(Pol);
- }
- return;
-} /* Domain_Free */
-
-/*
- * Print the contents of a polyhedron.
- */
-void Polyhedron_Print(FILE *Dst, const char *Format, const Polyhedron *Pol)
-{
- unsigned Dimension, NbConstraints, NbRays;
- int i, j;
- Value *p;
-
- if (!Pol) {
- fprintf(Dst, "<null polyhedron>\n");
- return;
- }
-
- Dimension = Pol->Dimension + 2; /* Homogenous Dimension + status */
- NbConstraints = Pol->NbConstraints;
- NbRays = Pol->NbRays;
- fprintf(Dst, "POLYHEDRON Dimension:%d\n", Pol->Dimension);
- fprintf(Dst," Constraints:%d Equations:%d Rays:%d Lines:%d\n",
- Pol->NbConstraints, Pol->NbEq, Pol->NbRays, Pol->NbBid);
- fprintf(Dst,"Constraints %d %d\n", NbConstraints, Dimension);
-
- for (i=0;i<NbConstraints;i++) {
- p=Pol->Constraint[i];
-
- /* if (*p) */
- if (value_notzero_p (*p))
- fprintf(Dst,"Inequality: [");
- else
- fprintf(Dst,"Equality: [");
- p++;
- for (j=1;j<Dimension;j++) {
- value_print(Dst,Format,*p++);
- }
- (void)fprintf(Dst," ]\n");
- }
-
- (void)fprintf(Dst, "Rays %d %d\n", NbRays, Dimension);
- for (i=0;i<NbRays;i++) {
- p=Pol->Ray[i];
-
- /* if (*p) */
- if (value_notzero_p (*p)) {
- p++;
-
- /* if ( p[Dimension-2] ) */
- if (value_notzero_p (p[Dimension-2]))
- fprintf(Dst, "Vertex: [");
- else
- fprintf(Dst, "Ray: [");
- }
- else {
- p++;
- fprintf(Dst, "Line: [");
- }
- for (j=1; j < Dimension-1; j++) {
- value_print(Dst,Format,*p++);
- }
-
- /* if (*p) */
- if (value_notzero_p (*p)) {
- fprintf( Dst, " ]/" );
- value_print(Dst,VALUE_FMT,*p);
- fprintf( Dst, "\n" );
- }
- else
- fprintf(Dst, " ]\n");
- }
- if (Pol->next) {
- fprintf(Dst, "UNION ");
- Polyhedron_Print(Dst,Format,Pol->next);
- }
-} /* Polyhedron_Print */
-
-/*
- * Print the contents of a polyhedron 'Pol' (used for debugging purpose).
- */
-void PolyPrint (Polyhedron *Pol) {
- Polyhedron_Print(stderr,"%4d",Pol);
-} /* PolyPrint */
-
-/*
- * Create and return an empty polyhedron of non-homogenous dimension
- * 'Dimension'. An empty polyhedron is characterized by :-
- * (a) The dimension of the ray-space is -1.
- * (b) There is an over-constrained system of equations given by:
- * x=0, y=0, ...... z=0, 1=0
- */
-Polyhedron *Empty_Polyhedron(unsigned Dimension) {
-
- Polyhedron *Pol;
- int i;
-
- Pol = Polyhedron_Alloc(Dimension, Dimension+1, 0);
- if (!Pol) {
- errormsg1("Empty_Polyhedron", "outofmem", "out of memory space");
- return 0;
- }
- Vector_Set(Pol->Constraint[0],0,(Dimension+1)*(Dimension+2));
- for (i=0; i<=Dimension; i++) {
-
- /* Pol->Constraint[i][i+1]=1 */
- value_set_si(Pol->Constraint[i][i+1],1);
- }
- Pol->NbEq = Dimension+1;
- Pol->NbBid = 0;
- F_SET(Pol,
- POL_VALID | POL_INEQUALITIES | POL_FACETS | POL_POINTS | POL_VERTICES);
- return Pol;
-} /* Empty_Polyhedron */
-
-/*
- * Create and return a universe polyhedron of non-homogenous dimension
- * 'Dimension'. A universe polyhedron is characterized by :-
- * (a) The dimension of rayspace is zero.
- * (b) The dimension of lineality space is the dimension of the polyhedron.
- * (c) There is only one constraint (positivity constraint) in the constraint
- * set given by : 1 >= 0.
- * (d) The bi-directional ray set is the canonical set of vectors.
- * (e) The only vertex is the origin (0,0,0,....0).
- */
-Polyhedron *Universe_Polyhedron(unsigned Dimension) {
-
- Polyhedron *Pol;
- int i;
-
- Pol = Polyhedron_Alloc(Dimension,1,Dimension+1);
- if (!Pol) {
- errormsg1("Universe_Polyhedron", "outofmem", "out of memory space");
- return 0;
- }
- Vector_Set(Pol->Constraint[0],0,(Dimension+2));
-
- /* Pol->Constraint[0][0] = 1 */
- value_set_si(Pol->Constraint[0][0],1);
-
- /* Pol->Constraint[0][Dimension+1] = 1 */
- value_set_si(Pol->Constraint[0][Dimension+1],1);
- Vector_Set(Pol->Ray[0],0,(Dimension+1)*(Dimension+2));
- for (i=0;i<=Dimension;i++) {
-
- /* Pol->Ray[i][i+1]=1 */
- value_set_si(Pol->Ray[i][i+1],1);
- }
-
- /* Pol->Ray[Dimension][0] = 1 : vertex status */
- value_set_si(Pol->Ray[Dimension][0],1);
- Pol->NbEq = 0;
- Pol->NbBid = Dimension;
- F_SET(Pol,
- POL_VALID | POL_INEQUALITIES | POL_FACETS | POL_POINTS | POL_VERTICES);
- return Pol;
-} /* Universe_Polyhedron */
-
-/*
-
-Sort constraints and remove trivially redundant constraints.
-
-*/
-static void SortConstraints(Matrix *Constraints, unsigned NbEq)
-{
- int i, j, k;
- for (i = NbEq; i < Constraints->NbRows; ++i) {
- int max = i;
- for (k = i+1; k < Constraints->NbRows; ++k) {
- for (j = 1; j < Constraints->NbColumns-1; ++j) {
- if (value_eq(Constraints->p[k][j],
- Constraints->p[max][j]))
- continue;
- if (value_abs_lt(Constraints->p[k][j],
- Constraints->p[max][j]))
- break;
- if (value_abs_eq(Constraints->p[k][j],
- Constraints->p[max][j]) &&
- value_pos_p(Constraints->p[max][j]))
- break;
- max = k;
- break;
- }
- /* equal, except for possibly the constant
- * => remove constraint with biggest constant
- */
- if (j == Constraints->NbColumns-1) {
- if (value_lt(Constraints->p[k][j], Constraints->p[max][j]))
- Vector_Exchange(Constraints->p[k],
- Constraints->p[max],
- Constraints->NbColumns);
- Constraints->NbRows--;
- if (k < Constraints->NbRows)
- Vector_Exchange(Constraints->p[k],
- Constraints->p[Constraints->NbRows],
- Constraints->NbColumns);
- k--;
- }
- }
- if (max != i)
- Vector_Exchange(Constraints->p[max], Constraints->p[i],
- Constraints->NbColumns);
- }
-}
-
-/*
-
-Search for trivial implicit equalities,
-assuming the constraints have been sorted.
-
-*/
-
-static int ImplicitEqualities(Matrix *Constraints, unsigned NbEq)
-{
- int row, nrow, k;
- int found = 0;
- Value tmp;
- for (row = NbEq; row < Constraints->NbRows; ++row) {
- int d = First_Non_Zero(Constraints->p[row]+1, Constraints->NbColumns-2);
- if (d == -1) {
- /* -n >= 0 */
- if (value_neg_p(Constraints->p[row][Constraints->NbColumns-1])) {
- value_set_si(Constraints->p[row][0], 0);
- found = 1;
- }
- break;
- }
- if (value_neg_p(Constraints->p[row][1+d]))
- continue;
- for (nrow = row+1; nrow < Constraints->NbRows; ++nrow) {
- if (value_zero_p(Constraints->p[nrow][1+d]))
- break;
- if (value_pos_p(Constraints->p[nrow][1+d]))
- continue;
- for (k = d; k < Constraints->NbColumns-1; ++k) {
- if (value_abs_ne(Constraints->p[row][1+k],
- Constraints->p[nrow][1+k]))
- break;
- if (value_zero_p(Constraints->p[row][1+k]))
- continue;
- if (value_eq(Constraints->p[row][1+k], Constraints->p[nrow][1+k]))
- break;
- }
- if (k == Constraints->NbColumns-1) {
- value_set_si(Constraints->p[row][0], 0);
- value_set_si(Constraints->p[nrow][0], 0);
- found = 1;
- break;
- }
- if (k != Constraints->NbColumns-2)
- continue;
- /* if the constants are such that
- * the sum c1+c2 is negative then the constraints conflict
- */
- value_init(tmp);
- value_addto(tmp, Constraints->p[row][1+k],
- Constraints->p[nrow][1+k]);
- if (value_sign(tmp) < 0) {
- Vector_Set(Constraints->p[row], 0, Constraints->NbColumns-1);
- Vector_Set(Constraints->p[nrow], 0, Constraints->NbColumns-1);
- value_set_si(Constraints->p[row][1+k], 1);
- value_set_si(Constraints->p[nrow][1+k], 1);
- found = 1;
- }
- value_clear(tmp);
- if (found)
- break;
- }
- }
- return found;
-}
-
-/**
-
-Given a matrix of constraints ('Constraints'), construct and return a
-polyhedron.
-
- at param Constraints Constraints (may be modified!)
- at param NbMaxRays Estimated number of rays in the ray matrix of the
-polyhedron.
- at return newly allocated Polyhedron
-
-*/
-Polyhedron *Constraints2Polyhedron(Matrix *Constraints,unsigned NbMaxRays) {
-
- Polyhedron *Pol = NULL;
- Matrix *Ray = NULL;
- SatMatrix *Sat = NULL;
- unsigned Dimension, nbcolumns;
- int i;
-
- Dimension = Constraints->NbColumns - 1; /* Homogeneous Dimension */
- if (Dimension < 1) {
- errormsg1("Constraints2Polyhedron","invalidpoly","invalid polyhedron dimension");
- return 0;
- }
-
- /* If there is no constraint in the constraint matrix, return universe */
- /* polyhderon. */
- if (Constraints->NbRows==0) {
- Pol = Universe_Polyhedron(Dimension-1);
- return Pol;
- }
-
- if (POL_ISSET(NbMaxRays, POL_NO_DUAL)) {
- unsigned NbEq;
- unsigned Rank;
- Value tmp;
- if (POL_ISSET(NbMaxRays, POL_INTEGER))
- value_init(tmp);
- do {
- NbEq = 0;
- /* Move equalities up */
- for (i = 0; i < Constraints->NbRows; ++i)
- if (value_zero_p(Constraints->p[i][0])) {
- if (POL_ISSET(NbMaxRays, POL_INTEGER) &&
- ConstraintSimplify(Constraints->p[i],
- Constraints->p[i], Dimension+1, &tmp)) {
- value_clear(tmp);
- return Empty_Polyhedron(Dimension-1);
- }
- /* detect 1 == 0, possibly created by ImplicitEqualities */
- if (First_Non_Zero(Constraints->p[i]+1, Dimension-1) == -1 &&
- value_notzero_p(Constraints->p[i][Dimension])) {
- if (POL_ISSET(NbMaxRays, POL_INTEGER))
- value_clear(tmp);
- return Empty_Polyhedron(Dimension-1);
- }
- if (i != NbEq)
- ExchangeRows(Constraints, i, NbEq);
- ++NbEq;
- }
- Rank = Gauss(Constraints, NbEq, Dimension);
- if (POL_ISSET(NbMaxRays, POL_INTEGER))
- for (i = NbEq; i < Constraints->NbRows; ++i)
- ConstraintSimplify(Constraints->p[i],
- Constraints->p[i], Dimension+1, &tmp);
- SortConstraints(Constraints, NbEq);
- } while (ImplicitEqualities(Constraints, NbEq));
- if (POL_ISSET(NbMaxRays, POL_INTEGER))
- value_clear(tmp);
- Pol = Polyhedron_Alloc(Dimension-1, Constraints->NbRows - (NbEq-Rank), 0);
- if (Rank > 0)
- Vector_Copy(Constraints->p[0], Pol->Constraint[0],
- Rank * Constraints->NbColumns);
- if (Constraints->NbRows > NbEq)
- Vector_Copy(Constraints->p[NbEq], Pol->Constraint[Rank],
- (Constraints->NbRows - NbEq) * Constraints->NbColumns);
- Pol->NbEq = Rank;
- /* Make sure nobody accesses the rays by accident */
- Pol->Ray = 0;
- F_SET(Pol, POL_VALID | POL_INEQUALITIES);
- return Pol;
- }
-
- if (Dimension > NbMaxRays)
- NbMaxRays = Dimension;
-
- /*
- * Rather than adding a 'positivity constraint', it is better to
- * initialize the lineality space with line in each of the index
- * dimensions, but no line in the lambda dimension. Then initialize
- * the ray space with an origin at 0. This is what you get anyway,
- * after the positivity constraint has been processed by Chernikova
- * function.
- */
-
- /* Allocate and initialize the Ray Space */
- Ray = Matrix_Alloc(NbMaxRays, Dimension+1);
- if(!Ray) {
- errormsg1("Constraints2Polyhedron","outofmem","out of memory space");
- return 0;
- }
- Vector_Set(Ray->p_Init,0, NbMaxRays * (Dimension+1));
- for (i=0; i<Dimension; i++) {
-
- /* Ray->p[i][i+1] = 1 */
- value_set_si(Ray->p[i][i+1],1);
- }
-
- /* Ray->p[Dimension-1][0] = 1 : mark for ray */
- value_set_si(Ray->p[Dimension-1][0],1);
- Ray->NbRows = Dimension;
-
- /* Initialize the Sat Matrix */
- nbcolumns = (Constraints->NbRows - 1)/(sizeof(int)*8) + 1;
- Sat = SMAlloc(NbMaxRays, nbcolumns);
- SMVector_Init(Sat->p_init,Dimension*nbcolumns);
- Sat->NbRows = Dimension;
-
- CATCH(any_exception_error) {
-
- /* In case of overflow, free the allocated memory and forward. */
- if (Sat) SMFree(&Sat);
- if (Ray) Matrix_Free(Ray);
- if (Pol) Polyhedron_Free(Pol);
- RETHROW();
- }
- TRY {
-
- /* Create ray matrix 'Ray' from constraint matrix 'Constraints' */
- Chernikova(Constraints,Ray,Sat,Dimension-1,NbMaxRays,0,0);
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "[constraints2polyhedron]\nConstraints = ");
- Matrix_Print(stderr,0,Constraints);
- fprintf(stderr, "\nRay = ");
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nSat = ");
- SMPrint(Sat);
-#endif
-
- /* Remove the redundant constraints and create the polyhedron */
- Pol = Remove_Redundants(Constraints,Ray,Sat,0);
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "\nPol = ");
- Polyhedron_Print(stderr,"%4d",Pol);
-#endif
-
- SMFree(&Sat), Sat = NULL;
- Matrix_Free(Ray), Ray = NULL;
- return Pol;
-} /* Constraints2Polyhedron */
-
-#undef POLY_DEBUG
-
-/*
- * Given a polyhedron 'Pol', return a matrix of constraints.
- */
-Matrix *Polyhedron2Constraints(Polyhedron *Pol) {
-
- Matrix *Mat;
- unsigned NbConstraints,Dimension;
-
- POL_ENSURE_INEQUALITIES(Pol);
-
- NbConstraints = Pol->NbConstraints;
- Dimension = Pol->Dimension+2;
- Mat = Matrix_Alloc(NbConstraints,Dimension);
- if(!Mat) {
- errormsg1("Polyhedron2Constraints", "outofmem", "out of memory space");
- return 0;
- }
- Vector_Copy(Pol->Constraint[0],Mat->p_Init,NbConstraints * Dimension);
- return Mat;
-} /* Polyhedron2Constraints */
-
-/**
-
-Given a matrix of rays 'Ray', create and return a polyhedron.
-
- at param Ray Rays (may be modified!)
- at param NbMaxConstrs Estimated number of constraints in the polyhedron.
- at return newly allocated Polyhedron
-
-*/
-Polyhedron *Rays2Polyhedron(Matrix *Ray,unsigned NbMaxConstrs) {
-
- Polyhedron *Pol = NULL;
- Matrix *Mat = NULL;
- SatMatrix *Sat = NULL, *SatTranspose = NULL;
- unsigned Dimension, nbcolumns;
- int i;
-
- Dimension = Ray->NbColumns-1; /* Homogeneous Dimension */
- Sat = NULL;
- SatTranspose = NULL;
- Mat = NULL;
-
- if (Ray->NbRows==0) {
-
- /* If there is no ray in the matrix 'Ray', return an empty polyhedron */
- Pol = Empty_Polyhedron(Dimension-1);
- return(Pol);
- }
-
- /* Ignore for now */
- if (POL_ISSET(NbMaxConstrs, POL_NO_DUAL))
- NbMaxConstrs = 0;
-
- if (Dimension > NbMaxConstrs)
- NbMaxConstrs = Dimension;
-
- /* Allocate space for constraint matrix 'Mat' */
- Mat = Matrix_Alloc(NbMaxConstrs,Dimension+1);
- if(!Mat) {
- errormsg1("Rays2Polyhedron","outofmem","out of memory space");
- return 0;
- }
-
- /* Initialize the constraint matrix 'Mat' */
- Vector_Set(Mat->p_Init,0,NbMaxConstrs * (Dimension+1));
- for (i=0; i<Dimension; i++) {
-
- /* Mat->p[i][i+1]=1 */
- value_set_si(Mat->p[i][i+1],1);
- }
-
- /* Allocate and assign the saturation matrix. Remember we are using a */
- /* transposed saturation matrix referenced by (constraint,ray) pair. */
- Mat->NbRows = Dimension;
- nbcolumns = (Ray->NbRows -1)/(sizeof(int)*8) + 1;
- SatTranspose = SMAlloc(NbMaxConstrs,nbcolumns);
- SMVector_Init(SatTranspose->p[0],Dimension * nbcolumns);
- SatTranspose->NbRows = Dimension;
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "[ray2polyhedron: Before]\nRay = ");
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSatTranspose = ");
- SMPrint (SatTranspose);
-#endif
-
- CATCH(any_exception_error) {
-
- /* In case of overflow, free the allocated memory before forwarding
- * the exception.
- */
- if (SatTranspose) SMFree(&SatTranspose);
- if (Sat) SMFree(&Sat);
- if (Mat) Matrix_Free(Mat);
- if (Pol) Polyhedron_Free(Pol);
- RETHROW();
- }
- TRY {
-
- /* Create constraint matrix 'Mat' from ray matrix 'Ray' */
- Chernikova(Ray,Mat,SatTranspose,Dimension,NbMaxConstrs,0,1);
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "[ray2polyhedron: After]\nRay = ");
- Matrix_Print(stderr,0,Ray);
- fprintf(stderr, "\nConstraints = ");
- Matrix_Print(stderr,0,Mat);
- fprintf(stderr, "\nSatTranspose = ");
- SMPrint (SatTranspose);
-#endif
-
- /* Transform the saturation matrix 'SatTranspose' in the standard */
- /* format, that is, ray X constraint format. */
- Sat = TransformSat(Mat,Ray,SatTranspose);
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "\nSat =");
- SMPrint(Sat);
-#endif
-
- SMFree(&SatTranspose), SatTranspose = NULL;
-
- /* Remove redundant rays from the ray matrix 'Ray' */
- Pol = Remove_Redundants(Mat,Ray,Sat,0);
- } /* of TRY */
-
- UNCATCH(any_exception_error);
-
-#ifdef POLY_DEBUG
- fprintf(stderr, "\nPol = ");
- Polyhedron_Print(stderr,"%4d",Pol);
-#endif
-
- SMFree(&Sat);
- Matrix_Free(Mat);
- return Pol;
-} /* Rays2Polyhedron */
-
-/*
- * Compute the dual representation if P only contains one representation.
- * Currently only handles the case where only the equalities are known.
- */
-void Polyhedron_Compute_Dual(Polyhedron *P)
-{
- if (!F_ISSET(P, POL_VALID))
- return;
-
- if (F_ISSET(P, POL_FACETS | POL_VERTICES))
- return;
-
- if (F_ISSET(P, POL_INEQUALITIES)) {
- Matrix M;
- Polyhedron tmp, *Q;
- /* Pretend P is a Matrix for a second */
- M.NbRows = P->NbConstraints;
- M.NbColumns = P->Dimension+2;
- M.p_Init = P->p_Init;
- M.p = P->Constraint;
- Q = Constraints2Polyhedron(&M, 0);
-
- /* Switch contents of P and Q ... */
- tmp = *Q;
- *Q = *P;
- *P = tmp;
- /* ... but keep the next pointer */
- P->next = Q->next;
- Polyhedron_Free(Q);
- return;
- }
-
- /* other cases not handled yet */
- assert(0);
-}
-
-/*
- * Build a saturation matrix from constraint matrix 'Mat' and ray matrix
- * 'Ray'. Only 'NbConstraints' constraint of matrix 'Mat' are considered
- * in creating the saturation matrix. 'NbMaxRays' is the maximum number
- * of rows (rays) allowed in the saturation matrix.
- * Vin100's stuff, for the polyparam vertices to work.
- */
-static SatMatrix *BuildSat(Matrix *Mat,Matrix *Ray,unsigned NbConstraints,unsigned NbMaxRays) {
-
- SatMatrix *Sat = NULL;
- int i, j, k, jx;
- Value *p1, *p2, *p3;
- unsigned Dimension, NbRay, bx, nbcolumns;
-
- CATCH(any_exception_error) {
- if (Sat)
- SMFree(&Sat);
- RETHROW();
- }
- TRY {
- NbRay = Ray->NbRows;
- Dimension = Mat->NbColumns-1; /* Homogeneous Dimension */
-
- /* Build the Sat matrix */
- nbcolumns = (Mat->NbRows - 1)/(sizeof(int)*8) + 1;
- Sat = SMAlloc(NbMaxRays,nbcolumns);
- Sat->NbRows = NbRay;
- SMVector_Init(Sat->p_init, nbcolumns * NbRay);
- jx=0; bx=MSB;
- for (k=0; k<NbConstraints; k++) {
- for (i=0; i<NbRay; i++) {
-
- /* Compute the dot product of ray(i) and constraint(k) and */
- /* store in the status element of ray(i). */
- p1 = Ray->p[i]+1;
- p2 = Mat->p[k]+1;
- p3 = Ray->p[i];
- value_set_si(*p3,0);
- for (j=0; j<Dimension; j++) {
- value_addmul(*p3, *p1, *p2);
- p1++; p2++;
- }
- }
- for (j=0; j<NbRay; j++) {
-
- /* Set 1 in the saturation matrix if the ray doesn't saturate */
- /* the constraint, otherwise the entry is 0. */
- if (value_notzero_p(Ray->p[j][0]))
- Sat->p[j][jx]|=bx;
- }
- NEXT(jx, bx);
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- return Sat;
-} /* BuildSat */
-
-/*
- * Add 'Nbconstraints' new constraints to polyhedron 'Pol'. Constraints are
- * pointed by 'Con' and the maximum allowed rays in the new polyhedron is
- * 'NbMaxRays'.
- */
-Polyhedron *AddConstraints(Value *Con,unsigned NbConstraints,Polyhedron *Pol,unsigned NbMaxRays) {
-
- Polyhedron *NewPol = NULL;
- Matrix *Mat = NULL, *Ray = NULL;
- SatMatrix *Sat = NULL;
- unsigned NbRay, NbCon, Dimension;
-
- if (NbConstraints == 0)
- return Polyhedron_Copy(Pol);
-
- POL_ENSURE_INEQUALITIES(Pol);
- Dimension = Pol->Dimension + 2; /* Homogeneous Dimension + Status */
-
- if (POL_ISSET(NbMaxRays, POL_NO_DUAL)) {
- NbCon = Pol->NbConstraints + NbConstraints;
-
- Mat = Matrix_Alloc(NbCon, Dimension);
- if (!Mat) {
- errormsg1("AddConstraints", "outofmem", "out of memory space");
- return NULL;
- }
- Vector_Copy(Pol->Constraint[0], Mat->p[0], Pol->NbConstraints * Dimension);
- Vector_Copy(Con, Mat->p[Pol->NbConstraints], NbConstraints * Dimension);
- NewPol = Constraints2Polyhedron(Mat, NbMaxRays);
- Matrix_Free(Mat);
- return NewPol;
- }
-
- POL_ENSURE_VERTICES(Pol);
-
- CATCH(any_exception_error) {
- if (NewPol) Polyhedron_Free(NewPol);
- if (Mat) Matrix_Free(Mat);
- if (Ray) Matrix_Free(Ray);
- if (Sat) SMFree(&Sat);
- RETHROW();
- }
- TRY {
- NbRay = Pol->NbRays;
- NbCon = Pol->NbConstraints + NbConstraints;
-
- if (NbRay > NbMaxRays)
- NbMaxRays = NbRay;
-
- Mat = Matrix_Alloc(NbCon, Dimension);
- if(!Mat) {
- errormsg1("AddConstraints", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* Copy constraints of polyhedron 'Pol' to matrix 'Mat' */
- Vector_Copy(Pol->Constraint[0], Mat->p[0], Pol->NbConstraints * Dimension);
-
- /* Add the new constraints pointed by 'Con' to matrix 'Mat' */
- Vector_Copy(Con, Mat->p[Pol->NbConstraints], NbConstraints * Dimension);
-
- /* Allocate space for ray matrix 'Ray' */
- Ray = Matrix_Alloc(NbMaxRays, Dimension);
- if(!Ray) {
- errormsg1("AddConstraints", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
- Ray->NbRows = NbRay;
-
- /* Copy rays of polyhedron 'Pol' to matrix 'Ray' */
- if (NbRay)
- Vector_Copy(Pol->Ray[0], Ray->p[0], NbRay * Dimension);
-
- /* Create the saturation matrix 'Sat' from constraint matrix 'Mat' and */
- /* ray matrix 'Ray' . */
- Sat = BuildSat(Mat, Ray, Pol->NbConstraints, NbMaxRays);
-
- /* Create the ray matrix 'Ray' from the constraint matrix 'Mat' */
- Pol_status = Chernikova(Mat, Ray, Sat, Pol->NbBid, NbMaxRays, Pol->NbConstraints,0);
-
- /* Remove redundant constraints from matrix 'Mat' */
- NewPol = Remove_Redundants(Mat, Ray, Sat, 0);
-
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- SMFree(&Sat);
- Matrix_Free(Ray);
- Matrix_Free(Mat);
- return NewPol;
-} /* AddConstraints */
-
-/*
- * Return 1 if 'Pol1' includes (covers) 'Pol2', 0 otherwise.
- * Polyhedron 'A' includes polyhedron 'B' if the rays of 'B' saturate
- * the equalities and verify the inequalities of 'A'. Both 'Pol1' and
- * 'Pol2' have same dimensions.
- */
-int PolyhedronIncludes(Polyhedron *Pol1,Polyhedron *Pol2) {
-
- int Dimension = Pol1->Dimension + 1; /* Homogenous Dimension */
- int i, j, k;
- Value *p1, *p2, p3;
-
- POL_ENSURE_FACETS(Pol1);
- POL_ENSURE_VERTICES(Pol1);
- POL_ENSURE_FACETS(Pol2);
- POL_ENSURE_VERTICES(Pol2);
-
- value_init(p3);
- for (k=0; k<Pol1->NbConstraints; k++) {
- for (i=0;i<Pol2->NbRays;i++) {
-
- /* Compute the dot product of ray(i) and constraint(k) and store in p3 */
- p1 = Pol2->Ray[i]+1;
- p2 = Pol1->Constraint[k]+1;
- value_set_si(p3,0);
- for(j=0;j<Dimension;j++) {
- value_addmul(p3, *p1,*p2);
- p1++; p2++;
- }
-
- /* If (p3 < 0) or (p3 > 0 and (constraint(k) is equality
- or ray(i) is a line)), return 0 */
- if(value_neg_p(p3) ||
- (value_notzero_p(p3)
- && (value_zero_p(Pol1->Constraint[k][0]) || (value_zero_p(Pol2->Ray[i][0])) ) )) {
- value_clear(p3);
- return 0;
- }
- }
- }
- value_clear(p3);
- return 1;
-} /* PolyhedronIncludes */
-
-/*
- * Add Polyhedron 'Pol' to polhedral domain 'PolDomain'. If 'Pol' covers
- * some polyhedron in the domain 'PolDomain', it is removed from the list.
- * On the other hand if some polyhedron in the domain covers polyhedron
- * 'Pol' then 'Pol' is not included in the domain.
- */
-Polyhedron *AddPolyToDomain(Polyhedron *Pol,Polyhedron *PolDomain) {
-
- Polyhedron *p, *pnext, *p_domain_end = (Polyhedron *) 0;
- int Redundant;
-
- if (!Pol)
- return PolDomain;
- if (!PolDomain)
- return Pol;
-
- POL_ENSURE_FACETS(Pol);
- POL_ENSURE_VERTICES(Pol);
-
- /* Check for emptiness of polyhedron 'Pol' */
- if (emptyQ(Pol)) {
- Polyhedron_Free(Pol);
- return PolDomain;
- }
-
- POL_ENSURE_FACETS(PolDomain);
- POL_ENSURE_VERTICES(PolDomain);
-
- /* Check for emptiness of polyhedral domain 'PolDomain' */
- if (emptyQ(PolDomain)) {
- Polyhedron_Free(PolDomain);
- return Pol;
- }
-
- /* Test 'Pol' against the domain 'PolDomain' */
- Redundant = 0;
- for (p=PolDomain,PolDomain=(Polyhedron *)0; p; p=pnext) {
-
- /* If 'Pol' covers 'p' */
- if (PolyhedronIncludes(Pol, p))
- {
- /* free p */
- pnext = p->next;
- Polyhedron_Free( p );
- continue;
- }
-
- /* Add polyhedron p to the new domain list */
- if (!PolDomain) PolDomain = p; else p_domain_end->next = p;
- p_domain_end = p;
-
- /* If p covers Pol */
- if (PolyhedronIncludes(p,Pol)) {
- Redundant = 1;
- break;
- }
- pnext = p->next;
- }
- if (!Redundant) {
-
- /* The whole list has been checked. Add new polyhedron 'Pol' to the */
- /* new domain list. */
- if (!PolDomain) PolDomain = Pol; else p_domain_end->next = Pol;
- }
- else {
-
- /* The rest of the list is just inherited from p */
- Polyhedron_Free(Pol);
- }
- return PolDomain;
-} /* AddPolyToDomain */
-
-/*
- * Given a polyhedra 'Pol' and a single constraint 'Con' and an integer 'Pass'
- * whose value ranges from 0 to 3, add the inverse of constraint 'Con' to the
- * constraint set of 'Pol' and return the new polyhedron. 'NbMaxRays' is the
- * maximum allowed rays in the new generated polyhedron.
- * If Pass == 0, add ( -constraint -1) >= 0
- * If Pass == 1, add ( +constraint -1) >= 0
- * If Pass == 2, add ( -constraint ) >= 0
- * If Pass == 3, add ( +constraint ) >= 0
- */
-Polyhedron *SubConstraint(Value *Con,Polyhedron *Pol,unsigned NbMaxRays,int Pass) {
-
- Polyhedron *NewPol = NULL;
- Matrix *Mat = NULL, *Ray = NULL;
- SatMatrix *Sat = NULL;
- unsigned NbRay, NbCon, NbEle1, Dimension;
- int i;
-
- POL_ENSURE_FACETS(Pol);
- POL_ENSURE_VERTICES(Pol);
-
- CATCH(any_exception_error) {
- if (NewPol) Polyhedron_Free(NewPol);
- if (Mat) Matrix_Free(Mat);
- if (Ray) Matrix_Free(Ray);
- if (Sat) SMFree(&Sat);
- RETHROW();
- }
- TRY {
-
- /* If 'Con' is the positivity constraint, return Null */
- Dimension = Pol->Dimension+1; /* Homogeneous Dimension */
- for (i=1; i<Dimension; i++)
- if (value_notzero_p(Con[i])) break;
- if (i==Dimension) {
- UNCATCH(any_exception_error);
- return (Polyhedron *) 0;
- }
-
- NbRay = Pol->NbRays;
- NbCon = Pol->NbConstraints;
- Dimension = Pol->Dimension+2; /* Homogeneous Dimension + Status */
- NbEle1 = NbCon * Dimension;
-
- /* Ignore for now */
- if (POL_ISSET(NbMaxRays, POL_NO_DUAL))
- NbMaxRays = 0;
-
- if (NbRay > NbMaxRays)
- NbMaxRays = NbRay;
-
- Mat = Matrix_Alloc(NbCon + 1, Dimension);
- if(!Mat) {
- errormsg1("SubConstraint", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* Set the constraints of Pol */
- Vector_Copy(Pol->Constraint[0], Mat->p[0], NbEle1);
-
- /* Add the new constraint */
- value_set_si(Mat->p[NbCon][0],1);
- if (!(Pass&1))
- for(i=1; i<Dimension; i++)
- value_oppose(Mat->p[NbCon][i],Con[i]);
- else
- for(i=1; i<Dimension; i++)
- value_assign(Mat->p[NbCon][i],Con[i]);
- if (!(Pass&2))
- value_decrement(Mat->p[NbCon][Dimension-1],Mat->p[NbCon][Dimension-1]);
-
- /* Allocate the ray matrix. */
- Ray = Matrix_Alloc(NbMaxRays, Dimension);
- if(!Ray) {
- errormsg1("SubConstraint", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* Initialize the ray matrix with the rays of polyhedron 'Pol' */
- Ray->NbRows = NbRay;
- if (NbRay)
- Vector_Copy(Pol->Ray[0], Ray->p[0], NbRay * Dimension);
-
- /* Create the saturation matrix from the constraint matrix 'mat' and */
- /* ray matrix 'Ray'. */
- Sat = BuildSat(Mat, Ray, NbCon, NbMaxRays);
-
- /* Create the ray matrix 'Ray' from consraint matrix 'Mat' */
- Pol_status = Chernikova(Mat, Ray, Sat, Pol->NbBid, NbMaxRays, NbCon,0);
-
- /* Remove redundant constraints from matrix 'Mat' */
- NewPol = Remove_Redundants(Mat, Ray, Sat, 0);
-
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
-
- SMFree(&Sat);
- Matrix_Free(Ray);
- Matrix_Free(Mat);
- return NewPol;
-} /* SubConstraint */
-
-/*
- * Return the intersection of two polyhedral domains 'Pol1' and 'Pol2'.
- * The maximum allowed rays in the new polyhedron generated is 'NbMaxRays'.
- */
-Polyhedron *DomainIntersection(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
-
- Polyhedron *p1, *p2, *p3, *d;
-
- if (!Pol1 || !Pol2) return (Polyhedron*) 0;
- if (Pol1->Dimension != Pol2->Dimension) {
- errormsg1( "DomainIntersection", "diffdim",
- "operation on different dimensions");
- return (Polyhedron*) 0;
- }
-
- /* For every polyhedron pair (p1,p2) where p1 belongs to domain Pol1 and */
- /* p2 belongs to domain Pol2, compute the intersection and add it to the */
- /* new domain 'd'. */
- d = (Polyhedron *)0;
- for (p1=Pol1; p1; p1=p1->next) {
- for (p2=Pol2; p2; p2=p2->next) {
- p3 = AddConstraints(p2->Constraint[0],
- p2->NbConstraints, p1, NbMaxRays);
- d = AddPolyToDomain(p3,d);
- }
- }
- if (!d)
- return Empty_Polyhedron(Pol1->Dimension);
- else
- return d;
-
-} /* DomainIntersection */
-
-/*
- * Given a polyhedron 'Pol', return a matrix of rays.
- */
-Matrix *Polyhedron2Rays(Polyhedron *Pol) {
-
- Matrix *Ray;
- unsigned NbRays, Dimension;
-
- POL_ENSURE_POINTS(Pol);
-
- NbRays = Pol->NbRays;
- Dimension = Pol->Dimension+2; /* Homogeneous Dimension + Status */
- Ray = Matrix_Alloc(NbRays, Dimension);
- if(!Ray) {
- errormsg1("Polyhedron2Rays", "outofmem", "out of memory space");
- return 0;
- }
- Vector_Copy(Pol->Ray[0], Ray->p_Init, NbRays*Dimension);
- return Ray;
-} /* Polyhedron2Rays */
-
-/*
- * Add 'NbAddedRays' rays to polyhedron 'Pol'. Rays are pointed by 'AddedRays'
- * and the maximum allowed constraints in the new polyhedron is 'NbMaxConstrs'.
- */
-Polyhedron *AddRays(Value *AddedRays,unsigned NbAddedRays,Polyhedron *Pol,unsigned NbMaxConstrs) {
-
- Polyhedron *NewPol = NULL;
- Matrix *Mat = NULL, *Ray = NULL;
- SatMatrix *Sat = NULL, *SatTranspose = NULL;
- unsigned NbCon, NbRay,NbEle1, Dimension;
-
- POL_ENSURE_FACETS(Pol);
- POL_ENSURE_VERTICES(Pol);
-
- CATCH(any_exception_error) {
- if (NewPol) Polyhedron_Free(NewPol);
- if (Mat) Matrix_Free(Mat);
- if (Ray) Matrix_Free(Ray);
- if (Sat) SMFree(&Sat);
- if (SatTranspose) SMFree(&SatTranspose);
- RETHROW();
- }
- TRY {
-
- NbCon = Pol->NbConstraints;
- NbRay = Pol->NbRays;
- Dimension = Pol->Dimension + 2; /* Homogeneous Dimension + Status */
- NbEle1 = NbRay * Dimension;
-
- Ray = Matrix_Alloc(NbAddedRays + NbRay, Dimension);
- if(!Ray) {
- errormsg1("AddRays", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* Copy rays of polyhedron 'Pol' to matrix 'Ray' */
- if (NbRay)
- Vector_Copy(Pol->Ray[0], Ray->p_Init, NbEle1);
-
- /* Add the new rays pointed by 'AddedRays' to matrix 'Ray' */
- Vector_Copy(AddedRays, Ray->p_Init+NbEle1, NbAddedRays * Dimension);
-
- /* Ignore for now */
- if (POL_ISSET(NbMaxConstrs, POL_NO_DUAL))
- NbMaxConstrs = 0;
-
- /* We need at least NbCon rows */
- if (NbMaxConstrs < NbCon)
- NbMaxConstrs = NbCon;
-
- /* Allocate space for constraint matrix 'Mat' */
- Mat = Matrix_Alloc(NbMaxConstrs, Dimension);
- if(!Mat) {
- errormsg1("AddRays", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
- Mat->NbRows = NbCon;
-
- /* Copy constraints of polyhedron 'Pol' to matrix 'Mat' */
- Vector_Copy(Pol->Constraint[0], Mat->p_Init, NbCon*Dimension);
-
- /* Create the saturation matrix 'SatTranspose' from constraint matrix */
- /* 'Mat' and ray matrix 'Ray'. Remember the saturation matrix is */
- /* referenced by (constraint,ray) pair */
- SatTranspose = BuildSat(Ray, Mat, NbRay, NbMaxConstrs);
-
- /* Create the constraint matrix 'Mat' from the ray matrix 'Ray' */
- Pol_status = Chernikova(Ray, Mat, SatTranspose, Pol->NbEq, NbMaxConstrs, NbRay,1);
-
- /* Transform the saturation matrix 'SatTranspose' in the standard format */
- /* , that is, (ray X constraint) format. */
- Sat = TransformSat(Mat, Ray, SatTranspose);
- SMFree(&SatTranspose), SatTranspose = NULL;
-
- /* Remove redundant rays from the ray matrix 'Ray' */
- NewPol = Remove_Redundants(Mat, Ray, Sat, 0);
-
- SMFree(&Sat), Sat = NULL;
- Matrix_Free(Mat), Mat = NULL;
- Matrix_Free(Ray), Ray = NULL;
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- return NewPol;
-} /* AddRays */
-
-/*
- * Add rays pointed by 'Ray' to each and every polyhedron in the polyhedral
- * domain 'Pol'. 'NbMaxConstrs' is maximum allowed constraints in the
- * constraint set of a polyhedron.
- */
-Polyhedron *DomainAddRays(Polyhedron *Pol,Matrix *Ray,unsigned NbMaxConstrs) {
-
- Polyhedron *PolA, *PolEndA, *p1, *p2, *p3;
- int Redundant;
-
- if (!Pol) return (Polyhedron*) 0;
- if (!Ray || Ray->NbRows == 0)
- return Domain_Copy(Pol);
- if (Pol->Dimension != Ray->NbColumns-2) {
- errormsg1(
- "DomainAddRays", "diffdim", "operation on different dimensions");
- return (Polyhedron*) 0;
- }
-
- /* Copy Pol to PolA */
- PolA = PolEndA = (Polyhedron *)0;
- for (p1=Pol; p1; p1=p1->next) {
- p3 = AddRays(Ray->p[0], Ray->NbRows, p1, NbMaxConstrs);
-
- /* Does any component of PolA cover 'p3' ? */
- Redundant = 0;
- for (p2=PolA; p2; p2=p2->next) {
- if (PolyhedronIncludes(p2, p3)) { /* If p2 covers p3 */
- Redundant = 1;
- break;
- }
- }
-
- /* If the new polyheron is not redundant, add it ('p3') to the list */
- if (Redundant)
- Polyhedron_Free(p3);
- else {
- if (!PolEndA)
- PolEndA = PolA = p3;
- else {
- PolEndA->next = p3;
- PolEndA = PolEndA->next;
- }
- }
- }
- return PolA;
-} /* DomainAddRays */
-
-/*
- * Create a copy of the polyhedron 'Pol'
- */
-Polyhedron *Polyhedron_Copy(Polyhedron *Pol) {
-
- Polyhedron *Pol1;
-
- if (!Pol) return (Polyhedron *)0;
-
- /* Allocate space for the new polyhedron */
- Pol1 = Polyhedron_Alloc(Pol->Dimension, Pol->NbConstraints, Pol->NbRays);
- if (!Pol1) {
- errormsg1("Polyhedron_Copy", "outofmem", "out of memory space");
- return 0;
- }
- if( Pol->NbConstraints )
- Vector_Copy(Pol->Constraint[0], Pol1->Constraint[0],
- Pol->NbConstraints*(Pol->Dimension+2));
- if( Pol->NbRays )
- Vector_Copy(Pol->Ray[0], Pol1->Ray[0],
- Pol->NbRays*(Pol->Dimension+2));
- Pol1->NbBid = Pol->NbBid;
- Pol1->NbEq = Pol->NbEq;
- Pol1->flags = Pol->flags;
- return Pol1;
-} /* Polyhedron_Copy */
-
-/*
- * Create a copy of a polyhedral domain.
- */
-Polyhedron *Domain_Copy(Polyhedron *Pol) {
-
- Polyhedron *Pol1;
-
- if (!Pol) return (Polyhedron *) 0;
- Pol1 = Polyhedron_Copy(Pol);
- if (Pol->next) Pol1->next = Domain_Copy(Pol->next);
- return Pol1;
-} /* Domain_Copy */
-
-/*
- * Given constraint number 'k' of a polyhedron, and an array 'Filter' to store
- * the non-redundant constraints of the polyhedron in bit-wise notation, and
- * a Matrix 'Sat', add the constraint 'k' in 'Filter' array. tmpR[i] stores the
- * number of constraints, other than those in 'Filter', which ray(i) saturates
- * or verifies. In case, ray(i) does not saturate or verify a constraint in
- * array 'Filter', it is assigned to -1. Similarly, tmpC[j] stores the number
- * of rays which constraint(j), if it doesn't belong to Filter, saturates or
- * verifies. If constraint(j) belongs to 'Filter', then tmpC[j] is assigned to
- * -1. 'NbConstraints' is the number of constraints in the constraint matrix of
- * the polyhedron.
- * NOTE: (1) 'Sat' is not the saturation matrix of the polyhedron. In fact,
- * entry in 'Sat' is set to 1 if ray(i) of polyhedron1 verifies or
- * saturates the constraint(j) of polyhedron2 and otherwise it is set
- * to 0. So here the difference with saturation matrix is in terms
- * definition and entries(1<->0) of the matrix 'Sat'.
- *
- * ALGORITHM:->
- * (1) Include constraint(k) in array 'Filter'.
- * (2) Set tmpC[k] to -1.
- * (3) For all ray(i) {
- * If ray(i) saturates or verifies constraint(k) then --(tmpR[i])
- * Else {
- * Discard ray(i) by assigning tmpR[i] = -1
- * Decrement tmpC[j] for all constraint(j) not in array 'Filter'.
- * }
- * }
- */
-static void addToFilter(int k, unsigned *Filter, SatMatrix *Sat,Value *tmpR,Value *tmpC,int NbRays,int NbConstraints) {
-
- int kj, i,j, jx;
- unsigned kb, bx;
-
- /* Remove constraint k */
- kj = k/WSIZE; kb = MSB; kb >>= k%WSIZE;
- Filter[kj]|=kb;
- value_set_si(tmpC[k],-1);
-
- /* Remove rays excluded by constraint k */
- for(i=0; i<NbRays; i++)
- if (value_posz_p(tmpR[i])) {
- if (Sat->p[i][kj]&kb)
- value_decrement(tmpR[i],tmpR[i]); /* adjust included ray */
- else {
-
- /* Constraint k excludes ray i -- delete ray i */
- value_set_si(tmpR[i],-1);
-
- /* Adjust non-deleted constraints */
- jx=0; bx=MSB;
- for(j=0; j<NbConstraints; j++) {
- if (value_posz_p(tmpC[j]) && (Sat->p[i][jx]&bx) )
- value_decrement(tmpC[j],tmpC[j]);
- NEXT(jx,bx);
- }
- }
- }
-} /* addToFilter */
-
-/*
- * Given polyhedra 'P1' and 'P2' such that their intersection is an empty
- * polyhedron, find the minimal set of constraints of 'P1' which contradict
- * all of the constraints of 'P2'. This is believed to be an NP-hard problem
- * and so a heuristic is employed to solve it in worst case. The heuristic is
- * to select in every turn that constraint of 'P1' which excludes most rays of
- * 'P2'. A bit in the binary format of an element of array 'Filter' is set to
- * 1 if the corresponding constraint is to be included in the minimal set of
- * constraints otherwise it is set to 0.
- */
-static void FindSimple(Polyhedron *P1,Polyhedron *P2,unsigned *Filter,unsigned NbMaxRays) {
-
- Matrix *Mat = NULL;
- SatMatrix *Sat = NULL;
- int i, j, k, jx, found;
- Value *p1, *p2, p3;
- unsigned Dimension, NbRays, NbConstraints, bx, nc;
- Value NbConstraintsLeft, tmp;
- Value *tmpC = NULL, *tmpR = NULL;
- Polyhedron *Pol = NULL, *Pol2 = NULL;
-
- /* Initialize all the 'Value' variables */
- value_init(p3); value_init(NbConstraintsLeft);
- value_init(tmp);
-
- CATCH(any_exception_error) {
- if (tmpC) free(tmpC);
- if (tmpR) free(tmpR);
- if (Mat) Matrix_Free(Mat);
- if (Sat) SMFree(&Sat);
- if (Pol2 && Pol2!=P2) Polyhedron_Free(Pol2);
- if (Pol && Pol!=Pol2 && Pol!=P2) Polyhedron_Free(Pol);
-
- /* Clear all the 'Value' variables */
- value_clear(p3); value_clear(NbConstraintsLeft);
- value_clear(tmp);
- RETHROW();
- }
- TRY {
-
- Dimension = P1->Dimension+2; /* status + homogeneous Dimension */
- Mat = Matrix_Alloc(P1->NbConstraints, Dimension);
- if(!Mat) {
- errormsg1("FindSimple", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
-
- /* Clear all the 'Value' variables */
- value_clear(p3); value_clear(NbConstraintsLeft); value_clear(tmp);
- return;
- }
-
- /* Post constraints in P1 already included by Filter */
- jx = 0; bx = MSB; Mat->NbRows=0;
- value_set_si(NbConstraintsLeft,0);
- for (k=0; k<P1->NbConstraints; k++) {
- if (Filter[jx]&bx) {
- Vector_Copy(P1->Constraint[k], Mat->p[Mat->NbRows], Dimension);
- Mat->NbRows++;
- }
- else
- value_increment(NbConstraintsLeft,NbConstraintsLeft);
- NEXT(jx,bx);
- }
- Pol2 = P2;
-
- for (;;) {
- if (Mat->NbRows==0)
- Pol = Polyhedron_Copy(Pol2);
- else {
- Pol = AddConstraints(Mat->p_Init, Mat->NbRows, Pol2, NbMaxRays);
- if (Pol2 != P2) Polyhedron_Free(Pol2), Pol2 = NULL;
- }
- if (emptyQ(Pol)) {
- Matrix_Free(Mat), Mat = NULL;
- Polyhedron_Free(Pol), Pol = NULL;
- UNCATCH(any_exception_error);
-
- /* Clear all the 'Value' variables */
- value_clear(p3); value_clear(NbConstraintsLeft); value_clear(tmp);
- return;
- }
- Mat->NbRows = 0; /* Reset Mat */
- Pol2 = Pol;
-
- /* Its not enough-- find some more constraints */
- Dimension = Pol->Dimension+1; /* homogeneous Dimension */
- NbRays = Pol->NbRays;
- NbConstraints = P1->NbConstraints;
- tmpR = (Value *)malloc(NbRays*sizeof(Value));
- if(!tmpR) {
- errormsg1("FindSimple", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
-
- /* Clear all the 'Value' variables */
- value_clear(p3); value_clear(NbConstraintsLeft); value_clear(tmp);
- return;
- }
- for(i=0;i<NbRays;i++)
- value_init(tmpR[i]);
- tmpC = (Value *)malloc(NbConstraints*sizeof(Value));
- if(!tmpC) {
- errormsg1("FindSimple", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
-
- /* Clear all the 'Value' variables */
- value_clear(p3); value_clear(NbConstraintsLeft);
- for(i=0;i<NbRays;i++)
- value_clear(tmpR[i]);
- free(tmpR);
- return;
- }
- for(i=0;i<NbConstraints;i++)
- value_init(tmpC[i]);
- Vector_Set(tmpR,0,NbRays);
- Vector_Set(tmpC,0,NbConstraints);
-
- /* Build the Sat matrix */
- nc = (NbConstraints - 1) / (sizeof(int)*8) + 1;
- Sat = SMAlloc(NbRays, nc);
- Sat->NbRows = NbRays;
- SMVector_Init(Sat->p_init, nc*NbRays);
-
- jx=0; bx=MSB;
- for (k=0; k<NbConstraints; k++) {
- if (Filter[jx]&bx)
- value_set_si(tmpC[k],-1);
- else
- for (i=0; i<NbRays; i++) {
- p1 = Pol->Ray[i]+1;
- p2 = P1->Constraint[k]+1;
- value_set_si(p3,0);
- for (j=0; j<Dimension; j++) {
- value_addmul(p3, *p1, *p2);
- p1++; p2++;
- }
- if(value_zero_p(p3) ||
- (value_pos_p(p3) && value_notzero_p(P1->Constraint[k][0]))) {
- Sat->p[i][jx]|=bx; /* constraint includes ray, set flag */
- value_increment(tmpR[i],tmpR[i]);
- value_increment(tmpC[k],tmpC[k]);
- }
- }
- NEXT(jx, bx);
- }
-
- do { /* find all of the essential constraints */
- found = 0;
- for(i=0; i<NbRays; i++)
- if(value_posz_p(tmpR[i])) {
- value_add_int(tmp,tmpR[i],1);
- if(value_eq(tmp,NbConstraintsLeft)) {
-
- /* Ray i is excluded by only one constraint... find it */
- jx = 0; bx = MSB;
- for(k=0; k<NbConstraints; k++) {
- if(value_posz_p(tmpC[k]) && ((Sat->p[i][jx]&bx)==0)) {
- addToFilter(k, Filter, Sat, tmpR, tmpC,
- NbRays, NbConstraints);
- Vector_Copy(P1->Constraint[k],
- Mat->p[Mat->NbRows],Dimension+1);
- Mat->NbRows++;
- value_decrement(NbConstraintsLeft,NbConstraintsLeft);
- found=1;
- break;
- }
- NEXT(jx,bx);
- }
- break;
- }
- }
- }
- while (found);
-
- if (!Mat->NbRows) { /* Well then, just use a stupid heuristic */
- /* find the constraint which excludes the most */
- Value cmax;
- value_init(cmax);
-
-#ifndef LINEAR_VALUE_IS_CHARS
- value_set_si(cmax,(NbRays * NbConstraints+1));
-#else
- value_set_si(cmax,1);
-#endif
-
- j = -1;
- for(k=0; k<NbConstraints; k++)
- if (value_posz_p(tmpC[k])) {
- if (value_gt(cmax,tmpC[k])) {
- value_assign(cmax,tmpC[k]);
- j = k;
- }
- }
- value_clear(cmax);
- if (j<0) {
- errormsg1("DomSimplify","logerror","logic error");
- }
- else {
- addToFilter(j, Filter, Sat, tmpR, tmpC, NbRays, NbConstraints);
- Vector_Copy(P1->Constraint[j],Mat->p[Mat->NbRows],Dimension+1);
- Mat->NbRows++;
- value_decrement(NbConstraintsLeft,NbConstraintsLeft);
- }
- }
- SMFree(&Sat), Sat = NULL;
- free(tmpC), tmpC = NULL;
- free(tmpR), tmpR = NULL;
- }
- } /* end of TRY */
-
- /* Clear all the 'Value' variables */
- value_clear(p3); value_clear(NbConstraintsLeft);
- value_clear(tmp);
- for(i=0;i<NbRays;i++)
- value_clear(tmpR[i]);
- for(i=0;i<NbRays;i++)
- value_clear(tmpC[i]);
-
- UNCATCH(any_exception_error);
-} /* FindSimple */
-
-/*
- * Return 0 if the intersection of Pol1 and Pol2 is empty, otherwise return 1.
- * If the intersection is non-empty, store the non-redundant constraints in
- * 'Filter' array. If the intersection is empty then store the smallest set of
- * constraints of 'Pol1' which on intersection with 'Pol2' gives empty set, in
- * 'Filter' array. 'NbMaxRays' is the maximum allowed rays in the intersection
- * of 'Pol1' and 'Pol2'.
- */
-static int SimplifyConstraints(Polyhedron *Pol1,Polyhedron *Pol2,unsigned *Filter,unsigned NbMaxRays) {
-
- Polyhedron *Pol = NULL;
- Matrix *Mat = NULL, *Ray = NULL;
- SatMatrix *Sat = NULL;
- unsigned NbRay, NbCon, NbCon1, NbCon2, NbEle1, Dimension, notempty;
-
- CATCH(any_exception_error) {
- if (Pol) Polyhedron_Free(Pol);
- if (Mat) Matrix_Free(Mat);
- if (Ray) Matrix_Free(Ray);
- if (Sat) SMFree(&Sat);
- RETHROW();
- }
- TRY {
-
- NbRay = Pol1->NbRays;
- NbCon1 = Pol1->NbConstraints;
- NbCon2 = Pol2->NbConstraints;
- NbCon = NbCon1 + NbCon2;
- Dimension = Pol1->Dimension+2; /* Homogeneous Dimension + Status */
- NbEle1 = NbCon1*Dimension;
-
- /* Ignore for now */
- if (POL_ISSET(NbMaxRays, POL_NO_DUAL))
- NbMaxRays = 0;
-
- if (NbRay > NbMaxRays)
- NbMaxRays = NbRay;
-
- /* Allocate space for constraint matrix 'Mat' */
- Mat = Matrix_Alloc(NbCon, Dimension);
- if(!Mat) {
- errormsg1("SimplifyConstraints", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* Copy constraints of 'Pol1' to matrix 'Mat' */
- Vector_Copy(Pol1->Constraint[0], Mat->p_Init, NbEle1);
-
- /* Add constraints of 'Pol2' to matrix 'Mat'*/
- Vector_Copy(Pol2->Constraint[0], Mat->p_Init+NbEle1, NbCon2*Dimension);
-
- /* Allocate space for ray matrix 'Ray' */
- Ray = Matrix_Alloc(NbMaxRays, Dimension);
- if(!Ray) {
- errormsg1("SimplifyConstraints", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
- Ray->NbRows = NbRay;
-
- /* Copy rays of polyhedron 'Pol1' to matrix 'Ray' */
- Vector_Copy(Pol1->Ray[0], Ray->p_Init, NbRay*Dimension);
-
- /* Create saturation matrix from constraint matrix 'Mat' and ray matrix */
- /* 'Ray'. */
- Sat = BuildSat(Mat, Ray, NbCon1, NbMaxRays);
-
- /* Create the ray matrix 'Ray' from the constraint matrix 'Mat' */
- Pol_status = Chernikova(Mat, Ray, Sat, Pol1->NbBid, NbMaxRays, NbCon1,0);
-
- /* Remove redundant constraints from the constraint matrix 'Mat' */
- Pol = Remove_Redundants(Mat, Ray, Sat, Filter);
- notempty = 1;
- if (Filter && emptyQ(Pol)) {
- notempty = 0;
- FindSimple(Pol1, Pol2, Filter, NbMaxRays);
- }
- /* Polyhedron_Print(stderr,"%4d",Pol1); */
-
- Polyhedron_Free(Pol), Pol = NULL;
- SMFree(&Sat), Sat = NULL;
- Matrix_Free(Ray), Ray = NULL;
- Matrix_Free(Mat), Mat = NULL;
-
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- return notempty;
-} /* SimplifyConstraints */
-
-/*
- * Eliminate equations of Pol1 using equations of Pol2. Mark as needed,
- * equations of Pol1 that are not eliminated. Or info into Filter vector.
- */
-static void SimplifyEqualities(Polyhedron *Pol1, Polyhedron *Pol2, unsigned *Filter) {
-
- int i,j;
- unsigned ix, bx, NbEqn, NbEqn1, NbEqn2, NbEle2, Dimension;
- Matrix *Mat;
-
- NbEqn1 = Pol1->NbEq;
- NbEqn2 = Pol2->NbEq;
- NbEqn = NbEqn1 + NbEqn2;
- Dimension = Pol1->Dimension+2; /* Homogeneous Dimension + Status */
- NbEle2 = NbEqn2*Dimension;
-
- Mat = Matrix_Alloc(NbEqn, Dimension);
- if (!Mat) {
- errormsg1("SimplifyEqualities", "outofmem", "out of memory space");
- Pol_status = 1;
- return;
- }
-
- /* Set the equalities of Pol2 */
- Vector_Copy(Pol2->Constraint[0], Mat->p_Init, NbEle2);
-
- /* Add the equalities of Pol1 */
- Vector_Copy(Pol1->Constraint[0], Mat->p_Init+NbEle2, NbEqn1*Dimension);
-
- Gauss(Mat, NbEqn2, Dimension-1);
-
- ix = 0;
- bx = MSB;
- for (i=NbEqn2; i<NbEqn; i++) {
- for (j=1; j<Dimension; j++) {
- if (value_notzero_p(Mat->p[i][j])) {
- /* If any coefficient of the equation is non-zero */
- /* Set the filter bit for the equation */
-
- Filter[ix] |= bx;
- break;
- }
- }
- NEXT(ix,bx);
- }
- Matrix_Free(Mat);
- return;
-} /* SimplifyEqualities */
-
-
-/*
- * Given two polyhedral domains 'Pol1' and 'Pol2', find the largest domain
- * set (or the smallest list of non-redundant constraints), that when
- * intersected with polyhedral domain 'Pol2' equals (Pol1)intersect(Pol2).
- * The output is a polyhedral domain with the "redundant" constraints removed.
- * 'NbMaxRays' is the maximium allowed rays in the new polyhedra.
- */
-Polyhedron *DomainSimplify(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays) {
-
- Polyhedron *p1, *p2, *p3, *d;
- unsigned k, jx, bx, nbentries, NbConstraints, Dimension, NbCon, empty;
- unsigned *Filter;
- Matrix *Constraints;
-
-
- if (!Pol1 || !Pol2) return Pol1;
- if (Pol1->Dimension != Pol2->Dimension) {
- errormsg1("DomSimplify","diffdim","operation on different dimensions");
- Pol_status = 1;
- return 0;
- }
- POL_ENSURE_VERTICES(Pol1);
- POL_ENSURE_VERTICES(Pol2);
- if (emptyQ(Pol1)||emptyQ(Pol2))
- return Empty_Polyhedron(Pol1->Dimension);
-
- /* Find the maximum number of constraints over all polyhedron in the */
- /* polyhedral domain 'Pol2' and store in 'NbCon'. */
- NbCon = 0;
- for (p2=Pol2; p2; p2=p2->next)
- if (p2->NbConstraints > NbCon)
- NbCon = p2->NbConstraints;
-
- Dimension = Pol1->Dimension+2; /* Homogenous Dimension + Status */
- d = (Polyhedron *)0;
- for (p1=Pol1; p1; p1=p1->next) {
-
- POL_ENSURE_VERTICES(p1);
-
- /* Filter is an array of integers, each bit in an element of Filter */
- /* array corresponds to a constraint. The bit is marked 1 if the */
- /* corresponding constraint is non-redundant and is 0 if it is */
- /* redundant. */
-
- NbConstraints = p1->NbConstraints;
- nbentries = (NbConstraints + NbCon - 1) / (sizeof(int)*8) + 1;
-
- /* Allocate space for array 'Filter' */
- Filter = (unsigned *)malloc(nbentries * sizeof(int));
- if (!Filter) {
- errormsg1("DomSimplify", "outofmem", "out of memory space\n");
- Pol_status = 1;
- return 0;
- }
-
- /* Initialize 'Filter' with zeros */
- SMVector_Init(Filter, nbentries);
-
- /* Filter the constraints of p1 in context of polyhedra p2(s) */
- empty = 1;
- for (p2=Pol2; p2; p2=p2->next) {
-
- POL_ENSURE_VERTICES(p2);
-
- /* Store the non-redundant constraints in array 'Filter'. With */
- /* successive loops, the array 'Filter' holds the union of all */
- /* non-redundant constraints. 'empty' is set to zero if the */
- /* intersection of two polyhedra is non-empty and Filter is !Null */
-
- SimplifyEqualities(p1, p2, Filter);
- if (SimplifyConstraints(p1, p2, Filter, NbMaxRays))
- empty=0;
-
- /* takes the union of all non redundant constraints */
- }
-
- if (!empty) {
-
- /* Copy all non-redundant constraints to matrix 'Constraints' */
- Constraints = Matrix_Alloc(NbConstraints, Dimension);
- if (!Constraints) {
- errormsg1("DomSimplify", "outofmem", "out of memory space\n");
- Pol_status = 1;
- return 0;
- }
- Constraints->NbRows = 0;
- for (k=0, jx=0, bx=MSB; k<NbConstraints; k++) {
-
- /* If a bit entry in Filter[jx] is marked 1, copy the correspond- */
- /* ing constraint in matrix 'Constraints'. */
- if (Filter[jx]&bx) {
- Vector_Copy(p1->Constraint[k],
- Constraints->p[Constraints->NbRows],
- Dimension);
- Constraints->NbRows++;
- }
- NEXT(jx,bx);
- }
-
- /* Create the polyhedron 'p3' corresponding to the constraints in */
- /* matrix 'Constraints'. */
- p3 = Constraints2Polyhedron(Constraints,NbMaxRays);
- Matrix_Free(Constraints);
-
- /* Add polyhedron 'p3' in the domain 'd'. */
- d = AddPolyToDomain (p3, d);
- p3 = NULL;
- }
- free(Filter);
- }
- if (!d)
- return Empty_Polyhedron(Pol1->Dimension);
- else return d;
-
-} /* DomainSimplify */
-
-/*
- * Domain Simplify as defined in Strasborg Polylib version.
- */
-Polyhedron *Stras_DomainSimplify(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
-
- Polyhedron *p1, *p2, *p3 = NULL, *d = NULL;
- unsigned k, jx, bx, nbentries, NbConstraints, Dimension, NbCon, empty;
- unsigned *Filter = NULL;
- Matrix *Constraints = NULL;
-
- CATCH(any_exception_error) {
- if (Constraints) Matrix_Free(Constraints);
- if (Filter) free(Filter);
- if (d) Polyhedron_Free(d);
- if (p2) Polyhedron_Free(p3);
- RETHROW();
- }
- TRY {
- if (!Pol1 || !Pol2) {
- UNCATCH(any_exception_error);
- return Pol1;
- }
- if (Pol1->Dimension != Pol2->Dimension) {
- errormsg1("DomainSimplify","diffdim","operation on different dimensions");
- UNCATCH(any_exception_error);
- return 0;
- }
- POL_ENSURE_VERTICES(Pol1);
- POL_ENSURE_VERTICES(Pol2);
- if (emptyQ(Pol1)||emptyQ(Pol2)) {
- UNCATCH(any_exception_error);
- return Empty_Polyhedron(Pol1->Dimension);
- }
-
- /* Find the maximum number of constraints over all polyhedron in the */
- /* polyhedral domain 'Pol2' and store in 'NbCon'. */
- NbCon = 0;
- for (p2=Pol2; p2; p2=p2->next)
- if (p2->NbConstraints > NbCon)
- NbCon = p2->NbConstraints;
-
- Dimension = Pol1->Dimension+2; /* Homogenous Dimension + Status */
- d = (Polyhedron *)0;
- for (p1=Pol1; p1; p1=p1->next) {
-
- /* Filter is an array of integers, each bit in an element of Filter */
- /* array corresponds to a constraint. The bit is marked 1 if the */
- /* corresponding constraint is non-redundant and is 0 if it is */
- /* redundant. */
-
- NbConstraints = p1->NbConstraints;
- nbentries = (NbConstraints + NbCon - 1)/(sizeof(int)*8) + 1;
-
- /* Allocate space for array 'Filter' */
- Filter = (unsigned *)malloc(nbentries * sizeof(int));
- if(!Filter) {
- errormsg1("DomainSimplify", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* Initialize 'Filter' with zeros */
- SMVector_Init(Filter, nbentries);
-
- /* Filter the constraints of p1 in context to the polyhedra p2(s) */
- empty = 1;
- for (p2=Pol2; p2; p2=p2->next) {
-
- /* Store the non-redundant constraints in array 'Filter'. With */
- /* successive loops, the array 'Filter' holds the union of all */
- /* non-redundant constraints. 'empty' is set to zero if the */
- /* intersection of two polyhedra is non-empty and Filter is !Null */
-
- if (SimplifyConstraints(p1, p2, Filter, NbMaxRays))
- empty=0;
- }
-
- if (!empty) {
-
- /* Copy all non-redundant constraints to matrix 'Constraints' */
- Constraints = Matrix_Alloc(NbConstraints,Dimension);
- if(!Constraints) {
- errormsg1("DomainSimplify", "outofmem", "out of memory space");
- UNCATCH(any_exception_error);
- return 0;
- }
- Constraints->NbRows = 0;
- for (k=0, jx=0, bx=MSB; k<NbConstraints; k++) {
-
- /* If a bit entry in Filter[jx] is marked 1, copy the correspond- */
- /* ing constraint in matrix 'Constraints'. */
- if (Filter[jx]&bx) {
- Vector_Copy(p1->Constraint[k],
- Constraints->p[Constraints->NbRows],
- Dimension);
- Constraints->NbRows++;
- }
- NEXT(jx,bx);
- }
-
- /* Create the polyhedron 'p3' corresponding to the constraints in */
- /* matrix 'Constraints'. */
- p3 = Constraints2Polyhedron(Constraints,NbMaxRays);
- Matrix_Free(Constraints), Constraints = NULL;
-
- /* Add polyhedron 'p3' in the domain 'd'. */
- d = AddPolyToDomain (p3, d);
- p3 = NULL;
- }
- free(Filter), Filter = NULL;
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- if (!d)
- return Empty_Polyhedron(Pol1->Dimension);
- else
- return d;
-} /* DomainSimplify */
-
-/*
- * Return the Union of two polyhedral domains 'Pol1' and Pol2'. The result is
- * a new polyhedral domain.
- */
-Polyhedron *DomainUnion(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
-
- Polyhedron *PolA, *PolEndA, *PolB, *PolEndB, *p1, *p2;
- int Redundant;
-
- if (!Pol1 || !Pol2) return (Polyhedron *) 0;
- if (Pol1->Dimension != Pol2->Dimension) {
- errormsg1("DomainUnion","diffdim","operation on different dimensions");
- return (Polyhedron*) 0;
- }
-
-
-
-
-
-
- /* Copy 'Pol1' to 'PolA' */
- PolA = PolEndA = (Polyhedron *)0;
- for (p1=Pol1; p1; p1=p1->next) {
-
- /* Does any component of 'Pol2' cover 'p1' ? */
- Redundant = 0;
- for (p2=Pol2; p2; p2=p2->next) {
- if (PolyhedronIncludes(p2, p1) ) { /* p2 covers p1 */
- Redundant = 1;
-
-
- break;
-
- }
- }
- if (!Redundant) {
-
- /* Add 'p1' to 'PolA' */
- if (!PolEndA)
- PolEndA = PolA = Polyhedron_Copy(p1);
- else {
- PolEndA->next = Polyhedron_Copy(p1);
- PolEndA = PolEndA->next;
- }
-
- }
- }
-
- /* Copy 'Pol2' to PolB */
- PolB = PolEndB = (Polyhedron *)0;
- for (p2=Pol2; p2; p2=p2->next) {
-
- /* Does any component of PolA cover 'p2' ? */
- Redundant = 0;
- for (p1=PolA; p1; p1=p1->next) {
- if (PolyhedronIncludes(p1, p2)) { /* p1 covers p2 */
- Redundant = 1;
- break;
- }
- }
- if (!Redundant) {
-
- /* Add 'p2' to 'PolB' */
- if (!PolEndB)
- PolEndB = PolB = Polyhedron_Copy(p2);
- else {
- PolEndB->next = Polyhedron_Copy(p2);
- PolEndB = PolEndB->next;
- }
-
-
- }
- }
-
- if (!PolA) return PolB;
- PolEndA->next = PolB;
- return PolA;
-} /* DomainUnion */
-
-/*
- * Given a polyhedral domain 'Pol', concatenate the lists of rays and lines
- * of the two (or more) polyhedra in the domain into one combined list, and
- * find the set of constraints which tightly bound all of those objects.
- * 'NbMaxConstrs' is the maximum allowed constraints in the new polyhedron.
- */
-Polyhedron *DomainConvex(Polyhedron *Pol,unsigned NbMaxConstrs) {
-
- Polyhedron *p, *q, *NewPol = NULL;
-
- CATCH(any_exception_error) {
- if (NewPol) Polyhedron_Free(NewPol);
- RETHROW();
- }
- TRY {
-
- if (!Pol) {
- UNCATCH(any_exception_error);
- return (Polyhedron*) 0;
- }
-
- POL_ENSURE_VERTICES(Pol);
- NewPol = Polyhedron_Copy(Pol);
- for (p=Pol->next; p; p=p->next) {
- POL_ENSURE_VERTICES(p);
- q = AddRays(p->Ray[0], p->NbRays, NewPol, NbMaxConstrs);
- Polyhedron_Free(NewPol);
- NewPol = q;
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
-
- return NewPol;
-} /* DomainConvex */
-
-/*
- * Given polyhedral domains 'Pol1' and 'Pol2', create a new polyhedral
- * domain which is mathematically the differnce of the two domains.
- */
-Polyhedron *DomainDifference(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
-
- Polyhedron *p1, *p2, *p3, *d;
- int i;
-
- if (!Pol1 || !Pol2) return (Polyhedron*) 0;
- if (Pol1->Dimension != Pol2->Dimension) {
- errormsg1("DomainDifference",
- "diffdim", "operation on different dimensions");
- return (Polyhedron*) 0;
- }
- POL_ENSURE_FACETS(Pol1);
- POL_ENSURE_VERTICES(Pol1);
- POL_ENSURE_FACETS(Pol2);
- POL_ENSURE_VERTICES(Pol2);
- if (emptyQ(Pol1) || emptyQ(Pol2))
- return (Domain_Copy(Pol1));
- d = (Polyhedron *)0;
- for (p2=Pol2; p2; p2=p2->next) {
- for (p1=Pol1; p1; p1=p1->next) {
- for (i=0; i<p2->NbConstraints; i++) {
-
- /* Add the constraint ( -p2->constraint[i] -1) >= 0 in 'p1' */
- /* and create the new polyhedron 'p3'. */
- p3 = SubConstraint(p2->Constraint[i], p1, NbMaxRays,0);
-
- /* Add 'p3' in the new domain 'd' */
- d = AddPolyToDomain (p3, d);
-
- /* If the constraint p2->constraint[i][0] is an equality, then */
- /* add the constraint ( +p2->constraint[i] -1) >= 0 in 'p1' and*/
- /* create the new polyhedron 'p3'. */
-
- if( value_notzero_p(p2->Constraint[i][0]) ) /* Inequality */
- continue;
- p3 = SubConstraint(p2->Constraint[i], p1, NbMaxRays,1);
-
- /* Add 'p3' in the new domain 'd' */
- d = AddPolyToDomain (p3, d);
- }
- }
- if (p2 != Pol2)
- Domain_Free(Pol1);
- Pol1 = d;
- d = (Polyhedron *)0;
- }
- if (!Pol1)
- return Empty_Polyhedron(Pol2->Dimension);
- else
- return Pol1;
-} /* DomainDifference */
-
-/*
- * Given a polyhedral domain 'Pol', convert it to a new polyhedral domain
- * with dimension expanded to 'align_dimension'. 'NbMaxRays' is the maximum
- * allowed rays in the new polyhedra.
- */
-Polyhedron *align_context(Polyhedron *Pol,int align_dimension,int NbMaxRays) {
-
- int i, j, k;
- Polyhedron *p = NULL, **next, *result = NULL;
- unsigned dim;
-
- CATCH(any_exception_error) {
- if (result) Polyhedron_Free(result);
- RETHROW();
- }
- TRY {
-
- if (!Pol) return Pol;
- dim = Pol->Dimension;
- if (align_dimension < Pol->Dimension) {
- errormsg1("align_context", "diffdim", "context dimension exceeds data");
- UNCATCH(any_exception_error);
- return NULL;
- }
- if (align_dimension == Pol->Dimension) {
- UNCATCH(any_exception_error);
- return Domain_Copy(Pol);
- }
-
- /* 'k' is the dimension increment */
- k = align_dimension - Pol->Dimension;
- next = &result;
-
- /* Expand the dimension of all polyhedra in the polyhedral domain 'Pol' */
- for (; Pol; Pol=Pol->next) {
- int have_cons = !F_ISSET(Pol, POL_VALID) || F_ISSET(Pol, POL_INEQUALITIES);
- int have_rays = !F_ISSET(Pol, POL_VALID) || F_ISSET(Pol, POL_POINTS);
- unsigned NbCons = have_cons ? Pol->NbConstraints : 0;
- unsigned NbRays = have_rays ? Pol->NbRays + k : 0;
-
- if (Pol->Dimension != dim) {
- Domain_Free(result);
- errormsg1("align_context", "diffdim", "context not of uniform dimension");
- UNCATCH(any_exception_error);
- return NULL;
- }
-
- p = Polyhedron_Alloc(align_dimension, NbCons, NbRays);
- if (have_cons) {
- for (i = 0; i < NbCons; ++i) {
- value_assign(p->Constraint[i][0], Pol->Constraint[i][0]); /* Status bit */
- Vector_Copy(Pol->Constraint[i]+1, p->Constraint[i]+k+1, Pol->Dimension+1);
- }
- p->NbEq = Pol->NbEq;
- }
-
- if (have_rays) {
- for (i = 0; i < k; ++i)
- value_set_si(p->Ray[i][1+i], 1); /* A line */
- for (i = 0; i < Pol->NbRays; ++i) {
- value_assign(p->Ray[k+i][0], Pol->Ray[i][0]); /* Status bit */
- Vector_Copy(Pol->Ray[i]+1, p->Ray[i+k]+k+1, Pol->Dimension+1);
- }
- p->NbBid = Pol->NbBid + k;
- }
- p->flags = Pol->flags;
-
- *next = p;
- next = &p->next;
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- return result;
-} /* align_context */
-
-/*----------------------------------------------------------------------*/
-/* Polyhedron *Polyhedron_Scan(D, C, NbMaxRays) */
-/* D : Domain to be scanned (single polyhedron only) */
-/* C : Context domain */
-/* NbMaxRays : Workspace size */
-/* Returns a linked list of scan domains, outer loop first */
-/*----------------------------------------------------------------------*/
-Polyhedron *Polyhedron_Scan(Polyhedron *D, Polyhedron *C,unsigned NbMaxRays) {
-
- int i, j, dim ;
- Matrix *Mat;
- Polyhedron *C1, *C2, *D1, *D2;
- Polyhedron *res, *last, *tmp;
-
- dim = D->Dimension - C->Dimension;
- res = last = (Polyhedron *) 0;
- if (dim==0) return (Polyhedron *)0;
-
- assert(!D->next);
-
- POL_ENSURE_FACETS(D);
- POL_ENSURE_VERTICES(D);
- POL_ENSURE_FACETS(C);
- POL_ENSURE_VERTICES(C);
-
- /* Allocate space for constraint matrix. */
- Mat = Matrix_Alloc(D->Dimension, D->Dimension+2);
- if(!Mat) {
- errormsg1("Polyhedron_Scan", "outofmem", "out of memory space");
- return 0;
- }
- C1 = align_context(C,D->Dimension,NbMaxRays);
- if(!C1) {
- return 0;
- }
- /* Vin100, aug 16, 2001: The context is intersected with D */
- D2 = DomainIntersection( C1, D, NbMaxRays);
-
- for (i=0; i<dim; i++)
- {
- Vector_Set(Mat->p_Init,0,D2->Dimension*(D2->Dimension + 2));
- for (j=i+1; j<dim; j++) {
- value_set_si(Mat->p[j-i-1][j+1],1);
- }
- Mat->NbRows = dim-i-1;
- D1 = Mat->NbRows ? DomainAddRays(D2, Mat, NbMaxRays) : D2;
- tmp = DomainSimplify(D1, C1, NbMaxRays);
- if (!last) res = last = tmp;
- else { last->next = tmp; last = tmp; }
- C2 = DomainIntersection(C1, D1, NbMaxRays);
- Domain_Free(C1);
- C1 = C2;
- if (Mat->NbRows) Domain_Free(D1);
- }
- Domain_Free(D2);
- Domain_Free(C1);
- Matrix_Free(Mat);
- return res;
-} /* Polyhedron_Scan */
-
-/*---------------------------------------------------------------------*/
-/* int lower_upper_bounds(pos,P,context,LBp,UBp) */
-/* pos : index position of current loop index (1..hdim-1) */
-/* P: loop domain */
-/* context : context values for fixed indices */
-/* notice that context[hdim] must be 1 */
-/* LBp, UBp : pointers to resulting bounds */
-/* returns the flag = (UB_INFINITY, LB_INFINITY) */
-/*---------------------------------------------------------------------*/
-int lower_upper_bounds(int pos,Polyhedron *P,Value *context,Value *LBp,Value *UBp) {
-
- Value LB, UB;
- int flag, i;
- Value n, n1, d, tmp;
-
- POL_ENSURE_FACETS(P);
- POL_ENSURE_VERTICES(P);
-
- /* Initialize all the 'Value' variables */
- value_init(LB); value_init(UB); value_init(tmp);
- value_init(n); value_init(n1); value_init(d);
-
- value_set_si(LB,0);
- value_set_si(UB,0);
-
- /* Compute Upper Bound and Lower Bound for current loop */
- flag = LB_INFINITY | UB_INFINITY;
- for (i=0; i<P->NbConstraints; i++) {
- value_assign(d,P->Constraint[i][pos]);
- Inner_Product(&context[1],&(P->Constraint[i][1]),P->Dimension+1,&n);
- if (value_zero_p(d)) {
- /* If context doesn't satisfy constraints, return empty loop. */
- if (value_neg_p(n) ||
- (value_zero_p(P->Constraint[i][0]) && value_notzero_p(n)))
- goto empty_loop;
- continue;
- }
- value_oppose(n,n);
-
- /*---------------------------------------------------*/
- /* Compute n/d n/d<0 n/d>0 */
- /*---------------------------------------------------*/
- /* n%d == 0 floor = n/d floor = n/d */
- /* ceiling = n/d ceiling = n/d */
- /*---------------------------------------------------*/
- /* n%d != 0 floor = n/d - 1 floor = n/d */
- /* ceiling = n/d ceiling = n/d + 1 */
- /*---------------------------------------------------*/
-
- /* Check to see if constraint is inequality */
- /* if constraint is equality, both upper and lower bounds are fixed */
- if(value_zero_p(P->Constraint[i][0])) { /* Equality */
- value_modulus(tmp,n,d);
-
- /* if not integer, return 0; */
- if (value_notzero_p(tmp))
- goto empty_loop;
-
- value_division(n1,n,d);
-
- /* Upper and Lower bounds found */
- if((flag&LB_INFINITY) || value_gt(n1,LB))
- value_assign(LB,n1);
- if((flag&UB_INFINITY) || value_lt(n1,UB))
- value_assign(UB,n1);
- flag = 0;
- }
-
- if (value_pos_p(d)) { /* Lower Bound */
- value_modulus(tmp,n,d);
-
- /* n1 = ceiling(n/d) */
- if (value_pos_p(n) && value_notzero_p(tmp)) {
- value_division(n1,n,d);
- value_add_int(n1,n1,1);
- }
- else
- value_division(n1,n,d);
- if (flag&LB_INFINITY) {
- value_assign(LB,n1);
- flag^=LB_INFINITY;
- }
- else if(value_gt(n1,LB))
- value_assign(LB,n1);
- }
-
- if (value_neg_p(d)) { /* Upper Bound */
- value_modulus(tmp,n,d);
-
- /* n1 = floor(n/d) */
- if (value_pos_p(n) && value_notzero_p(tmp)) {
- value_division(n1,n,d);
- value_sub_int(n1,n1,1);
- }
- else
- value_division(n1,n,d);
-
- if (flag&UB_INFINITY) {
- value_assign(UB,n1);
- flag^=UB_INFINITY;
- }
- else if (value_lt(n1,UB))
- value_assign(UB, n1);
- }
- }
- if ((flag & LB_INFINITY)==0) value_assign(*LBp,LB);
- if ((flag & UB_INFINITY)==0) value_assign(*UBp,UB);
-
- if (0) {
-empty_loop:
- flag = 0;
- value_set_si(*LBp, 1);
- value_set_si(*UBp, 0); /* empty loop */
- }
-
- /* Clear all the 'Value' variables */
- value_clear(LB); value_clear(UB); value_clear(tmp);
- value_clear(n); value_clear(n1); value_clear(d);
- return flag;
-} /* lower_upper_bounds */
-
-/*
- * C = A x B
- */
-static void Rays_Mult(Value **A, Matrix *B, Value **C, unsigned NbRays)
-{
- int i, j, k;
- unsigned Dimension1, Dimension2;
- Value Sum, tmp;
-
- value_init(Sum); value_init(tmp);
-
- CATCH(any_exception_error) {
- value_clear(Sum); value_clear(tmp);
- RETHROW();
- }
- TRY {
- Dimension1 = B->NbRows;
- Dimension2 = B->NbColumns;
-
- for (i=0; i<NbRays; i++) {
- value_assign(C[i][0],A[i][0]);
- for (j=0; j<Dimension2; j++) {
- value_set_si(Sum,0);
- for (k=0; k<Dimension1; k++) {
-
- /* Sum+=A[i][k+1] * B->p[k][j]; */
- value_addmul(Sum, A[i][k+1], B->p[k][j]);
- }
- value_assign(C[i][j+1],Sum);
- }
- Vector_Gcd(C[i]+1, Dimension2, &tmp);
- if (value_notone_p(tmp))
- Vector_AntiScale(C[i]+1, C[i]+1, tmp, Dimension2);
- }
- }
- UNCATCH(any_exception_error);
- value_clear(Sum); value_clear(tmp);
-}
-
-/*
- * C = A x B^T
- */
-static void Rays_Mult_Transpose(Value **A, Matrix *B, Value **C,
- unsigned NbRays)
-{
- int i, j, k;
- unsigned Dimension1, Dimension2;
- Value Sum, tmp;
-
- value_init(Sum); value_init(tmp);
-
- CATCH(any_exception_error) {
- value_clear(Sum); value_clear(tmp);
- RETHROW();
- }
- TRY {
- Dimension1 = B->NbColumns;
- Dimension2 = B->NbRows;
-
- for (i=0; i<NbRays; i++) {
- value_assign(C[i][0],A[i][0]);
- for (j=0; j<Dimension2; j++) {
- value_set_si(Sum,0);
- for (k=0; k<Dimension1; k++) {
-
- /* Sum+=A[i][k+1] * B->p[j][k]; */
- value_addmul(Sum, A[i][k+1], B->p[j][k]);
- }
- value_assign(C[i][j+1],Sum);
- }
- Vector_Gcd(C[i]+1, Dimension2, &tmp);
- if (value_notone_p(tmp))
- Vector_AntiScale(C[i]+1, C[i]+1, tmp, Dimension2);
- }
- }
- UNCATCH(any_exception_error);
- value_clear(Sum); value_clear(tmp);
-}
-
-/*
- * Given a polyhedron 'Pol' and a transformation matrix 'Func', return the
- * polyhedron which when transformed by mapping function 'Func' gives 'Pol'.
- * 'NbMaxRays' is the maximum number of rays that can be in the ray matrix
- * of the resulting polyhedron.
- */
-Polyhedron *Polyhedron_Preimage(Polyhedron *Pol,Matrix *Func,unsigned NbMaxRays) {
-
- Matrix *Constraints = NULL;
- Polyhedron *NewPol = NULL;
- unsigned NbConstraints, Dimension1, Dimension2;
-
- POL_ENSURE_INEQUALITIES(Pol);
-
- CATCH(any_exception_error) {
- if (Constraints) Matrix_Free(Constraints);
- if (NewPol) Polyhedron_Free(NewPol);
- RETHROW();
- }
- TRY {
-
- NbConstraints = Pol->NbConstraints;
- Dimension1 = Pol->Dimension+1; /* Homogeneous Dimension */
- Dimension2 = Func->NbColumns; /* Homogeneous Dimension */
- if (Dimension1!=(Func->NbRows)) {
- errormsg1("Polyhedron_Preimage", "dimincomp", "incompatable dimensions");
- UNCATCH(any_exception_error);
- return Empty_Polyhedron(Dimension2-1);
- }
-
- /* Dim1 Dim2 Dim2
- __k__ __j__ __j__
- NbCon | | X Dim1| | = NbCon | |
- i |___| k |___| i |___|
- Pol->Constraints Function Constraints
- */
-
- /* Allocate space for the resulting constraint matrix */
- Constraints = Matrix_Alloc(NbConstraints, Dimension2+1);
- if (!Constraints) {
- errormsg1("Polyhedron_Preimage", "outofmem", "out of memory space\n");
- Pol_status = 1;
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* The new constraint matrix is the product of constraint matrix of the */
- /* polyhedron and the function matrix. */
- Rays_Mult(Pol->Constraint, Func, Constraints->p, NbConstraints);
- NewPol = Constraints2Polyhedron(Constraints, NbMaxRays);
- Matrix_Free(Constraints), Constraints = NULL;
-
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
-
- return NewPol;
-} /* Polyhedron_Preimage */
-
-/*
- * Given a polyhedral domain 'Pol' and a transformation matrix 'Func', return
- * the polyhedral domain which when transformed by mapping function 'Func'
- * gives 'Pol'. 'NbMaxRays' is the maximum number of rays that can be in the
- * ray matrix of the resulting domain.
- */
-Polyhedron *DomainPreimage(Polyhedron *Pol,Matrix *Func,unsigned NbMaxRays) {
-
- Polyhedron *p, *q, *d = NULL;
-
- CATCH(any_exception_error) {
- if (d) Polyhedron_Free(d);
- RETHROW();
- }
- TRY {
- if (!Pol || !Func) {
- UNCATCH(any_exception_error);
- return (Polyhedron *) 0;
- }
- d = (Polyhedron *) 0;
- for (p=Pol; p; p=p->next) {
- q = Polyhedron_Preimage(p, Func, NbMaxRays);
- d = AddPolyToDomain (q, d);
- }
- } /* end of TRY */
- UNCATCH(any_exception_error);
- return d;
-} /* DomainPreimage */
-
-/*
- * Transform a polyhedron 'Pol' into another polyhedron according to a given
- * affine mapping function 'Func'. 'NbMaxConstrs' is the maximum number of
- * constraints that can be in the constraint matrix of the new polyhedron.
- */
-Polyhedron *Polyhedron_Image(Polyhedron *Pol, Matrix *Func,unsigned NbMaxConstrs) {
-
- Matrix *Rays = NULL;
- Polyhedron *NewPol = NULL;
- unsigned NbRays, Dimension1, Dimension2;
-
- POL_ENSURE_FACETS(Pol);
- POL_ENSURE_VERTICES(Pol);
-
- CATCH(any_exception_error) {
- if (Rays) Matrix_Free(Rays);
- if (NewPol) Polyhedron_Free(NewPol);
- RETHROW();
- }
- TRY {
-
- NbRays = Pol->NbRays;
- Dimension1 = Pol->Dimension+1; /* Homogeneous Dimension */
- Dimension2 = Func->NbRows; /* Homogeneous Dimension */
- if (Dimension1!=Func->NbColumns) {
- errormsg1("Polyhedron_Image", "dimincomp", "incompatible dimensions");
- UNCATCH(any_exception_error);
- return Empty_Polyhedron(Dimension2-1);
- }
-
- /*
- Dim1 / Dim1 \Transpose Dim2
- __k__ | __k__ | __j__
- NbRays| | X | Dim2 | | | = NbRays| |
- i |___| | j |___| | i |___|
- Pol->Rays \ Func / Rays
-
- */
-
- if (Dimension1 == Dimension2) {
- Matrix *M, *M2;
- int ok;
- M = Matrix_Copy(Func);
- M2 = Matrix_Alloc(Dimension2, Dimension1);
- if (!M2) {
- errormsg1("Polyhedron_Image", "outofmem", "out of memory space\n");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- ok = Matrix_Inverse(M, M2);
- Matrix_Free(M);
- if (ok) {
- NewPol = Polyhedron_Alloc(Pol->Dimension, Pol->NbConstraints,
- Pol->NbRays);
- if (!NewPol) {
- errormsg1("Polyhedron_Image", "outofmem",
- "out of memory space\n");
- UNCATCH(any_exception_error);
- return 0;
- }
- Rays_Mult_Transpose(Pol->Ray, Func, NewPol->Ray, NbRays);
- Rays_Mult(Pol->Constraint, M2, NewPol->Constraint,
- Pol->NbConstraints);
- NewPol->NbEq = Pol->NbEq;
- NewPol->NbBid = Pol->NbBid;
- if (NewPol->NbEq)
- Gauss4(NewPol->Constraint, NewPol->NbEq, NewPol->NbConstraints,
- NewPol->Dimension+1);
- if (NewPol->NbBid)
- Gauss4(NewPol->Ray, NewPol->NbBid, NewPol->NbRays,
- NewPol->Dimension+1);
- }
- Matrix_Free(M2);
- }
-
- if (!NewPol) {
- /* Allocate space for the resulting ray matrix */
- Rays = Matrix_Alloc(NbRays, Dimension2+1);
- if (!Rays) {
- errormsg1("Polyhedron_Image", "outofmem", "out of memory space\n");
- UNCATCH(any_exception_error);
- return 0;
- }
-
- /* The new ray space is the product of ray matrix of the polyhedron and */
- /* the transpose matrix of the mapping function. */
- Rays_Mult_Transpose(Pol->Ray, Func, Rays->p, NbRays);
- NewPol = Rays2Polyhedron(Rays, NbMaxConstrs);
- Matrix_Free(Rays), Rays = NULL;
- }
-
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- return NewPol;
-} /* Polyhedron_Image */
-
-/*
- *Transform a polyhedral domain 'Pol' into another domain according to a given
- * affine mapping function 'Func'. 'NbMaxConstrs' is the maximum number of
- * constraints that can be in the constraint matrix of the resulting domain.
- */
-Polyhedron *DomainImage(Polyhedron *Pol,Matrix *Func,unsigned NbMaxConstrs) {
-
- Polyhedron *p, *q, *d = NULL;
-
- CATCH(any_exception_error) {
- if (d) Polyhedron_Free(d);
- RETHROW();
- }
- TRY {
-
- if (!Pol || !Func) {
- UNCATCH(any_exception_error);
- return (Polyhedron *) 0;
- }
- d = (Polyhedron *) 0;
- for (p=Pol; p; p=p->next) {
- q = Polyhedron_Image(p, Func, NbMaxConstrs);
- d = AddPolyToDomain (q, d);
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
-
- return d;
-} /* DomainImage */
-
-/*
- * Given a polyhedron 'Pol' and an affine cost function 'Cost', compute the
- * maximum and minimum value of the function over set of points representing
- * polyhedron.
- * Note: If Polyhedron 'Pol' is empty, then there is no feasible solution.
- * Otherwise, if there is a bidirectional ray with Sum[cost(i)*ray(i)] != 0 or
- * a unidirectional ray with Sum[cost(i)*ray(i)] >0, then the maximum is un-
- * bounded else the finite optimal solution occurs at one of the vertices of
- * the polyhderon.
- */
-Interval *DomainCost(Polyhedron *Pol,Value *Cost) {
-
- int i, j, NbRay, Dim;
- Value *p1, *p2, p3, d, status;
- Value tmp1, tmp2, tmp3;
- Value **Ray;
- Interval *I = NULL;
-
- value_init(p3); value_init(d); value_init(status);
- value_init(tmp1); value_init(tmp2); value_init(tmp3);
-
- POL_ENSURE_FACETS(Pol);
- POL_ENSURE_VERTICES(Pol);
-
- CATCH(any_exception_error) {
- if (I) free(I);
- RETHROW();
- value_clear(p3); value_clear(d); value_clear(status);
- value_clear(tmp1); value_clear(tmp2); value_clear(tmp3);
- }
- TRY {
-
- Ray = Pol->Ray;
- NbRay = Pol->NbRays;
- Dim = Pol->Dimension+1; /* Homogenous Dimension */
- I = (Interval *) malloc (sizeof(Interval));
- if (!I) {
- errormsg1("DomainCost", "outofmem", "out of memory space\n");
- UNCATCH(any_exception_error);
- value_clear(p3); value_clear(d); value_clear(status);
- value_clear(tmp1); value_clear(tmp2); value_clear(tmp3);
- return 0;
- }
-
- /* The maximum and minimum values of the cost function over polyhedral */
- /* domain is stored in 'I'. I->MaxN and I->MaxD store the numerator and */
- /* denominator of the maximum value. Likewise,I->MinN and I->MinD store */
- /* the numerator and denominator of the minimum value. I->MaxI and */
- /* I->MinI store the ray indices corresponding to the max and min values*/
- /* of the function. */
-
- value_set_si(I->MaxN,-1);
- value_set_si(I->MaxD,0); /* Actual cost is MaxN/MaxD */
- I->MaxI = -1;
- value_set_si(I->MinN,1);
- value_set_si(I->MinD,0);
- I->MinI = -1;
-
- /* Compute the cost of each ray[i] */
- for (i=0; i<NbRay; i++) {
- p1 = Ray[i];
- value_assign(status, *p1);
- p1++;
- p2 = Cost;
-
- /* p3 = *p1++ * *p2++; */
- value_multiply(p3,*p1,*p2);
- p1++; p2++;
- for (j=1; j<Dim; j++) {
- value_multiply(tmp1,*p1,*p2);
-
- /* p3 += *p1++ * *p2++; */
- value_addto(p3,p3,tmp1);
- p1++; p2++;
- }
-
- /* d = *--p1; */
- p1--;
- value_assign(d,*p1); /* d == 0 for lines and ray, non-zero for vertex */
- value_multiply(tmp1,p3,I->MaxD);
- value_multiply(tmp2,I->MaxN,d);
- value_set_si(tmp3,1);
-
- /* Compare p3/d with MaxN/MaxD to assign new maximum cost value */
- if (I->MaxI==-1 ||
- value_gt(tmp1,tmp2) ||
- (value_eq(tmp1,tmp2) &&
- value_eq(d,tmp3) && value_ne(I->MaxD,tmp3))) {
- value_assign(I->MaxN,p3);
- value_assign(I->MaxD,d);
- I->MaxI = i;
- }
- value_multiply(tmp1,p3,I->MinD);
- value_multiply(tmp2,I->MinN,d);
- value_set_si(tmp3,1);
-
- /* Compare p3/d with MinN/MinD to assign new minimum cost value */
- if (I->MinI==-1 ||
- value_lt(tmp1,tmp2) ||
- (value_eq(tmp1,tmp2) &&
- value_eq(d,tmp3) && value_ne(I->MinD,tmp3))) {
- value_assign(I->MinN, p3);
- value_assign(I->MinD, d);
- I->MinI = i;
- }
- value_multiply(tmp1,p3,I->MaxD);
- value_set_si(tmp2,0);
-
- /* If there is a line, assign max to +infinity and min to -infinity */
- if (value_zero_p(status)) { /* line , d is 0 */
- if (value_lt(tmp1,tmp2)) {
- value_oppose(I->MaxN,p3);
- value_set_si(I->MaxD,0);
- I->MaxI = i;
- }
- value_multiply(tmp1,p3,I->MinD);
- value_set_si(tmp2,0);
-
- if (value_gt(tmp1,tmp2)) {
- value_oppose(I->MinN,p3);
- value_set_si(I->MinD,0);
- I->MinI = i;
- }
- }
- }
- } /* end of TRY */
-
- UNCATCH(any_exception_error);
- value_clear(p3); value_clear(d); value_clear(status);
- value_clear(tmp1); value_clear(tmp2); value_clear(tmp3);
- return I;
-} /* DomainCost */
-
-/*
- * Add constraints pointed by 'Mat' to each and every polyhedron in the
- * polyhedral domain 'Pol'. 'NbMaxRays' is maximum allowed rays in the ray
- * matrix of a polyhedron.
- */
-Polyhedron *DomainAddConstraints(Polyhedron *Pol,Matrix *Mat,unsigned NbMaxRays) {
-
- Polyhedron *PolA, *PolEndA, *p1, *p2, *p3;
- int Redundant;
-
- if (!Pol) return (Polyhedron*) 0;
- if (!Mat) return Pol;
- if (Pol->Dimension != Mat->NbColumns-2) {
- errormsg1("DomainAddConstraints",
- "diffdim", "operation on different dimensions");
- return (Polyhedron*) 0;
- }
-
- /* Copy 'Pol' to 'PolA' */
- PolA = PolEndA = (Polyhedron *)0;
- for (p1=Pol; p1; p1=p1->next) {
- p3 = AddConstraints(Mat->p_Init, Mat->NbRows, p1, NbMaxRays);
-
- /* Does any component of 'PolA' cover 'p3' */
- Redundant = 0;
- for (p2=PolA; p2; p2=p2->next) {
- if (PolyhedronIncludes(p2, p3)) { /* 'p2' covers 'p3' */
- Redundant = 1;
- break;
- }
- }
-
- /* If the new polyhedron 'p3' is not redundant, add it to the domain */
- if (Redundant)
- Polyhedron_Free(p3);
- else {
- if (!PolEndA)
- PolEndA = PolA = p3;
- else {
- PolEndA->next = p3;
- PolEndA = PolEndA->next;
- }
- }
- }
- return PolA;
-} /* DomainAddConstraints */
-
-
-/*
- * Computes the disjoint union of a union of polyhedra.
- * If flag = 0 the result is such that there are no intersections
- * between the resulting polyhedra,
- * if flag = 1 it computes a joint union, the resulting polyhedra are
- * adjacent (they have their facets in common).
- *
- * WARNING: if all polyhedra are not of same geometrical dimension
- * duplicates may appear.
- */
-Polyhedron *Disjoint_Domain( Polyhedron *P, int flag, unsigned NbMaxRays )
-{
- Polyhedron *lP, *tmp, *Result, *lR, *prec, *reste;
- Polyhedron *p1, *p2, *p3, *Pol1, *dx, *d1, *d2, *pi, *newpi;
- int i;
-
- if( flag!=0 && flag!=1 )
- {
- errormsg1("Disjoint_Domain",
- "invalidarg", "flag should be equal to 0 or 1");
- return (Polyhedron*) 0;
- }
- if(!P) return (Polyhedron*) 0;
- if(!P->next) return Polyhedron_Copy(P);
-
- Result = (Polyhedron *)0;
-
- for(lP=P;lP;lP=lP->next)
- {
- reste = Polyhedron_Copy(lP);
- prec = (Polyhedron *)0; /* preceeding lR */
- /* Intersection with each polyhedron of the current Result */
- lR=Result;
- while( lR && reste )
- {
- /* dx = DomainIntersection(reste,lR->P,WS); */
- dx = (Polyhedron *)0;
- for( p1=reste; p1; p1=p1->next )
- {
- p3 = AddConstraints(lR->Constraint[0], lR->NbConstraints, p1,
- NbMaxRays);
- dx = AddPolyToDomain(p3,dx);
- }
-
- /* if empty intersection, continue */
- if(!dx)
- { prec = lR;
- lR=lR->next;
- continue;
- }
- if (emptyQ(dx)) {
- Domain_Free(dx);
- prec = lR;
- lR=lR->next;
- continue;
- }
-
- /* intersection is not empty, we need to compute the differences */
- /* between the intersection and the two polyhedra, such that the */
- /* results are disjoint unions (according to flag) */
- /* d1 = reste \ P = DomainDifference(reste,lR->P,WS); */
- /* d2 = P \ reste = DomainDifference(lR->P,reste,WS); */
-
- /* compute d1 */
- d1 = (Polyhedron *)0;
- for (p1=reste; p1; p1=p1->next)
- {
- pi = p1;
- for (i=0; i<P->NbConstraints && pi ; i++)
- {
-
- /* Add the constraint ( -P->constraint[i] [-1 if flag=0]) >= 0 in 'p1' */
- /* and create the new polyhedron 'p3'. */
- p3 = SubConstraint(P->Constraint[i], pi, NbMaxRays,2*flag);
- /* Add 'p3' in the new domain 'd1' */
- d1 = AddPolyToDomain (p3, d1);
-
- /* If the constraint P->constraint[i][0] is an equality, then add */
- /* the constraint ( +P->constraint[i] [-1 if flag=0]) >= 0 in 'pi' */
- /* and create the new polyhedron 'p3'. */
- if( value_zero_p(P->Constraint[i][0]) ) /* Inequality */
- {
- p3 = SubConstraint(P->Constraint[i], pi, NbMaxRays,1+2*flag);
- /* Add 'p3' in the new domain 'd1' */
- d1 = AddPolyToDomain (p3, d1);
-
- /* newpi : add constraint P->constraint[i]==0 to pi */
- newpi = AddConstraints( P->Constraint[i], 1, pi, NbMaxRays);
- }
- else
- {
- /* newpi : add constraint +P->constraint[i] >= 0 in pi */
- newpi = SubConstraint(P->Constraint[i], pi, NbMaxRays,3);
- }
- if( newpi && emptyQ( newpi ) )
- {
- Domain_Free( newpi );
- newpi = (Polyhedron *)0;
- }
- if( pi != p1 )
- Domain_Free( pi );
- pi = newpi;
- }
- if( pi != p1 )
- Domain_Free( pi );
- }
-
- /* and now d2 */
- Pol1 = Polyhedron_Copy( lR );
- for (p2=reste; p2; p2=p2->next)
- {
- d2 = (Polyhedron *)0;
- for (p1=Pol1; p1; p1=p1->next)
- {
- pi = p1;
- for (i=0; i<p2->NbConstraints && pi ; i++)
- {
-
- /* Add the constraint ( -p2->constraint[i] [-1 if flag=0]) >= 0 in 'pi' */
- /* and create the new polyhedron 'p3'. */
- p3 = SubConstraint(p2->Constraint[i], pi, NbMaxRays,2*flag);
- /* Add 'p3' in the new domain 'd2' */
- d2 = AddPolyToDomain (p3, d2);
-
- /* If the constraint p2->constraint[i][0] is an equality, then add */
- /* the constraint ( +p2->constraint[i] [-1 if flag=0]) >= 0 in 'pi' */
- /* and create the new polyhedron 'p3'. */
- if( value_zero_p(p2->Constraint[i][0]) ) /* Inequality */
- {
- p3 = SubConstraint(p2->Constraint[i], pi, NbMaxRays,1+2*flag);
- /* Add 'p3' in the new domain 'd2' */
- d2 = AddPolyToDomain (p3, d2);
-
- /* newpi : add constraint p2->constraint[i]==0 to pi */
- newpi = AddConstraints( p2->Constraint[i], 1, pi, NbMaxRays);
- }
- else
- {
- /* newpi : add constraint +p2->constraint[i] >= 0 in pi */
- newpi = SubConstraint(p2->Constraint[i], pi, NbMaxRays,3);
- }
- if( newpi && emptyQ( newpi ) )
- {
- Domain_Free( newpi );
- newpi = (Polyhedron *)0;
- }
- if( pi != p1 )
- Domain_Free( pi );
- pi = newpi;
- }
- if( pi && pi!=p1 )
- Domain_Free( pi );
- }
- if( Pol1 )
- Domain_Free( Pol1 );
- Pol1 = d2;
- }
- /* ok, d1 and d2 are computed */
-
- /* now, replace lR by d2+dx (at least dx is nonempty) and set reste to d1 */
- if( d1 && emptyQ(d1) )
- {
- Domain_Free( d1 );
- d1 = NULL;
- }
- if( d2 && emptyQ(d2) )
- {
- Domain_Free( d2 );
- d2 = NULL;
- }
-
- /* set reste */
- Domain_Free( reste );
- reste = d1;
-
- /* add d2 at beginning of Result */
- if( d2 )
- {
- for( tmp=d2 ; tmp->next ; tmp=tmp->next )
- ;
- tmp->next = Result;
- Result = d2;
- if( !prec )
- prec = tmp;
- }
-
- /* add dx at beginning of Result */
- for( tmp=dx ; tmp->next ; tmp=tmp->next )
- ;
- tmp->next = Result;
- Result = dx;
- if( !prec )
- prec = tmp;
-
- /* suppress current lR */
- if( !prec )
- errormsg1( "Disjoint_Domain","internalerror","internal error");
- prec->next = lR->next;
- Polyhedron_Free( lR );
- lR = prec->next;
- } /* end for result */
-
- /* if there is something left, add it to Result : */
- if(reste)
- {
- if(emptyQ(reste))
- {
- Domain_Free( reste );
- reste = NULL;
- }
- else
- {
- Polyhedron *tnext;
- for( tmp=reste ; tmp ; tmp=tnext )
- {
- tnext = tmp->next;
- tmp->next = NULL;
- Result = AddPolyToDomain(tmp, Result);
- }
- }
- }
- }
-
- return( Result );
-}
-
-
-
-/* Procedure to print constraint matrix of a polyhedron */
-void Polyhedron_PrintConstraints(FILE *Dst, const char *Format, Polyhedron *Pol)
-{
- int i,j;
-
- fprintf( Dst, "%d %d\n", Pol->NbConstraints, Pol->Dimension+2 );
- for( i=0 ; i<Pol->NbConstraints ; i++ )
- {
- for( j=0 ; j<Pol->Dimension+2 ; j++ )
- value_print( Dst, Format, Pol->Constraint[i][j] );
- fprintf( Dst, "\n" );
- }
-
-}
-
-/* Procedure to print constraint matrix of a domain */
-void Domain_PrintConstraints(FILE *Dst, const char *Format, Polyhedron *Pol)
-{
- Polyhedron *Q;
- for (Q = Pol; Q; Q = Q->next)
- Polyhedron_PrintConstraints(Dst, Format, Q);
-}
-
-static Polyhedron *p_simplify_constraints(Polyhedron *P, Vector *row,
- Value *g, unsigned MaxRays)
-{
- Polyhedron *T, *R = P;
- int len = P->Dimension+2;
- int r;
-
- /* Also look at equalities.
- * If an equality can be "simplified" then there
- * are no integer solutions and we return an empty polyhedron
- */
- for (r = 0; r < R->NbConstraints; ++r) {
- if (ConstraintSimplify(R->Constraint[r], row->p, len, g)) {
- T = R;
- if (value_zero_p(R->Constraint[r][0])) {
- R = Empty_Polyhedron(R->Dimension);
- r = R->NbConstraints;
- } else if (POL_ISSET(MaxRays, POL_NO_DUAL)) {
- R = Polyhedron_Copy(R);
- F_CLR(R, POL_FACETS | POL_VERTICES | POL_POINTS);
- Vector_Copy(row->p+1, R->Constraint[r]+1, R->Dimension+1);
- } else {
- R = AddConstraints(row->p, 1, R, MaxRays);
- r = -1;
- }
- if (T != P)
- Polyhedron_Free(T);
- }
- }
- if (R != P)
- Polyhedron_Free(P);
- return R;
-}
-
-/*
- * Replaces constraint a x >= c by x >= ceil(c/a)
- * where "a" is a common factor in the coefficients
- * Destroys P and returns a newly allocated Polyhedron
- * or just returns P in case no changes were made
- */
-Polyhedron *DomainConstraintSimplify(Polyhedron *P, unsigned MaxRays)
-{
- Polyhedron **prev;
- int len = P->Dimension+2;
- Vector *row = Vector_Alloc(len);
- Value g;
- Polyhedron *R = P, *N;
- value_set_si(row->p[0], 1);
- value_init(g);
-
- for (prev = &R; P; P = N) {
- Polyhedron *T;
- N = P->next;
- T = p_simplify_constraints(P, row, &g, MaxRays);
-
- if (emptyQ(T) && prev != &R) {
- Polyhedron_Free(T);
- *prev = NULL;
- continue;
- }
-
- if (T != P)
- T->next = N;
- *prev = T;
- prev = &T->next;
- }
-
- if (R->next && emptyQ(R)) {
- N = R->next;
- Polyhedron_Free(R);
- R = N;
- }
-
- value_clear(g);
- Vector_Free(row);
- return R;
-}
diff --git a/source/polylib_mod/polylib/Lattice.h b/source/polylib_mod/polylib/Lattice.h
deleted file mode 100644
index 5e1c702..0000000
--- a/source/polylib_mod/polylib/Lattice.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _Lattice_h_
-#define _Lattice_h_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void AffineHermite ( Lattice *A, Lattice **H, Matrix **U );
-extern void AffineSmith ( Lattice *A, Lattice **U, Lattice **V, Lattice
- **Diag );
-extern Lattice *ChangeLatticeDimension ( Lattice *A, int dimension );
-extern Lattice *EmptyLattice ( int dimension );
-extern Lattice *ExtractLinearPart ( Lattice *A );
-extern int FindHermiteBasisofDomain ( Polyhedron *A, Matrix **B );
-extern Lattice *Homogenise ( Lattice *A, Bool Forward );
-extern int intcompare ( const void *a, const void *b );
-extern Bool isEmptyLattice ( Lattice *A );
-extern Bool isfulldim ( Matrix *m );
-extern Bool IsLattice ( Matrix *m );
-extern Bool isLinear ( Lattice *A );
-extern LatticeUnion *LatticeDifference ( Lattice *A, Lattice *B );
-extern Lattice *LatticeImage ( Lattice *A, Matrix *M );
-extern Bool LatticeIncludes ( Lattice *A, Lattice *B );
-extern Lattice *LatticeIntersection ( Lattice *X, Lattice *Y );
-extern Lattice *LatticePreimage ( Lattice *L, Matrix *G );
-extern LatticeUnion *LatticeSimplify ( LatticeUnion *latlist );
-extern LatticeUnion *LatticeUnion_Alloc ( void );
-extern void LatticeUnion_Free ( LatticeUnion *Head );
-extern void PrintLatticeUnion ( FILE *fp, char *format, LatticeUnion
- *Head );
-extern Bool sameAffinepart ( Lattice *A, Lattice *B );
-extern Bool sameLattice ( Lattice *A, Lattice *B );
-extern LatticeUnion *Lattice2LatticeUnion(Lattice *X,Lattice *Y);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _Lattice_h_ */
diff --git a/source/polylib_mod/polylib/Matop.h b/source/polylib_mod/polylib/Matop.h
deleted file mode 100644
index b2d9733..0000000
--- a/source/polylib_mod/polylib/Matop.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _Matop_h_
-#define _Matop_h_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* computes c = lcm(a,b) using Gcd(a,b,&c) */
-extern void Lcm3(Value a, Value b, Value *c);
-extern Matrix *AddANullColumn ( Matrix *M );
-extern Matrix *AddANullRow ( Matrix *M );
-extern void ExchangeColumns ( Matrix *M, int Column1, int Column2 );
-extern void ExchangeRows ( Matrix *M, int Row1, int Row2 );
-extern int findHermiteBasis ( Matrix *M, Matrix **Result );
-extern Matrix *Identity ( unsigned size );
-extern Bool isinHnf ( Matrix *A );
-extern Bool isIntegral ( Matrix *A );
-extern Value *Lcm (Value i, Value j);
-extern Matrix *Matrix_Copy(Matrix const *Src);
-extern void PutColumnFirst ( Matrix *X, int Columnnumber );
-extern void PutColumnLast ( Matrix *X, int Columnnumber );
-extern void PutRowFirst ( Matrix *X, int Rownumber );
-extern void PutRowLast ( Matrix *X, int Rownumber );
-extern Matrix *RemoveNColumns ( Matrix *M, int FirstColumnnumber, int NumColumns );
-extern Matrix *RemoveColumn ( Matrix *M, int Columnnumber );
-extern Matrix *RemoveRow ( Matrix *M, int Rownumber );
-extern Matrix *Transpose ( Matrix *A );
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _Matop_h_ */
diff --git a/source/polylib_mod/polylib/NormalForms.h b/source/polylib_mod/polylib/NormalForms.h
deleted file mode 100644
index 9e01196..0000000
--- a/source/polylib_mod/polylib/NormalForms.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void Smith(Matrix *A, Matrix **U, Matrix **V, Matrix **Product);
-extern void Hermite(Matrix *A, Matrix **H, Matrix **U);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/source/polylib_mod/polylib/SolveDio.h b/source/polylib_mod/polylib/SolveDio.h
deleted file mode 100644
index 383da6b..0000000
--- a/source/polylib_mod/polylib/SolveDio.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _SolveDio_h_
-#define _SolveDio_h_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern int SolveDiophantine ( Matrix *M, Matrix **U, Vector **X );
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _SolveDio_h_ */
diff --git a/source/polylib_mod/polylib/Zpolyhedron.h b/source/polylib_mod/polylib/Zpolyhedron.h
deleted file mode 100644
index 91b9c05..0000000
--- a/source/polylib_mod/polylib/Zpolyhedron.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _Zpolyhedron_h_
-#define _Zpolyhedron_h_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void CanonicalForm(ZPolyhedron *Zpol, ZPolyhedron **Result,
- Matrix **Basis);
-extern ZPolyhedron *EmptyZPolyhedron (int dimension);
-extern ZPolyhedron *IntegraliseLattice (ZPolyhedron *A);
-extern Bool isEmptyZPolyhedron (ZPolyhedron *Zpol);
-extern ZPolyhedron *ZDomainDifference (ZPolyhedron *A, ZPolyhedron *B);
-extern ZPolyhedron *ZDomainImage ( ZPolyhedron *A, Matrix *Func );
-extern Bool ZDomainIncludes ( ZPolyhedron *A, ZPolyhedron *B );
-extern ZPolyhedron *ZDomainIntersection ( ZPolyhedron *A, ZPolyhedron *B );
-extern ZPolyhedron *ZDomainPreimage ( ZPolyhedron *A, Matrix *Func );
-extern void ZDomainPrint(FILE *fp, const char *format, ZPolyhedron *A);
-extern ZPolyhedron *ZDomainSimplify ( ZPolyhedron *ZDom );
-extern ZPolyhedron *ZDomainUnion ( ZPolyhedron *A, ZPolyhedron *B );
-extern ZPolyhedron *ZDomain_Copy ( ZPolyhedron *Head );
-extern void ZDomain_Free ( ZPolyhedron *Head );
-extern Bool ZPolyhedronIncludes ( ZPolyhedron *A, ZPolyhedron *B );
-extern ZPolyhedron *ZPolyhedron_Alloc ( Lattice *Lat, Polyhedron *Poly );
-extern ZPolyhedron *SplitZpolyhedron(ZPolyhedron *ZPol, Lattice *B);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _Zpolyhedron_h_ */
diff --git a/source/polylib_mod/polylib/alpha.h b/source/polylib_mod/polylib/alpha.h
deleted file mode 100644
index 37d7742..0000000
--- a/source/polylib_mod/polylib/alpha.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _alpha_h_
-#define _alpha_h_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern int GaussSimplify ( Matrix *M, Matrix *M2 );
-extern int PolyhedronLTQ ( Polyhedron *P1, Polyhedron *P2, int INDEX, int
- PDIM, int MAXRAYS );
-extern int PolyhedronTSort ( Polyhedron ** L, unsigned int n, unsigned
- int index, unsigned int pdim, int * time,
- int * pvect, unsigned int MAXRAYS );
-extern int Polyhedron_Not_Empty ( Polyhedron *P, Polyhedron *C, int
- MAXRAYS );
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _alpha_h_ */
diff --git a/source/polylib_mod/polylib/arithmetic_errors.h b/source/polylib_mod/polylib/arithmetic_errors.h
deleted file mode 100644
index 1e9e08d..0000000
--- a/source/polylib_mod/polylib/arithmetic_errors.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * $Id: arithmetic_errors.h,v 1.4 2006/03/15 19:59:37 verdoolaege Exp $
- *
- * managing arithmetic errors...
- * detecting and managing arithmetic errors on Values should be
- * systematic. These macros gives a C++ look and feel to this
- * management.
- *
- * (c) CA et FC, Sept 1997
- *
- * $Log: arithmetic_errors.h,v $
- * Revision 1.4 2006/03/15 19:59:37 verdoolaege
- * arith: add some missing consts
- *
- * Revision 1.3 2004/02/08 21:53:27 kienhuis
- * Update from Fabien Coelho, via Bart Kienhuis
- *
- * I've updated here in the C3/Linear library the arithmetic_error
- * package that I developped (with others) to handle exceptions in C.
- * It adds a simple callback feature which is needed for pips here.
- * If you do not use it, it should not harm;-)
- *
- * Revision 1.34 2003/09/03 13:59:46 coelho
- * ++
- *
- * Revision 1.33 2003/09/03 13:35:34 coelho
- * no more callback.
- *
- * Revision 1.32 2003/08/18 14:55:38 coelho
- * callback fix.
- *
- * Revision 1.31 2003/08/18 14:16:45 coelho
- * NULL callback added.
- *
- * Revision 1.30 2003/06/13 13:59:55 coelho
- * hop.
- *
- * Revision 1.29 2000/07/27 15:01:55 coelho
- * hop.
- *
- * Revision 1.28 2000/07/26 09:11:58 coelho
- * hop.
- *
- * Revision 1.27 2000/07/26 09:07:32 coelho
- * *** empty log message ***
- *
- * Revision 1.26 2000/07/26 09:06:32 coelho
- * the_last_just_thrown_exception declared.
- *
- * Revision 1.25 2000/07/26 08:41:40 coelho
- * RETHROW added.
- *
- * Revision 1.24 1998/10/26 14:37:48 coelho
- * constants moved out.
- *
- * Revision 1.23 1998/10/26 14:36:13 coelho
- * constants explicitely defined in .h.
- *
- * Revision 1.22 1998/10/24 15:18:26 coelho
- * THROW macro updated to tell its source.
- *
- * Revision 1.21 1998/10/24 14:33:08 coelho
- * parser exception added.
- *
- * Revision 1.20 1998/10/24 14:32:45 coelho
- * simpler macros.
- *
- * Revision 1.19 1998/10/24 09:22:47 coelho
- * size update.
- *
- * Revision 1.18 1998/10/24 09:21:45 coelho
- * const added to constants.
- *
- */
-
-#if !defined(linear_arithmetic_error_included)
-#define linear_arithmetic_error_included
-
-#include <setjmp.h>
-
-typedef void (*exception_callback_t)(const char *, const char *, int);
-
-/*
-const unsigned int overflow_error = 1;
-const unsigned int simplex_arithmetic_error = 2;
-const unsigned int user_exception_error = 4;
-const unsigned int parser_exception_error = 8;
-const unsigned int any_exception_error = ~0;
-*/
-
-/* use gnu cpp '__FUNCTION__' extension if possible.
- */
-#if defined(__GNUC__)
-#define __CURRENT_FUNCTION_NAME__ __FUNCTION__
-#else
-#define __CURRENT_FUNCTION_NAME__ "<unknown>"
-#endif
-
-/* 'const' out because of cproto 4.6. FC 13/06/2003 */
-#define EXCEPTION extern unsigned int
-
-#define THROW(what) \
- (throw_exception(what, __CURRENT_FUNCTION_NAME__, __FILE__, __LINE__))
-
-#define CATCH(what) \
- if (setjmp(*push_exception_on_stack(what, __CURRENT_FUNCTION_NAME__, \
- __FILE__, __LINE__)))
-
-#define UNCATCH(what) \
- (pop_exception_from_stack(what, __CURRENT_FUNCTION_NAME__, \
- __FILE__, __LINE__))
-
-#define TRY else
-
-extern unsigned int the_last_just_thrown_exception;
-#define RETHROW() THROW(the_last_just_thrown_exception)
-
-#endif /* linear_arithmetic_error_included */
-
-/* end of it.
- */
diff --git a/source/polylib_mod/polylib/arithmetique.h b/source/polylib_mod/polylib/arithmetique.h
deleted file mode 100644
index 0c706c6..0000000
--- a/source/polylib_mod/polylib/arithmetique.h
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* header file built by cproto */
-#ifndef arithmetique_header_included
-#define arithmetique_header_included
-
-/** package arithmetique
- *
- * $Id: arithmetique.h,v 1.24 2007/02/22 09:16:57 skimo Exp $
- *
- * Francois Irigoin, mai 1989
- *
- * Modifications
- * - rewrite of DIVIDE which was wrong (Remi Triolet, Francois Irigoin,
- * april 90)
- * - simplification of POSITIVE_DIVIDE by suppressing one modulo
- * - B.Meister : added addmul, operation existing in gmp and quite useful
- * (05-2005)
- */
-
-/* We would like linear to be generic about the "integer" type used
- * to represent integer values. Thus Value is defined here. It should
- * be changed to "int" "long" or "long long". In an ideal world,
- * any source modification should be limited to this package.
- *
- * Indeed, we cannot switch easily to bignums that need constructors
- * dans destructors... That would lead to too many modifications...
- * C++ would make things easier and cleaner...
- *
- * Fabien COELHO
- */
-
-#include <stdio.h>
-#include <limits.h> /* Included for getting constants: INT_MAX, etc.. */
-
-#ifdef GNUMP
-#include <gmp.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef mp_get_memory_functions
-#if defined(__cplusplus)
-extern "C" {
-#endif
-void mp_get_memory_functions(
- void *(**alloc_func_ptr) (size_t),
- void *(**realloc_func_ptr) (void *, size_t, size_t),
- void (**free_func_ptr) (void *, size_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif
-#endif
-
-#ifdef CLN
-#include <sstream>
-#define WANT_OBFUSCATING_OPERATORS
-#include <cln/cln.h>
-#endif
-
-/*
- # #### # # #### # #### # # ####
- # # # ## # # # # # # ## # # #
- # # # # # # # # # # # # # #
- # # # # # # # ### # # # # # # # ###
- # # # # ## # # # # # # ## # #
- ###### #### # # #### ###### #### # # ####
-
-*/
-
-/*
- * Constants like LONG_LONG_MAX are not defined with ansi options, so they are
- * defined here.
- */
-
-#ifndef LONG_LONG_MAX
-
-/* would fix on solaris:
- * #define LONG_LONG_MAX LLONG_MAX
- * #define LONG_LONG_MIN LLONG_MIN
- */
-
-#ifndef __LONG_LONG_MAX__
-#define __LONG_LONG_MAX__ 9223372036854775807LL
-#endif
-#undef LONG_LONG_MAX
-#define LONG_LONG_MAX __LONG_LONG_MAX__
-#undef LONG_LONG_MIN
-#define LONG_LONG_MIN (-LONG_LONG_MAX-1)
-#undef ULONG_LONG_MAX
-#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1)
-#endif
-
-#if defined(LINEAR_VALUE_IS_LONGLONG)
-
-#define LINEAR_VALUE_STRING "long long int"
-typedef long long int Value;
-#if defined(WIN32) && !defined(unix)
- /* Mingw or Windows need an incompatible format string. */
-# define VALUE_FMT "%I64d"
-#else
-# define VALUE_FMT "%lld"
-#endif
-#define VALUE_CONST(val) (val##LL)
-
-/*
- * CAUTION! 'VALUE_MIN' is defined as 'LONG_LONG_MIN +1' so as to preserve the
- * symmetry (-min==max) and to have a NAN value. FC
- */
-
-#define VALUE_NAN LONG_LONG_MIN
-#define VALUE_MIN (LONG_LONG_MIN+1LL)
-#define VALUE_MAX LONG_LONG_MAX
-#define VALUE_SQRT_MIN long_to_value(LONG_MIN)
-#define VALUE_SQRT_MAX long_to_value(LONG_MAX)
-#define VALUE_ZERO (0LL)
-#define VALUE_ONE (1LL)
-#define VALUE_MONE (-1LL)
-
-#define VALUE_TO_LONG(val) \
- ((long)((val)>(Value)LONG_MIN&&(val)<=(Value)LONG_MAX)?\
- (val):(THROW(overflow_error), LONG_MIN))
-
-#define VALUE_TO_INT(val) \
- ((int)((val)>(Value)INT_MIN&&(val)<=(Value)INT_MAX)?\
- (val):(THROW(overflow_error), INT_MIN))
-
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-/* #define VALUE_TO_FLOAT(val) ((float)(val)): Doesn't seem to work with gcc */
-#define VALUE_TO_FLOAT(val) ((float)((int)(val)))
-
-/* end LINEAR_VALUE_IS_LONGLONG */
-
-/*
-
- # #### # # ####
- # # # ## # # #
- # # # # # # #
- # # # # # # # ###
- # # # # ## # #
- ###### #### # # ####
-
-*/
-
-#elif defined(LINEAR_VALUE_IS_LONG)
-
-#define LINEAR_VALUE_STRING "long int"
-typedef long Value;
-#define VALUE_FMT "%ld"
-#define VALUE_CONST(val) (val##L)
-#define VALUE_NAN LONG_MIN
-#define VALUE_MIN (LONG_MIN+1L)
-#define VALUE_MAX LONG_MAX
-#define VALUE_SQRT_MIN int_to_value(INT_MIN)
-#define VALUE_SQRT_MAX int_to_value(INT_MAX)
-#define VALUE_ZERO 0L
-#define VALUE_ONE 1L
-#define VALUE_MONE -1L
-#define VALUE_TO_LONG(val) (val)
-#define VALUE_TO_INT(val) ((int)(val))
-#define VALUE_TO_FLOAT(val) ((float)(val))
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-/* end LINEAR_VALUE_IS_LONG */
-
-/*
- ###### # #### ## #####
- # # # # # # #
- ##### # # # # # #
- # # # # ###### #
- # # # # # # #
- # ###### #### # # #
-
-*/
-
-/*
-#elif defined(LINEAR_VALUE_IS_FLOAT)
-
-#define LINEAR_VALUE_STRING "float"
-typedef float Value;
-#define VALUE_FMT "%f"
-#define VALUE_CONST(val) (val)
-#define VALUE_MIN FLOAT_MIN
-#define VALUE_MAX FLOAT_MAX
-#define VALUE_ZERO 0.0
-#define VALUE_ONE 1.0
-#define VALUE_MONE -1.0
-#define VALUE_TO_LONG(val) ((long)(val))
-#define VALUE_TO_INT(val) ((int)(val))
-#define VALUE_TO_FLOAT(val) ((float)(val))
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-*/
-
-/* end LINEAR_VALUE_IS_FLOAT */
-
-/*
- #### # # ## ##### # #
- # # # # # # # # # #
- # ###### # # # # #######
- # # # ###### ##### # #
- # # # # # # # # # #
- #### # # # # # #
-
- */
-
-/* Char version is used to detect invalid assignments */
-
-#elif defined(LINEAR_VALUE_IS_CHARS)
-
-#define LINEAR_VALUE_STRING "char"
-typedef union { char *s; long l; int i; float f; double d;} Value;
-#define VALUE_FMT "%s"
-#define VALUE_CONST(val) ((Value)(val))
-#define VALUE_NAN ((Value)(long)0xdadeebee)
-#define VALUE_MIN ((Value)(long)0xdeadbeef)
-#define VALUE_MAX ((Value)(long)0xfeedabee)
-#define VALUE_ZERO ((Value)0)
-#define VALUE_ONE ((Value)1)
-#define VALUE_MONE ((Value)-1)
-#define VALUE_TO_LONG(val) (val.l)
-#define VALUE_TO_INT(val) (val.i)
-#define VALUE_TO_FLOAT(val) (val.f)
-#define VALUE_TO_DOUBLE(val) (val.d)
-
-/* end LINEAR_VALUE_IS_CHARS */
-
-/*
- # # # #####
- # ## # #
- # # # # #
- # # # # #
- # # ## #
- # # # #
-
-*/
-
-#elif defined(LINEAR_VALUE_IS_INT)
-
-#define LINEAR_VALUE_STRING "int"
-typedef int Value;
-#define VALUE_FMT "%d"
-#define VALUE_CONST(val) (val)
-#define VALUE_NAN INT_MIN
-#define VALUE_MIN (INT_MIN+1)
-#define VALUE_MAX INT_MAX
-#define VALUE_ZERO 0
-#define VALUE_ONE 1
-#define VALUE_MONE -1
-#define VALUE_TO_LONG(val) ((long)(val))
-#define VALUE_TO_INT(val) ((int)(val))
-#define VALUE_TO_FLOAT(val) ((float)(val))
-#define VALUE_TO_DOUBLE(val) ((double)(val))
-
-/* end LINEAR_VALUE_IS_INT */
-
-#elif defined(GNUMP)
-
-#define LINEAR_VALUE_STRING "gmp"
-typedef mpz_t Value;
-#define VALUE_FMT "%s"
-
-/* don't use these, use value_set_si instead ! */
-#undef VALUE_ZERO
-#undef VALUE_ONE
-#undef VALUE_MONE
-#define VALUE_TO_LONG(val) (mpz_get_si(val))
-#define VALUE_TO_INT(val) ((int)mpz_get_si(val))
-#define VALUE_TO_FLOAT(val) ((float)((int)mpz_get_si(val)))
-#define VALUE_TO_DOUBLE(val) (mpz_get_d(val))
-
-#elif defined(CLN)
-
-#define LINEAR_VALUE_STRING "cln"
-typedef cln::cl_I Value;
-#define VALUE_FMT "%s"
-
-#define VALUE_TO_INT(val) (cln::cl_I_to_int(val))
-#define VALUE_TO_DOUBLE(val) (cln::double_approx(val))
-
-#endif
-
-/* ***************** MACROS FOR MANIPULATING VALUES ******************** */
-
-#if defined(CLN)
-
-#define value_init(val) ((val).word = ((cln::cl_uint)cl_FN_tag) << cl_tag_shift)
-#define value_assign(v1,v2) ((v1) = (v2))
-#define value_set_si(val,i) ((val) = (i))
-#define value_set_double(val,d) ((val) = cln::truncate1(cln::cl_R(d)))
-#define value_clear(val) ((val) = 0)
-#define value_read(val,str) ((val) = (str))
-#define value_print(Dst,fmt,val) {std::ostringstream strm; strm << val; \
- fprintf((Dst),(fmt),strm.str().c_str()); \
- }
-#define value_swap(v1,v2) {Value tmp; tmp = v2; \
- v2 = v1; v1 = tmp; \
- }
-
-/* Boolean operators on 'Value' */
-
-#define value_eq(v1,v2) ((v1)==(v2))
-#define value_ne(v1,v2) ((v1)!=(v2))
-#define value_gt(v1,v2) ((v1)>(v2))
-#define value_ge(v1,v2) ((v1)>=(v2))
-#define value_lt(v1,v2) ((v1)<(v2))
-#define value_le(v1,v2) ((v1)<=(v2))
-
-#define value_abs_eq(v1,v2) (cln::abs(v1)==cln::abs(v2))
-#define value_abs_ne(v1,v2) (cln::abs(v1)!=cln::abs(v2))
-#define value_abs_gt(v1,v2) (cln::abs(v1)>cln::abs(v2))
-#define value_abs_ge(v1,v2) (cln::abs(v1)>=cln::abs(v2))
-#define value_abs_lt(v1,v2) (cln::abs(v1)<cln::abs(v2))
-#define value_abs_le(v1,v2) (cln::abs(v1)<=cln::abs(v2))
-
-#define value_sign(val) (cln::signum(val))
-#define value_compare(v1,v2) (cln::compare((v1),(v2)))
-
-#define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
-#define value_add_int(ref,val,vint) ((ref) = (val)+(vint))
-#define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
-#define value_increment(ref,val) ((ref) = (val)+1)
-#define value_multiply(ref,val1,val2) ((ref) = (val1)*(val2))
-#define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
-#define value_sub_int(ref,val1,val2) ((ref) = (val1)-(val2))
-#define value_decrement(ref,val) ((ref) = (val)-1)
-#define value_division(ref,val1,val2) ((ref) = cln::truncate1(val1,val2))
-#define value_divexact(ref,val1,val2) ((ref) = cln::exquo(val1,val2))
-#define value_modulus(ref,val1,val2) ((ref) = cln::truncate2(val1,val2).remainder)
-#define value_pdivision(ref,val1,val2) ((ref) = cln::floor1(val1,val2))
-#define value_pmodulus(ref,val1,val2) ((ref) = cln::floor2(val1,val2).remainder)
-#define value_oppose(ref,val) ((ref) = -(val))
-#define value_absolute(ref,val) ((ref) = cln::abs(val))
-#define value_minimum(ref,val1,val2) ((ref) = cln::min((val1),(val2)))
-#define value_maximum(ref,val1,val2) ((ref) = cln::max((val1),(val2)))
-#define value_gcd(ref,val1,val2) ((ref) = cln::gcd((val1),(val2)))
-#define value_lcm(ref,val1,val2) ((ref) = cln::lcm((val1),(val2)))
-#define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
-#define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
-
-/* Conditional operations on 'Value' */
-
-#define value_pos_p(val) ((val) > 0)
-#define value_neg_p(val) ((val) < 0)
-#define value_posz_p(val) ((val) >= 0)
-#define value_negz_p(val) ((val) <= 0)
-#define value_zero_p(val) ((val) == 0)
-#define value_notzero_p(val) ((val) != 0)
-#define value_one_p(val) ((val) == 1)
-#define value_notone_p(val) ((val) != 1)
-#define value_mone_p(val) ((val) == -1)
-#define value_notmone_p(val) ((val) != -1)
-#define value_cmp_si(val, n) (cln::compare(val,n))
-
-#elif defined(GNUMP)
-
-/* Basic macros */
-
-#define value_init(val) (mpz_init((val)))
-#define value_assign(v1,v2) (mpz_set((v1),(v2)))
-#define value_set_si(val,i) (mpz_set_si((val),(i)))
-#define value_set_double(val,d)(mpz_set_d((val),(d)))
-#define value_clear(val) (mpz_clear((val)))
-#define value_read(val,str) (mpz_set_str((val),(str),10))
-typedef void (*value_print_gmp_free_t)(void *, size_t);
-#define value_print(Dst,fmt,val) {char *str; \
- value_print_gmp_free_t gmp_free; \
- str = mpz_get_str(0,10,(val)); \
- fprintf((Dst),(fmt),str); \
- mp_get_memory_functions(NULL, NULL, &gmp_free); \
- (*gmp_free) (str, strlen(str)+1); \
- }
-#define value_swap(val1,val2) (mpz_swap(val1, val2))
-
-/* Boolean operators on 'Value' */
-
-#define value_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
-#define value_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
-#define value_gt(v1,v2) (mpz_cmp((v1),(v2)) > 0)
-#define value_ge(v1,v2) (mpz_cmp((v1),(v2)) >= 0)
-#define value_lt(v1,v2) (mpz_cmp((v1),(v2)) < 0)
-#define value_le(v1,v2) (mpz_cmp((v1),(v2)) <= 0)
-
-#define value_abs_eq(v1,v2) (mpz_cmpabs((v1),(v2)) == 0)
-#define value_abs_ne(v1,v2) (mpz_cmpabs((v1),(v2)) != 0)
-#define value_abs_gt(v1,v2) (mpz_cmpabs((v1),(v2)) > 0)
-#define value_abs_ge(v1,v2) (mpz_cmpabs((v1),(v2)) >= 0)
-#define value_abs_lt(v1,v2) (mpz_cmpabs((v1),(v2)) < 0)
-#define value_abs_le(v1,v2) (mpz_cmpabs((v1),(v2)) <= 0)
-
-/* Trian operators on 'Value' */
-
-#define value_sign(val) (mpz_sgn(val))
-#define value_compare(v1,v2) (mpz_cmp((v1),(v2)))
-
-/* Binary operations on 'Value' */
-
-#define value_addto(ref,val1,val2) (mpz_add((ref),(val1),(val2)))
-#define value_add_int(ref,val,vint) (mpz_add_ui((ref),(val),(long)(vint)))
-#define value_addmul(ref, val1, val2) (mpz_addmul((ref), (val1), (val2)))
-#define value_increment(ref,val) (mpz_add_ui((ref),(val),1))
-#define value_multiply(ref,val1,val2) (mpz_mul((ref),(val1),(val2)))
-#define value_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
-#define value_sub_int(ref,val,vint) (mpz_sub_ui((ref),(val),(long)(vint)))
-#define value_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
-#define value_division(ref,val1,val2) (mpz_tdiv_q((ref),(val1),(val2)))
-#define value_divexact(ref,val1,val2) (mpz_divexact((ref),(val1),(val2)))
-#define value_modulus(ref,val1,val2) (mpz_tdiv_r((ref),(val1),(val2)))
-#define value_pdivision(ref,val1,val2) (mpz_fdiv_q((ref),(val1),(val2)))
-#define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2)))
-#define value_oppose(ref,val) (mpz_neg((ref),(val)))
-#define value_absolute(ref,val) (mpz_abs((ref),(val)))
-#define value_minimum(ref,val1,val2) (value_le((val1),(val2)) ? \
- mpz_set((ref),(val1)) : \
- mpz_set((ref),(val2)))
-#define value_maximum(ref,val1,val2) (value_ge((val1),(val2)) ? \
- mpz_set((ref),(val1)) : \
- mpz_set((ref),(val2)))
-#define value_gcd(ref,val1,val2) (mpz_gcd(ref,val1,val2))
-#define value_lcm(ref,val1,val2) (mpz_lcm(ref,val1,val2))
-#define value_orto(ref,val1,val2) (mpz_ior((ref),(val1),(val2)))
-#define value_andto(ref,val1,val2) (mpz_and((ref),(val1),(val2)))
-
-/* Conditional operations on 'Value' */
-
-#define value_pos_p(val) (mpz_sgn(val) > 0)
-#define value_neg_p(val) (mpz_sgn(val) < 0)
-#define value_posz_p(val) (mpz_sgn(val) >= 0)
-#define value_negz_p(val) (mpz_sgn(val) <= 0)
-#define value_zero_p(val) (mpz_sgn(val) == 0)
-#define value_notzero_p(val) (mpz_sgn(val) != 0)
-#define value_one_p(val) (mpz_cmp_si(val,1) == 0)
-#define value_notone_p(val) (mpz_cmp_si(val,1) != 0)
-#define value_mone_p(val) (mpz_cmp_si(val,-1) ==0)
-#define value_notmone_p(val) (mpz_cmp_si(val,-1) !=0)
-#define value_cmp_si(val, n) (mpz_cmp_si(val,n))
-
-/* ************************************************************************* */
-
-#else /* 'Value' set to longlong|long|float|char *|int */
-/* Basic Macros */
-
-#define value_init(val) ((val) = 0)
-#define value_assign(v1,v2) ((v1) = (v2))
-#define value_set_si(val,i) ((val) = (Value)(i))
-#define value_set_double(val,d) ((val) = (Value)(d))
-#define value_clear(val) ((val) = 0)
-#define value_read(val,str) (sscanf((str),VALUE_FMT,&(val)))
-#define value_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
-#define value_swap(v1,v2) {Value tmp; tmp = v2; \
- v2 = v1; v1 = tmp; \
- }
-/* Cast to 'Value' */
-
-#define int_to_value(i) ((Value)(i))
-#define long_to_value(l) ((Value)(l))
-#define float_to_value(f) ((Value)(f))
-#define double_to_value(d) ((Value)(d))
-
-/* Boolean operators on 'Value' */
-
-#define value_eq(v1,v2) ((v1)==(v2))
-#define value_ne(v1,v2) ((v1)!=(v2))
-#define value_gt(v1,v2) ((v1)>(v2))
-#define value_ge(v1,v2) ((v1)>=(v2))
-#define value_lt(v1,v2) ((v1)<(v2))
-#define value_le(v1,v2) ((v1)<=(v2))
-
-#define value_abs_eq(v1,v2) (value_abs(v1)==value_abs(v2))
-#define value_abs_ne(v1,v2) (value_abs(v1)!=value_abs(v2))
-#define value_abs_gt(v1,v2) (value_abs(v1)>value_abs(v2))
-#define value_abs_ge(v1,v2) (value_abs(v1)>=value_abs(v2))
-#define value_abs_lt(v1,v2) (value_abs(v1)<value_abs(v2))
-#define value_abs_le(v1,v2) (value_abs(v1)<=value_abs(v2))
-
-/* Trian operators on 'Value' */
-
-#define value_sign(v) (value_eq(v,VALUE_ZERO)?0:value_lt(v,VALUE_ZERO)?-1:1)
-#define value_compare(v1,v2) (value_eq(v1,v2)?0:value_lt(v1,v2)?-1:1)
-
-/* Binary operators on 'Value' */
-
-#define value_plus(v1,v2) ((v1)+(v2))
-#define value_div(v1,v2) ((v1)/(v2))
-#define value_mod(v1,v2) ((v1)%(v2))
-#define value_direct_multiply(v1,v2) ((v1)*(v2)) /* direct! */
-#define value_minus(v1,v2) ((v1)-(v2))
-#define value_pdiv(v1,v2) (DIVIDE((v1),(v2)))
-#define value_pmod(v1,v2) (MODULO((v1),(v2)))
-#define value_min(v1,v2) (value_le((v1),(v2))? (v1): (v2))
-#define value_max(v1,v2) (value_ge((v1),(v2))? (v1): (v2))
-#define value_or(v1,v2) ((v1)|(v2))
-#define value_and(v1,v2) ((v1)&(v2))
-#define value_lshift(v1,v2) ((v1)<<(v2))
-#define value_rshift(v1,v2) ((v1)>>(v2))
-
-/* Binary operations on 'Value' */
-
-#define value_addto(ref,val1,val2) ((ref) = (val1)+(val2))
-#define value_add_int(ref,val,vint) ((ref) = (val)+(Value)(vint))
-#define value_addmul(ref, val1, val2) ((ref) += (val1)*(val2))
-#define value_increment(ref,val) ((ref) = (val)+VALUE_ONE)
-#define value_direct_product(ref,val1,val2) ((ref) = (val1)*(val2)) /* direct! */
-#define value_multiply(ref,val1,val2) ((ref) = value_mult((val1),(val2)))
-#define value_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
-#define value_sub_int(ref,val,vint) ((ref) = (val)-(Value)(vint))
-#define value_decrement(ref,val) ((ref) = (val)-VALUE_ONE)
-#define value_division(ref,val1,val2) ((ref) = (val1)/(val2))
-#define value_divexact(ref,val1,val2) ((ref) = (val1)/(val2))
-#define value_modulus(ref,val1,val2) ((ref) = (val1)%(val2))
-#define value_pdivision(ref,val1,val2) ((ref) = value_pdiv((val1),(val2)))
-#define value_pmodulus(ref,val1,val2) ((ref) = value_pmod((val1),(val2)))
-#define value_oppose(ref,val) ((ref) = value_uminus((val)))
-#define value_absolute(ref,val) ((ref) = value_abs((val)))
-#define value_minimum(ref,val1,val2) ((ref) = value_min((val1),(val2)))
-#define value_maximum(ref,val1,val2) ((ref) = value_max((val1),(val2)))
-#define value_gcd(ref,val1,val2) Gcd((val1),(val2),&(ref))
-#define value_lcm(ref,val1,val2) Lcm3((val1),(val2),&(ref))
-#define value_orto(ref,val1,val2) ((ref) = (val1)|(val2))
-#define value_andto(ref,val1,val2) ((ref) = (val1)&(val2))
-
-/* Unary operators on 'Value' */
-
-#define value_uminus(val) (-(val))
-#define value_not(val) (~(val))
-#define value_abs(val) (value_posz_p(val)? \
- (val) : \
- (value_ne((val), VALUE_NAN) ? \
- value_uminus(val) : \
- (THROW (overflow_error), VALUE_NAN )))
-
-/* Conditional operations on 'Value' */
-
-#define value_pos_p(val) value_gt(val,VALUE_ZERO)
-#define value_neg_p(val) value_lt(val,VALUE_ZERO)
-#define value_posz_p(val) value_ge(val,VALUE_ZERO)
-#define value_negz_p(val) value_le(val,VALUE_ZERO)
-#define value_zero_p(val) value_eq(val,VALUE_ZERO)
-#define value_notzero_p(val) value_ne(val,VALUE_ZERO)
-#define value_one_p(val) value_eq(val,VALUE_ONE)
-#define value_notone_p(val) value_ne(val,VALUE_ONE)
-#define value_mone_p(val) value_eq(val,VALUE_MONE)
-#define value_notmone_p(val) value_ne(val,VALUE_MONE)
-#define value_cmp_si(val, n) (val - (n))
-#define value_min_p(val) value_eq(val,VALUE_MIN)
-#define value_max_p(val) value_eq(val,VALUE_MAX)
-#define value_notmin_p(val) value_ne(val,VALUE_MIN)
-#define value_notmax_p(val) value_ne(val,VALUE_MAX)
-
-#endif /* 'Value' set to |longlong|long|float|char *|int */
-
-
-/* *********************** PROTECTED MULTIPLICATION ********************** */
-
-#include "arithmetic_errors.h"
-
-/* (|v| < MAX / |w|) => v*w is okay
- * I could check ((v*w)/w)==v but a tmp would be useful
- */
-#define value_protected_hard_idiv_multiply(v,w,throw) \
- ((value_zero_p(w) || value_zero_p(v))? VALUE_ZERO: \
- value_lt(value_abs(v),value_div(VALUE_MAX,value_abs(w)))? \
- value_direct_multiply(v,w): (throw, VALUE_NAN))
-
-/* is a software idiv is assumed, quick check performed first
- */
-#if defined(LINEAR_VALUE_ASSUME_SOFTWARE_IDIV)
-#define value_protected_multiply(v,w,throw) \
- ((value_le(v,VALUE_SQRT_MAX) && value_le(w,VALUE_SQRT_MAX) && \
- value_ge(v,VALUE_SQRT_MIN) && value_ge(w,VALUE_SQRT_MIN))? \
- value_direct_multiply(v,w): value_protected_hard_idiv_multiply(v,w,throw))
-#else
-#define value_protected_multiply(v,w,throw) \
- value_protected_hard_idiv_multiply(v,w,throw)
-#endif
-
-/* protected versions
- */
-#define value_protected_mult(v,w) \
- value_protected_multiply(v,w,THROW(overflow_error))
-#define value_protected_product(v,w) \
- v=value_protected_mult(v,w)
-
-/* whether the default is protected or not
- * this define makes no sense any more... well, doesn't matter. FC.
- */
-#if defined(LINEAR_VALUE_PROTECT_MULTIPLY)
-#define value_mult(v,w) value_protected_mult(v,w)
-#define value_product(v,w) value_protected_product(v,w)
-#else
-
-/* I do enforce the protection whatever requested:-)
- * prints out a message and throws the exception, hoping
- * that some valid CATCH waits for it upwards.
- */
-#define value_mult(v,w) \
- value_protected_multiply(v,w, \
- (fprintf(stderr,"[value_mult] value overflow!\n"),THROW(overflow_error)))
-#define value_product(v,w) v=value_mult(v,w)
-
-/* was:
- * #define value_mult(v,w) value_direct_multiply(v,w)
- * #define value_product(v,w) value_direct_product(v,w)
- * could be: protected versions...
- */
-#endif
-
-/******************************************************* STATIC VALUE DEBUG */
-
-/* LINEAR_VALUE_IS_CHARS is used for type checking.
- * some operations are not allowed on (char*), thus
- * they are switched to some other operation here...
- */
-#if defined(LINEAR_VALUE_IS_CHARS)
-#define value_fake_binary(v1,v2) ((Value)((v1).i+(v2).i))
-#define value_bool_binary(v1,v2) ((int)((v1).i+(v2).i))
-#undef float_to_value
-#define float_to_value(f) ((Value)f)
-#undef double_to_value
-#define double_to_value(f) ((Value)f)
-#undef value_uminus
-#define value_uminus(v) (v)
-#undef value_mult
-#define value_mult(v1,v2) value_fake_binary(v1,v2)
-#undef value_mod
-#define value_mod(v1,v2) value_fake_binary(v1,v2)
-#undef value_ge
-#define value_ge(v1,v2) value_bool_binary(v1,v2)
-#undef value_gt
-#define value_gt(v1,v2) value_bool_binary(v1,v2)
-#undef value_le
-#define value_le(v1,v2) value_bool_binary(v1,v2)
-#undef value_lt
-#define value_lt(v1,v2) value_bool_binary(v1,v2)
-#undef value_ne
-#define value_ne(v1,v2) value_bool_binary(v1,v2)
-#undef value_eq
-#define value_eq(v1,v2) value_bool_binary(v1,v2)
-#undef value_plus
-#define value_plus(v1,v2) value_fake_binary(v1,v2)
-#undef value_minus
-#define value_minus(v1,v2) value_fake_binary(v1,v2)
-#undef value_pdiv
-#define value_pdiv(v1,v2) value_fake_binary(v1,v2)
-#undef value_div
-#define value_div(v1,v2) value_fake_binary(v1,v2)
-#undef value_mod
-#define value_mod(v1,v2) value_fake_binary(v1,v2)
-#undef value_addto
-#define value_addto(v1,v2) value_assign(v1,value_plus(v1,v2))
-#undef value_subtract
-#define value_subtract(v1,v2) value_addto(v1,v2)
-#undef value_product
-#define value_product(v1,v2) value_addto(v1,v2)
-#undef value_modulus
-#define value_modulus(v1,v2) value_addto(v1,v2)
-#undef value_division
-#define value_division(v1,v2) value_addto(v1,v2)
-#undef value_divexact
-#define value_divexact(v1,v2) value_addto(v1,v2)
-#undef value_increment
-#define value_increment(v) value_addto(v,VALUE_ONE)
-#undef value_decrement
-#define value_decrement(v) value_addto(v,VALUE_MONE)
-#undef value_orto
-#define value_orto(ref,val) value_addto(v1,v2)
-#undef value_andto
-#define value_andto(ref,val) value_addto(v1,v2)
-#undef value_or
-#define value_or(v1,v2) value_fake_binary(v1,v2)
-#undef value_and
-#define value_and(v1,v2) value_fake_binary(v1,v2)
-#undef value_lshift
-#define value_lshift(v1,v2) value_fake_binary(v1,v2)
-#undef value_rshift
-#define value_rshift(v1,v2) value_fake_binary(v1,v2)
-#endif
-
-/* for backward compatibility */
-#define value_substract(ref,val1,val2) (value_subtract((ref),(val1),(val2)))
-
-/* valeur absolue
- */
-#ifndef ABS
-#define ABS(x) (((x)>=0) ? (x) : -(x))
-#endif
-
-/* minimum et maximum
- * if they are defined somewhere else, they are very likely
- * to be defined the same way. Thus the previous def is not overwritten.
- */
-#ifndef MIN
-#define MIN(x,y) (((x)>=(y))?(y):(x))
-#endif
-#ifndef MAX
-#define MAX(x,y) (((x)>=(y))?(x):(y))
-#endif
-
-/* signe d'un entier: -1, 0 ou 1 */
-#define SIGN(x) (((x)>0)? 1 : ((x)==0? 0 : -1))
-
-/* division avec reste toujours positif
- * basee sur les equations:
- * a/(-b) = - (a/b)
- * (-a)/b = - ((a+b-1)/b)
- * ou a et b sont des entiers positifs
- */
-#define DIVIDE(x,y) ((y)>0? POSITIVE_DIVIDE(x,y) : \
- -POSITIVE_DIVIDE((x),(-(y))))
-
-/* division avec reste toujours positif quand y est positif: assert(y>=0) */
-#define POSITIVE_DIVIDE(x,y) ((x)>0 ? (x)/(y) : - (-(x)+(y)-1)/(y))
-
-/* modulo a resultat toujours positif */
-#define MODULO(x,y) ((y)>0 ? POSITIVE_MODULO(x,y) : POSITIVE_MODULO(-x,-y))
-
-/* modulo par rapport a un nombre positif: assert(y>=0)
- *
- * Ce n'est pas la macro la plus efficace que j'aie jamais ecrite: il faut
- * faire, dans le pire des cas, deux appels a la routine .rem, qui n'est
- * surement pas plus cablee que la division ou la multiplication
- */
-#define POSITIVE_MODULO(x,y) ((x) > 0 ? (x)%(y) : \
- ((x)%(y) == 0 ? 0 : ((y)-(-(x))%(y))))
-
-/* errors.c */
-extern unsigned int overflow_error;
-extern unsigned int simplex_arithmetic_error;
-extern unsigned int user_exception_error;
-extern unsigned int parser_exception_error;
-extern unsigned int any_exception_error;
-extern unsigned int the_last_just_thrown_exception;
-extern void dump_exception_stack_to_file(FILE * /*f*/);
-extern void dump_exception_stack(void);
-extern jmp_buf *push_exception_on_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
-extern void pop_exception_from_stack(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
-extern void throw_exception(int /*what*/, const char * /*function*/, const char * /*file*/, int /*line*/);
-
-#endif /* arithmetique_header_included */
-
-
-
diff --git a/source/polylib_mod/polylib/compress_parms.h b/source/polylib_mod/polylib/compress_parms.h
deleted file mode 100644
index 23dcc22..0000000
--- a/source/polylib_mod/polylib/compress_parms.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @author B. Meister 12/2003-2006
- * LSIIT -ICPS
- * UMR 7005 CNRS
- * Louis Pasteur University (ULP), Strasbourg, France
- */
-#ifndef __BM_COMPRESS_PARMS_H__
-#define __BM_COMPRESS_PARMS_H__
-
-#include "matrix_addon.h"
-#include "matrix_permutations.h"
-#include <assert.h>
-
-
-/* ----- functions applying on equalities ----- */
-
-/**
- * Given a system of non-redundant equalities, looks if it has an integer
- * solution in the combined space, and if yes, returns one solution.
- */
-void Equalities_integerSolution(Matrix * Eqs, Matrix ** sol);
-
-/**
- * Computes the validity lattice of a set of equalities. I.e., the lattice
- * induced on the last <tt>b</tt> variables by the equalities involving the
- * first <tt>a</tt> integer existential variables.
- */
-void Equalities_validityLattice(Matrix * Eqs, int a, Matrix** vl);
-
-/**
- * Given an integer matrix B with m rows and integer m-vectors C and d,
- * computes the basis of the integer solutions to (BN+C) mod d = 0 (1).
- * This is an affine lattice (G): (N 1)^T= G(N' 1)^T, forall N' in Z^b.
- * If there is no solution, returns NULL.
-*/
-void Equalities_intModBasis(Matrix * B, Matrix * C, Matrix * d, Matrix ** imb);
-
-
-/* ----- functions applying on constraints ----- */
-
-
-/**
- * Eliminates all the equalities in a set of constraints and returns the set of
- * constraints defining a full-dimensional polyhedron, such that there is a
- * bijection between integer points of the original polyhedron and these of the
- * resulting (projected) polyhedron).
- */
-void Constraints_fullDimensionize(Matrix ** M, Matrix ** C, Matrix ** VL,
- Matrix ** Eqs, Matrix ** ParmEqs,
- unsigned int ** elimVars,
- unsigned int ** elimParms,
- int maxRays);
-
-/* extracts equalities involving only parameters */
-#define Constraints_removeParmEqs(a,b,c,d) Constraints_Remove_parm_eqs(a,b,c,d)
-Matrix * Constraints_Remove_parm_eqs(Matrix ** M, Matrix ** Ctxt,
- int renderSpace,
- unsigned int ** elimParms);
-
-/**
- * Eliminates the columns corresponding to a list of eliminated parameters.
- */
-void Constraints_removeElimCols(Matrix * M, unsigned int nbVars,
- unsigned int *elimParms, Matrix ** newM);
-
-
-/* ----- function applying on a lattice ----- */
-
-/**
- * Given a matrix that defines a full-dimensional affine lattice, returns the
- * affine sub-lattice spanned in the k first dimensions.
- * Useful for instance when you only look for the parameters' validity lattice.
- */
-void Lattice_extractSubLattice(Matrix * lat, unsigned int k, Matrix ** subLat);
-
-
-/* ----- functions applying on a polyhedron ----- */
-
-
-Polyhedron * Polyhedron_Remove_parm_eqs(Polyhedron ** P, Polyhedron ** C,
- int renderSpace,
- unsigned int ** elimParms,
- int maxRays);
-#define Polyhedron_removeParmEqs(a,b,c,d,e) Polyhedron_Remove_parm_eqs(a,b,c,d,e)
-
-
-/* ----- functions kept for backwards compatibility ----- */
-
-
-/**
- * given a full-row-rank nxm matrix M(made of row-vectors),
- * computes the basis K (made of n-m column-vectors) of the integer kernel of M
- * so we have: M.K = 0
-*/
-Matrix * int_ker(Matrix * M);
-
-/* given a matrix of m parameterized equations, compress the parameters and
- transform the variable space into a n-m space. */
-Matrix * full_dimensionize(Matrix const * M, int nb_parms,
- Matrix ** Validity_Lattice);
-
-/* Compute the overall period of the variables I for (MI) mod |d|,
- where M is a matrix and |d| a vector
- Produce a diagonal matrix S = (s_k) where s_k is the overall period of i_k */
-Matrix * affine_periods(Matrix * M, Matrix * d);
-
-/* given a matrix B' with m rows and m-vectors C' and d, computes the
- basis of the integer solutions to (B'N+C') mod d = 0.
-returns NULL if there is no integer solution */
-Matrix * int_mod_basis(Matrix * Bp, Matrix * Cp, Matrix * d);
-
-/* given a parameterized constraints matrix with m equalities, computes the
- compression matrix C such that there is an integer solution in the variables
- space for each value of N', with N = Cmp N' (N are the original parameters) */
-Matrix * compress_parms(Matrix * E, int nb_parms);
-
-
-#endif /* __BM_COMPRESS_PARMS_H__ */
diff --git a/source/polylib_mod/polylib/ehrhart.h b/source/polylib_mod/polylib/ehrhart.h
deleted file mode 100644
index b334f24..0000000
--- a/source/polylib_mod/polylib/ehrhart.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ehrhart_H_
-#define _ehrhart_H_
-
-/*********************** User defines ******************************/
-
-/* Print all overflow warnings, or just one per domain */
-/* #define ALL_OVERFLOW_WARNINGS */
-
-/******************* End of user defines ***************************/
-
-
-#ifndef ALL_OVERFLOW_WARNINGS
-extern int overflow_warning_flag;
-#endif
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void count_points ( int pos, Polyhedron *P, Value *context, Value *res );
-extern void eadd ( evalue *e1, evalue *res );
-extern enode *ecopy ( enode *e );
-extern void edot ( enode *v1, enode *v2, evalue *res );
-extern enode *new_enode( enode_type type,int size, int pos );
-extern void free_evalue_refs ( evalue *e );
-extern Enumeration *Polyhedron_Enumerate(Polyhedron *P, Polyhedron *C,
- unsigned MAXRAYS, const char **pname);
-extern void print_enode(FILE *DST, enode *p, const char **pname);
-extern void print_evalue(FILE *DST, evalue *e, const char **pname);
-extern void reduce_evalue (evalue *e);
-extern void Enumeration_Free(Enumeration *en);
-extern Enumeration *Ehrhart_Quick_Apx(Matrix * M, Matrix * C,
- Matrix ** Validity_Lattice,
- unsigned MAXRAYS);
-extern Enumeration * Enumeration_zero(unsigned int nbParms,
- unsigned int maxRays);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _ehrhart_H_ */
diff --git a/source/polylib_mod/polylib/errormsg.h b/source/polylib_mod/polylib/errormsg.h
deleted file mode 100644
index c4dc1ad..0000000
--- a/source/polylib_mod/polylib/errormsg.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _errormsg_H_
-#define _errormsg_H_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void errormsg1(const char *f, const char *msgname, const char *msg);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _errormsg_H_ */
diff --git a/source/polylib_mod/polylib/eval_ehrhart.h b/source/polylib_mod/polylib/eval_ehrhart.h
deleted file mode 100644
index ed92b2b..0000000
--- a/source/polylib_mod/polylib/eval_ehrhart.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _eval_ehrhart_H_
-#define _eval_ehrhart_H_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern double compute_evalue ( evalue *e, Value *list_args );
-extern Value *compute_poly (Enumeration *en, Value *list_args);
-extern int in_domain(Polyhedron *P, Value *list_args);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _eval_ehrhart_H_ */
-
-
-
diff --git a/source/polylib_mod/polylib/ext_ehrhart.h b/source/polylib_mod/polylib/ext_ehrhart.h
deleted file mode 100644
index 811e883..0000000
--- a/source/polylib_mod/polylib/ext_ehrhart.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _EXT_EHRHART_H_
-#define _EXT_EHRHART_H_
-
-extern Enumeration *Domain_Enumerate(Polyhedron *D, Polyhedron *C,
- unsigned MAXRAYS, const char **pn);
-
-extern void new_eadd (evalue *e1,evalue *res);
-
-#endif
diff --git a/source/polylib_mod/polylib/homogenization.h b/source/polylib_mod/polylib/homogenization.h
deleted file mode 100644
index 6a24fba..0000000
--- a/source/polylib_mod/polylib/homogenization.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/** homogenization.h -- Bavo Nootaert **/
-#ifndef HOMOGENIZATION_H
-#define HOMOGENIZATTON_H
-
-#include <polylib/polylib.h>
-
-Polyhedron *homogenize(Polyhedron *P, unsigned MAXRAYS);
-
-void dehomogenize_evalue(evalue *ep, int nb_param);
-void dehomogenize_enode(enode *p, int nb_param);
-void dehomogenize_enumeration(Enumeration *en, int nb_param, int maxRays);
-Polyhedron *dehomogenize_polyhedron(Polyhedron *p, int maxRays);
-
-#endif
diff --git a/source/polylib_mod/polylib/matrix.h b/source/polylib_mod/polylib/matrix.h
deleted file mode 100644
index 4236072..0000000
--- a/source/polylib_mod/polylib/matrix.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _matrix_H_
-#define _matrix_H_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern Matrix *Matrix_Alloc(unsigned NbRows, unsigned NbColumns);
-extern void Matrix_Free(Matrix *Mat);
-extern void Matrix_Extend(Matrix *Mat, unsigned NbRows);
-extern void Matrix_Print(FILE * Dst, const char *Format, Matrix *Mat);
-extern void Matrix_Read_Input(Matrix *Mat);
-extern Matrix *Matrix_Read(void);
-extern void right_hermite(Matrix *A,Matrix **Hp,Matrix **Up,Matrix
- **Qp);
-extern void left_hermite(Matrix *A,Matrix **Hp,Matrix **Qp,Matrix
- **Up);
-extern int MatInverse(Matrix *M,Matrix *MInv);
-extern void rat_prodmat(Matrix *S,Matrix *X,Matrix *P);
-extern void Matrix_Vector_Product(Matrix *mat,Value *p1,Value *p2);
-extern void Vector_Matrix_Product(Value *p1,Matrix *mat,Value *p2);
-extern void Matrix_Product(Matrix *mat1,Matrix *mat2,Matrix *mat3);
-extern int Matrix_Inverse(Matrix *Mat,Matrix *MatInv);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _matrix_H_ */
diff --git a/source/polylib_mod/polylib/matrix_addon.h b/source/polylib_mod/polylib/matrix_addon.h
deleted file mode 100644
index 0194719..0000000
--- a/source/polylib_mod/polylib/matrix_addon.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Polylib matrix addons
- * Mainly, deals with polyhedra represented in implicit form (set of
- * constraints).
- * @author Benoit Meister
- */
-
-#ifndef __BM_MATRIX_ADDON_H__
-#define __BM_MATRIX_ADDON_H__
-
-#include<polylib/polylib.h>
-#include<assert.h>
-
-/** Shortcut for Matrix_Print */
-#define show_matrix(M) { printf(#M"= \n"); \
- if (M!=NULL) { \
- Matrix_Print(stderr,P_VALUE_FMT,(M));} \
- else {printf("<NULL>\n");} \
- }
-
-/**
- * Allocates a matrix if it is null, or else asserts that it has at least a
- * certain size */
-#define ensureMatrix(M, r, c) { if (M==NULL) M = Matrix_Alloc(r,c); \
- else assert (M->NbRows>=r && M->NbColumns>=c); \
- }
-
-/* Creates a view of the constraints of a polyhedron as a Matrix * */
-Matrix * constraintsView(Polyhedron * P);
-
-/* "Frees" a view of the constraints of a polyhedron */
-void constraintsView_Free(Matrix * M);
-
-/* splits a matrix of constraints M into a matrix of equalities Eqs and a
- matrix of inequalities Ineqs allocs the new matrices. */
-void split_constraints(Matrix const * M, Matrix ** Eqs, Matrix **Ineqs);
-
-/* returns the dim-dimensional identity matrix */
-Matrix * Identity_Matrix(unsigned int dim);
-
-void Matrix_identity(unsigned int dim, Matrix **I);
-
-/* given a n x n integer transformation matrix transf, compute its inverse M/g,
- where M is a nxn integer matrix. g is a common denominator for elements of
- (transf^{-1})*/
-void mtransformation_inverse(Matrix * transf, Matrix ** inv, Value * g);
-
-/* simplifies a matrix seen as a polyhedron, by dividing its rows by the gcd of
-their elements. */
-void mpolyhedron_simplify(Matrix * polyh);
-
-/* inflates a polyhedron (represented as a matrix) P, so that the apx of its
- Ehrhart Polynomial is an upper bound of the Ehrhart polynomial of P WARNING:
- this inflation is supposed to be applied on full-dimensional polyhedra. */
-void mpolyhedron_inflate(Matrix * polyh, unsigned int nb_parms);
-
-/* deflates a polyhedron (represented as a matrix) P, so that the apx of its
- Ehrhart Polynomial is a lower bound of the Ehrhart polynomial of P WARNING:
- this deflation is supposed to be applied on full-dimensional polyhedra. */
-void mpolyhedron_deflate(Matrix * polyh, unsigned int nb_parms);
-
-/* use an eliminator row to eliminate a variable in a victim row (without
-changing the sign of the victim row -> important if it is an inequality). */
-void eliminate_var_with_constr(Matrix * Eliminator,
- unsigned int eliminator_row, Matrix * Victim,
- unsigned int victim_row,
- unsigned int var_to_elim);
-
-
-/* ----- PARTIAL MAPPINGS ----- */
-
-/* compresses the last vars/pars of the polyhedron M expressed as a polylib
- matrix
- - adresses the full-rank compressions only
- - modfies M */
-void mpolyhedron_compress_last_vars(Matrix * M, Matrix * compression);
-#define Constraints_compressLastVars(a, b) mpolyhedron_compress_last_vars(a, b)
-
-/* uses a set of m equalities Eqs to eliminate m variables in the polyhedron.
- Ineqs represented as a matrix eliminates the m first variables
-- assumes that Eqs allows to eliminate the m equalities
-- modifies Ineqs */
-unsigned int mpolyhedron_eliminate_first_variables(Matrix * Eqs,
- Matrix * Ineqs);
-#define Constraints_eliminateFirstVars(a,b) mpolyhedron_eliminate_first_variables(a,b)
-
-/** returns a contiguous submatrix of a matrix. */
-void Matrix_subMatrix(Matrix * M, unsigned int sr, unsigned int sc,
- unsigned int nbR, unsigned int nbC, Matrix ** sub);
-/**
- * Cloning function. Similar to Matrix_Copy() but allocates the target matrix
- * if it is set to NULL.
- */
-void Matrix_clone(Matrix * M, Matrix ** Cl);
-
-/**
- * Copies a contiguous submatrix of M1 into M2, at the indicated position.
- * M1 and M2 are assumed t be allocated already.
- */
-void Matrix_copySubMatrix(Matrix *M1,
- unsigned int sr1, unsigned int sc1,
- unsigned int nbR, unsigned int nbC,
- Matrix * M2,
- unsigned int sr2, unsigned int sc2);
-
-/**
- * given a matrix M into -M
- */
-void Matrix_oppose(Matrix * M);
-
-#endif /* __BM_MATRIX_ADDON_H__ */
diff --git a/source/polylib_mod/polylib/matrix_permutations.h b/source/polylib_mod/polylib/matrix_permutations.h
deleted file mode 100644
index 2d6b302..0000000
--- a/source/polylib_mod/polylib/matrix_permutations.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Permutations on matrices
- * Matrices are seen either as transformations (mtransformation) or as
- * polyhedra (mpolyhedron or Constraints).
- * @author B. Meister
- */
-
-#ifndef __BM_MATRIX_PERMUTATIONS_H__
-#define __BM_MATRIX_PERMUTATIONS_H__
-
-#include<polylib/polylib.h>
-#include<assert.h>
-
-/* Permutations here are vectors that give the future position for each
- variable */
-
-/* utility function : bit count */
-unsigned int nb_bits(unsigned long long int x);
-
-/* gives the inverse permutation vector of a permutation vector */
-unsigned int * permutation_inverse(unsigned int * perm, unsigned int nb_elems);
-
-/*
- * Given a linear tranformation on initial variables, and a variable
- * permutation, compute the tranformation for the permuted variables. perm is
- * a vector giving the new "position of the k^th variable, k \in [1..n] we can
- * call it a "permutation vector" if you wish transf[x][y] ->
- * permuted[permutation(x)][permutation(y)]
- */
-Matrix * mtransformation_permute(Matrix * transf, unsigned int * permutation);
-
-/* permutes the variables of a matrix seen as a polyhedron */
-Matrix * mpolyhedron_permute(Matrix * polyh, unsigned int * permutation);
-
-/* permutes the variables of a matrix seen as a polyhedron */
-void Constraints_permute(Matrix * C, unsigned int * perm, Matrix ** Cp);
-
-/** Given a set of <i>equalities</i>, find a set of variables that can be
- * eliminated using these equalities. The variables that we agree to eliminate
- * are in a zone of contiguous variables (or parameters). <p>
- * Notes:
- <ul>
- <li>brute force, surely enhanceable algorithm</li>
- <li>limited number of variables in the zone: limit = bitwidth of long long
- </ul>
- * @param Eqs the matrix of equalities.
- * @param start the rank of the first variable (inclusive) of the zone in Eqs
- * @param end the rank of the last variable (inclusive) of the zone
- * return a bitfield where bits set to one define the variables to eliminate
-*/
-unsigned long long int eliminable_vars(Matrix * Eqs, unsigned start,
- unsigned end);
-
-/*
-* find a valid permutation : for a set of m equations, find m variables that
-* will be put at the beginning (to be eliminated) it must be possible to
-* eliminate these variables : the submatrix built with their columns must be
-* full-rank. brute force method, that tests all the combinations until finding
-* one which works.
-* <b>LIMITATIONS</b> : up to x-1 variables, where the long long
-* format is x-1 bits (often 64 in year 2005).
-*/
-unsigned int * find_a_permutation(Matrix * Eqs, unsigned int nb_parms);
-
-/*
-* compute the permutation of variables and parameters, according to some
-* variables to keep. put the variables not to be kept at the beginning, then
-* the parameters and finally the variables to be kept. strongly related to the
-* function compress_to_full_dim2
-*/
-unsigned int * permutation_for_full_dim2(unsigned int * vars_to_keep,
- unsigned int nb_keep,
- unsigned int nb_vars_parms,
- unsigned int nb_parms);
-
-#endif /*__BM_MATRIX_PERMUTATIONS_H__ */
diff --git a/source/polylib_mod/polylib/param.h b/source/polylib_mod/polylib/param.h
deleted file mode 100644
index 8ba0295..0000000
--- a/source/polylib_mod/polylib/param.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _param_H_
-#define _param_H_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern const char **Read_ParamNames(FILE *in, int m);
-extern void Free_ParamNames(const char **params, int m);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _param_H_ */
diff --git a/source/polylib_mod/polylib/polyhedron.h b/source/polylib_mod/polylib/polyhedron.h
deleted file mode 100644
index f513903..0000000
--- a/source/polylib_mod/polylib/polyhedron.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _polyhedron_H_
-#define _polyhedron_H_
-
-/* Make sure the Constraint member is valid */
-#define POL_ENSURE_INEQUALITIES(P) \
- if (F_ISSET(P, POL_VALID) && !F_ISSET(P, POL_INEQUALITIES)) \
- Polyhedron_Compute_Dual(P);
-/* Make sure the Ray member is valid */
-#define POL_ENSURE_POINTS(P) \
- if (F_ISSET(P, POL_VALID) && !F_ISSET(P, POL_POINTS)) \
- Polyhedron_Compute_Dual(P);
-/* Make sure the Constraint member is valid and non-redundant */
-#define POL_ENSURE_FACETS(P) \
- if (F_ISSET(P, POL_VALID) && !F_ISSET(P, POL_FACETS)) \
- Polyhedron_Compute_Dual(P);
-/* Make sure the Ray member is valid and non-redundant */
-#define POL_ENSURE_VERTICES(P) \
- if (F_ISSET(P, POL_VALID) && !F_ISSET(P, POL_VERTICES)) \
- Polyhedron_Compute_Dual(P);
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void Polyhedron_Compute_Dual(Polyhedron *P);
-
-Polyhedron *DomainConstraintSimplify(Polyhedron *P, unsigned MaxRays);
-
-extern Polyhedron *AddConstraints(Value *Con,unsigned NbConstraints,
- Polyhedron *Pol,unsigned NbMaxRays );
-extern Polyhedron *AddPolyToDomain(Polyhedron *Pol,Polyhedron *PolDomain);
-extern Polyhedron *AddRays (Value *Ray2,unsigned NbRay2,Polyhedron
- *Pol1,unsigned NbMaxRays);
-extern Polyhedron *align_context(Polyhedron *Pol,int align_dimension,
- int NbMaxRays);
-extern Polyhedron *Constraints2Polyhedron(Matrix *Constraints, unsigned
- NbMaxRays);
-extern Polyhedron *Disjoint_Domain( Polyhedron *Pol, int flag, unsigned
- NbMaxRays );
-extern Polyhedron *DomainAddConstraints(Polyhedron *Pol,Matrix *Mat,
- unsigned NbMaxRays);
-extern Polyhedron *DomainAddRays(Polyhedron *Pol,Matrix *Ray,
- unsigned NbMaxConstrs);
-extern Polyhedron *DomainConvex(Polyhedron *Pol,unsigned NbMaxConstrs);
-extern Interval *DomainCost(Polyhedron *Pol,Value *Cost);
-extern Polyhedron *DomainDifference(Polyhedron *Pol1,Polyhedron *Pol2,
- unsigned NbMaxRays);
-extern Polyhedron *DomainImage(Polyhedron *Pol,Matrix *Func,unsigned
- NbMaxConstrs);
-extern Polyhedron *DomainIntersection(Polyhedron *Pol1,Polyhedron
- *Pol2, unsigned NbMaxRays);
-extern Polyhedron *DomainPreimage(Polyhedron *Pol,Matrix *Func,
- unsigned NbMaxRays);
-extern Polyhedron *DomainSimplify(Polyhedron *Pol1, Polyhedron *Pol2,
- unsigned NbMaxRays);
-extern Polyhedron *Stras_DomainSimplify(Polyhedron *Pol1, Polyhedron *Pol2,
- unsigned NbMaxRays);
-extern Polyhedron *DomainUnion(Polyhedron *Pol1,Polyhedron *Pol2,
- unsigned NbMaxRays);
-extern Polyhedron *Domain_Copy(Polyhedron *Pol);
-extern void Domain_Free (Polyhedron *Pol);
-extern void Domain_PrintConstraints(FILE *Dst, const char *Format,
- Polyhedron *Pol);
-extern Polyhedron *Empty_Polyhedron(unsigned Dimension);
-extern int Gauss(Matrix *Mat,int NbEq,int Dimension);
-extern int lower_upper_bounds(int pos,Polyhedron *P,Value *context,
- Value *LBp,Value *UBp);
-extern Matrix *Polyhedron2Constraints(Polyhedron *Pol);
-extern Matrix *Polyhedron2Rays(Polyhedron *Pol);
-extern int PolyhedronIncludes(Polyhedron *Pol1,Polyhedron *Pol2);
-extern Polyhedron* Polyhedron_Alloc(unsigned Dimension,unsigned
- NbConstraints,unsigned NbRays);
-extern Polyhedron *Polyhedron_Copy(Polyhedron *Pol);
-extern void Polyhedron_Free(Polyhedron *Pol);
-extern Polyhedron *Polyhedron_Image(Polyhedron *Pol,Matrix *Func,
- unsigned NbMaxConstrs);
-extern Polyhedron *Polyhedron_Preimage(Polyhedron *Pol,Matrix *Func,
- unsigned NbMaxRays);
-extern void Polyhedron_Print(FILE *Dst, const char *Format, const Polyhedron *Pol);
-extern void Polyhedron_PrintConstraints(FILE *Dst, const char *Format,
- Polyhedron *Pol);
-extern Polyhedron *Polyhedron_Scan(Polyhedron *D,Polyhedron *C,
- unsigned MAXRAYS);
-extern void PolyPrint(Polyhedron *Pol);
-extern Polyhedron *Rays2Polyhedron(Matrix *Ray,unsigned NbMaxConstrs);
-extern Polyhedron *SubConstraint(Value *Con,Polyhedron *Pol,
- unsigned NbMaxRays, int Pass);
-extern Polyhedron *Universe_Polyhedron (unsigned Dimension);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _polyhedron_H_ */
diff --git a/source/polylib_mod/polylib/polylib.h b/source/polylib_mod/polylib/polylib.h
deleted file mode 100644
index c787c69..0000000
--- a/source/polylib_mod/polylib/polylib.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * polylib.h V4.12
- */
-
-/* WARNING: you should not include directly this file, but use
- polylib32.h or polylib64.h (for 32 or 64 bits integers).
-*/
-
-#if POLYLIB_BITS == 32
-#define LINEAR_VALUE_IS_INT
-#elif POLYLIB_BITS == 64
-#define LINEAR_VALUE_IS_LONG
-#define LINEAR_VALUE_PROTECT_MULTIPLY
-#endif
-
-#if ! defined(LINEAR_VALUE_IS_LONGLONG) \
- && ! defined(LINEAR_VALUE_IS_LONG) \
- && ! defined(LINEAR_VALUE_IS_INT) \
- && ! defined(LINEAR_VALUE_IS_CHARS) \
- && ! defined(GNUMP) \
- && ! defined(CLN)
-#error Please define LINEAR_VALUE_IS_* or #include polylib32.h or polylib64.h
-#endif
-
-#include <polylib/arithmetique.h>
-#include <polylib/arithmetic_errors.h>
-#include <polylib/types.h>
-#include <polylib/errormsg.h>
-#include <polylib/vector.h>
-#include <polylib/matrix.h>
-#include <polylib/polyhedron.h>
-#include <polylib/polyparam.h>
-#include <polylib/param.h>
-#include <polylib/alpha.h>
-#include <polylib/ehrhart.h>
-#include <polylib/ext_ehrhart.h>
-#include <polylib/eval_ehrhart.h>
-#include <polylib/SolveDio.h>
-#include <polylib/Lattice.h>
-#include <polylib/Matop.h>
-#include <polylib/NormalForms.h>
-#include <polylib/Zpolyhedron.h>
-
-/* added for Ehrhart polynomial approximation + bounds */
-#include <polylib/matrix_addon.h>
-#include <polylib/matrix_permutations.h>
-#include <polylib/compress_parms.h>
-
-#ifdef GNUMP
-#include <gmp.h>
-#endif
-
-
diff --git a/source/polylib_mod/polylib/polylib.h.in b/source/polylib_mod/polylib/polylib.h.in
deleted file mode 100644
index c477e74..0000000
--- a/source/polylib_mod/polylib/polylib.h.in
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * polylib.h V4.12
- */
-
-/* WARNING: you should not include directly this file, but use
- polylib32.h or polylib64.h (for 32 or 64 bits integers).
-*/
-
-#if POLYLIB_BITS == 32
- at polylib32_defs@
-#elif POLYLIB_BITS == 64
- at polylib64_defs@
-#endif
-
-#if ! defined(LINEAR_VALUE_IS_LONGLONG) \
- && ! defined(LINEAR_VALUE_IS_LONG) \
- && ! defined(LINEAR_VALUE_IS_INT) \
- && ! defined(LINEAR_VALUE_IS_CHARS) \
- && ! defined(GNUMP) \
- && ! defined(CLN)
-#error Please define LINEAR_VALUE_IS_* or #include polylib32.h or polylib64.h
-#endif
-
-#include <polylib/arithmetique.h>
-#include <polylib/arithmetic_errors.h>
-#include <polylib/types.h>
-#include <polylib/errormsg.h>
-#include <polylib/vector.h>
-#include <polylib/matrix.h>
-#include <polylib/polyhedron.h>
-#include <polylib/polyparam.h>
-#include <polylib/param.h>
-#include <polylib/alpha.h>
-#include <polylib/ehrhart.h>
-#include <polylib/ext_ehrhart.h>
-#include <polylib/eval_ehrhart.h>
-#include <polylib/SolveDio.h>
-#include <polylib/Lattice.h>
-#include <polylib/Matop.h>
-#include <polylib/NormalForms.h>
-#include <polylib/Zpolyhedron.h>
-
-/* added for Ehrhart polynomial approximation + bounds */
-#include <polylib/matrix_addon.h>
-#include <polylib/matrix_permutations.h>
-#include <polylib/compress_parms.h>
-
-#ifdef GNUMP
-#include <gmp.h>
-#endif
-
-
diff --git a/source/polylib_mod/polylib/polylib32.h b/source/polylib_mod/polylib/polylib32.h
deleted file mode 100644
index 59fffc3..0000000
--- a/source/polylib_mod/polylib/polylib32.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define POLYLIB_BITS 32
-
-#include <polylib/polylib.h>
diff --git a/source/polylib_mod/polylib/polylib64.h b/source/polylib_mod/polylib/polylib64.h
deleted file mode 100644
index fe430b5..0000000
--- a/source/polylib_mod/polylib/polylib64.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define POLYLIB_BITS 64
-
-#include <polylib/polylib.h>
diff --git a/source/polylib_mod/polylib/polylibgmp.h b/source/polylib_mod/polylib/polylibgmp.h
deleted file mode 100644
index 92080c9..0000000
--- a/source/polylib_mod/polylib/polylibgmp.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define GNUMP
-
-#include<gmp.h>
-#include <polylib/polylib.h>
diff --git a/source/polylib_mod/polylib/polyparam.h b/source/polylib_mod/polylib/polyparam.h
deleted file mode 100644
index bc06787..0000000
--- a/source/polylib_mod/polylib/polyparam.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _polyparam_H_
-#define _polyparam_H_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void Compute_PDomains ( Param_Domain *PD, int nb_domains, int
- working_space );
-extern Param_Polyhedron *GenParamPolyhedron(Polyhedron *Pol, Matrix *Rays);
-extern void Param_Domain_Free (Param_Domain *PD);
-extern void Param_Polyhedron_Free ( Param_Polyhedron *P );
-extern void Param_Vertices_Free ( Param_Vertices *PV );
-extern void Param_Vertices_Print(FILE *DST, Param_Vertices *PV,
- const char **param_names);
-extern Polyhedron *PDomainDifference ( Polyhedron *Pol1, Polyhedron
- *Pol2, unsigned NbMaxRays );
-extern Polyhedron *PDomainIntersection ( Polyhedron *Pol1, Polyhedron
- *Pol2, unsigned NbMaxRays );
-extern Param_Polyhedron *Polyhedron2Param_Domain ( Polyhedron *Din,
- Polyhedron *Cin, int
- working_space );
-extern Param_Polyhedron *Polyhedron2Param_SimplifiedDomain (
- Polyhedron **Din, Polyhedron *Cin, int working_space,
- Polyhedron **CEq, Matrix **CT );
-extern Param_Polyhedron *Polyhedron2Param_Vertices ( Polyhedron *Din,
- Polyhedron *Cin, int
- working_space );
-extern void Print_Domain(FILE *DST, Polyhedron *D, const char **param_names);
-extern void Print_Vertex(FILE *DST, Matrix *V, const char **param_names);
-extern Matrix *VertexCT( Matrix *V, Matrix *CT );
-void Param_Polyhedron_Scale_Integer(Param_Polyhedron *PP, Polyhedron **P,
- Value *det, unsigned MaxRays);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _polyparam_H_ */
diff --git a/source/polylib_mod/polylib/ranking.h b/source/polylib_mod/polylib/ranking.h
deleted file mode 100644
index d2b14d2..0000000
--- a/source/polylib_mod/polylib/ranking.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Tools to compute the ranking function of an iteration J: the number of
- * integer points in P that are lexicographically inferior to J
- * @author B. Meister <meister at icps.u-strasbg.fr>
- * 6/2005
- * LSIIT-ICPS, UMR 7005 CNRS Universite Louis Pasteur
- * HiPEAC Network
- */
-
-#ifndef __BM_POLYLIB_RANKING_H__
-#define __BM_POLYLIB_RANKING_H__
-#include <polylib/polylib.h>
-
-/*
- * Returns a list of polytopes needed to compute
- * the number of points in P that are lexicographically
- * smaller than a given point in D.
- * Only the first dim dimensions are taken into account
- * for computing the lexsmaller relation.
- * The remaining variables are assumed to be extra
- * existential/control variables.
- * When P == D, this is the conventional ranking function.
- * P and D are assumed to have the same parameter domain C.
- *
- * The first polyhedron in the list returned is the
- * updated context: a combination of D and C or an extended C.
- *
- * The order of the variables in the remaining polyhedra is
- * - first dim variables of P
- * - existential variables of P
- * - existential variables of D
- * - first dim variables of D
- * - the parameters
- */
-Polyhedron *LexSmaller(Polyhedron *P, Polyhedron *D, unsigned dim,
- Polyhedron *C, unsigned MAXRAYS);
-
-/*
- * Returns the number of points in P that are lexicographically
- * smaller than a given point in D.
- * Only the first dim dimensions are taken into account
- * for computing the lexsmaller relation.
- * The remaining variables are assumed to be extra
- * existential/control variables.
- * When P == D, this is the conventional ranking function.
- * P and D are assumed to have the same parameter domain C.
- * The variables in the Enumeration correspond to the first dim variables
- * in D followed by the parameters of D (the variables of C).
- */
-Enumeration *Polyhedron_LexSmallerEnumerate(Polyhedron *P, Polyhedron *D,
- unsigned dim,
- Polyhedron *C, unsigned MAXRAYS);
-
-/*
- * Returns a function that assigns a unique number to each point in the
- * polytope P ranging from zero to (number of points in P)-1.
- * The order of the numbers corresponds to the lexicographical order.
- *
- * C is the parameter context of the polytope
- */
-Enumeration *Polyhedron_Ranking(Polyhedron *P, Polyhedron *C, unsigned MAXRAYS);
-
-#endif /* __BM_POLYLIB_RANKING_H__ */
diff --git a/source/polylib_mod/polylib/types.h b/source/polylib_mod/polylib/types.h
deleted file mode 100644
index ab32dce..0000000
--- a/source/polylib_mod/polylib/types.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* types-polylib.h
- COPYRIGHT
- Both this software and its documentation are
-
- Copyright 1993, IRISA /Universite de Rennes I - France
- Copyright 1996,1997,1998, Doran Wilde and Vincent Loechner
- All rights reserved.
-
- Permission is granted to copy, use, and distribute
- for any commercial or noncommercial purpose under the terms
- of the GNU General Public license, version 2, June 1991
- (see file : LICENSING).
-*/
-
-#ifndef _types_polylib_h_
-#define _types_polylib_h_
-
-#ifdef GNUMP
-#include<gmp.h>
-#endif
-
-#include <limits.h>
-
-/*********************** USER DEFINES ******************************/
-
-/* first parameter name char. */
-#define FIRST_PARAMETER_NAME 'P'
-
-/******************* END OF USER DEFINES ***************************/
-
-
-#define PCHAR (FIRST_PARAMETER_NAME-1)
-#define MAXNOOFRAYS 200
-
-#if defined(LINEAR_VALUE_IS_LONGLONG)
-#define P_VALUE_FMT "%4lld "
-#elif defined(LINEAR_VALUE_IS_LONG)
-#define P_VALUE_FMT "%4ld "
-#elif defined(LINEAR_VALUE_IS_CHARS)
-#define P_VALUE_FMT "%s "
-#elif defined(LINEAR_VALUE_IS_INT)
-#define P_VALUE_FMT "%4d "
-#else /* GNUMP */
-#define P_VALUE_FMT "%4s "
-#endif
-
-/* Used in lower_upper_bounds */
-#define LB_INFINITY 1
-#define UB_INFINITY 2
-
-/* MSB, TOP, and NEXT are defined over integer type, not on value type */
-/* Put a one in the most significant bit of an int (portable) */
-#define MSB ((unsigned)(((unsigned)1)<<(sizeof(int)*8-1)))
-
-/* Largest representable positive number */
-#define TOP ((int)(MSB-1))
-
-/* Right shift the one bit in b and increment j if the last bit in b is one */
-#define NEXT(j,b) { if (!((b)>>=1)) { (b)=MSB; (j)++; } }
-
-/* Status of last Polyhedron operation */
-extern int Pol_status;
-
-#define POL_HIGH_BIT (UINT_MAX - (UINT_MAX >> 1))
-#define POL_NO_DUAL (POL_HIGH_BIT | 0x0001)
-#define POL_INTEGER (POL_HIGH_BIT | 0x0002)
-#define POL_ISSET(flags,f) ((flags & f) == f)
-
-typedef struct {
- unsigned Size;
- Value *p;
-} Vector;
-
-typedef struct matrix {
- unsigned NbRows, NbColumns;
- Value **p;
- Value *p_Init;
- int p_Init_size; /* needed to free the memory allocated by mpz_init */
-} Matrix;
-
-/* Macros to init/set/clear/test flags. */
-#define FL_INIT(l, f) (l) = (f) /* Specific flags location. */
-#define FL_SET(l, f) ((l) |= (f))
-#define FL_CLR(l, f) ((l) &= ~(f))
-#define FL_ISSET(l, f) ((l) & (f))
-
-#define F_INIT(p, f) FL_INIT((p)->flags, f) /* Structure element flags. */
-#define F_SET(p, f) FL_SET((p)->flags, f)
-#define F_CLR(p, f) FL_CLR((p)->flags, f)
-#define F_ISSET(p, f) FL_ISSET((p)->flags, f)
-
-typedef struct polyhedron {
- unsigned Dimension, NbConstraints, NbRays, NbEq, NbBid;
- Value **Constraint;
- Value **Ray;
- Value *p_Init;
- int p_Init_size;
- struct polyhedron *next;
-#define POL_INEQUALITIES 0x00000001
-#define POL_FACETS 0x00000002
-#define POL_POINTS 0x00000004
-#define POL_VERTICES 0x00000008
-/* The flags field contains "valid" information,
- * i.e., the structure was created by PolyLib.
- */
-#define POL_VALID 0x00000010
- unsigned flags;
-} Polyhedron;
-
-typedef struct interval {
- Value MaxN, MaxD;
- Value MinN, MinD;
- int MaxI, MinI;
-} Interval;
-
-/* Test whether P is an empty polyhedron */
-#define emptyQ(P) \
- ((F_ISSET(P, POL_INEQUALITIES) && P->NbEq > P->Dimension) || \
- (F_ISSET(P, POL_POINTS) && P->NbRays == 0))
-
-/* Test whether P is a universe polyheron */
-#define universeQ(P) (P->Dimension==P->NbBid)
-
-typedef struct _Param_Vertex {
- Matrix *Vertex; /* Each row is a coordinate of the vertex. The first */
- /* "m" values of each row are the coefficients of the */
- /* parameters. The (m+1)th value is the constant, the */
- /* The (m+2)th value is the common denominator. */
- Matrix *Domain; /* Constraints on parameters (in Polyhedral format) */
- unsigned *Facets; /* Bit array of facets defining the vertex. */
- struct _Param_Vertex *next; /* Pointer to the next structure */
-} Param_Vertices;
-
-typedef struct _Param_Domain {
- unsigned *F; /* Bit array of faces */
- Polyhedron *Domain; /* Pointer to Domain (constraints on parameters) */
- struct _Param_Domain *next; /* Pointer to the next structure */
-} Param_Domain;
-
-typedef struct _Param_Polyhedron {
- int nbV; /* Number of parameterized vertices */
- Param_Vertices *V; /* Pointer to the list of parameteric vertices */
- Param_Domain *D; /* Pointer to the list of validity domains */
- Matrix *Constraints;/* Constraints referred to by V->Facets */
- Matrix *Rays; /* Lines/rays (non parametric) */
-} Param_Polyhedron;
-
-#define FORALL_PVertex_in_ParamPolyhedron(_V, _D, _P) \
-{ int _i, _ix; \
- unsigned _bx; \
- for( _i=0, _ix=0, _bx=MSB, _V=_P->V ; \
- _V && (_i<_P->nbV) ; _i++, _V=_V->next ) \
- { if (_D->F[_ix] & _bx) \
- {
-
-#define END_FORALL_PVertex_in_ParamPolyhedron \
- } \
- NEXT(_ix, _bx); \
- } \
-}
-
-/* Data structures for pseudo-polynomial */
-
-typedef enum { polynomial, periodic, evector } enode_type;
-
-#ifdef CLN
-#define POLY_UNION_OR_STRUCT struct
-#else
-#define POLY_UNION_OR_STRUCT union
-#endif
-
-typedef struct _evalue {
- Value d; /* denominator */
- POLY_UNION_OR_STRUCT {
- Value n; /* numerator (if denominator != 0) */
- struct _enode *p; /* pointer (if denominator == 0) */
- } x;
-} evalue;
-
-typedef struct _enode {
- enode_type type; /* polynomial or periodic or evector */
- int size; /* number of attached pointers */
- int pos; /* parameter position */
- evalue arr[1]; /* array of rational/pointer */
-} enode;
-
-typedef struct _enumeration {
-
- Polyhedron *ValidityDomain; /* contraints on the parameters */
- evalue EP; /* dimension = combined space */
- struct _enumeration *next; /* Ehrhart Polynomial, corresponding
- to parameter values inside the
- domain ValidityDomain below */
-} Enumeration;
-
-/*-----------------------------Example Usage------------------------------*/
-/* enode *e */
-/* e->type = polynomial e->type = periodic e->type = evector */
-/* e->size = degree+1 e->size = period e->size = length */
-/* e->pos = [1..nb_param] */
-/* e->arr[i].d = denominator (Value) */
-/* e->arr[i].x.p = pointer to another enode (if denominator is zero) */
-/* e->arr[i].x.n = numerator (Value) (if denominator is non-zero) */
-/*------------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------------*/
-/* This representation has the following advantages: */
-/* -- its dynamic, it can grow/shrink easily */
-/* -- it is easy to evaluate for a given context (values of parameters) */
-/* -- it allows pseudo-polynomial to be reduced with rules */
-/* -- it can be constructed recursively */
-/*------------------------------------------------------------------------*/
-
-/* *********************** |Represnting Z-Polyhedron| ******************* */
-
-
-typedef enum {False = 0, True = 1} Bool;
-typedef Matrix Lattice;
-typedef struct LatticeUnion {
- Lattice *M;
- struct LatticeUnion *next;
-} LatticeUnion;
-
-typedef struct ZPolyhedron {
- Lattice *Lat ;
- Polyhedron *P;
- struct ZPolyhedron *next;
-} ZPolyhedron;
-
-#ifndef FOREVER
-#define FOREVER for(;;)
-#endif
-
-#endif /* _types_polylib_h_ */
diff --git a/source/polylib_mod/polylib/vector.h b/source/polylib_mod/polylib/vector.h
deleted file mode 100644
index b100c5c..0000000
--- a/source/polylib_mod/polylib/vector.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _vector_H_
-#define _vector_H_
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int ConstraintSimplify(Value *old, Value *n, int len, Value* v);
-Value* value_alloc(int want, int *got);
-void value_free(Value *p, int size);
-
-extern void Factorial(int n,Value *result);
-extern void Binomial(int n,int p,Value *result);
-extern void CNP(int a,int b,Value *result);
-extern void Gcd(Value a,Value b,Value *result);
-extern int First_Non_Zero(Value *p, unsigned length);
-extern Vector *Vector_Alloc(unsigned length);
-extern void Vector_Free(Vector *vector);
-extern void Vector_Print(FILE *Dst, const char *Format, Vector *Vec);
-extern Vector *Vector_Read(void);
-extern void Vector_Set(Value *p,int n,unsigned length);
-extern void Vector_Exchange(Value *p1, Value *p2, unsigned length);
-extern void Vector_Copy(Value *p1, Value *p2, unsigned length);
-extern void Vector_Add(Value *p1,Value *p2,Value *p3,unsigned length);
-extern void Vector_Sub(Value *p1,Value *p2,Value *p3,unsigned length);
-extern void Vector_Or(Value *p1,Value *p2,Value *p3,unsigned length);
-extern void Vector_Scale(Value *p1, Value *p2, Value lambda, unsigned
- length);
-extern void Vector_AntiScale(Value *p1,Value *p2,Value lambda,
- unsigned length);
-extern void Vector_Oppose(Value *p1, Value *p2, unsigned length);
-extern void Inner_Product(Value *p1,Value *p2,unsigned length, Value *result);
-extern void Vector_Max(Value *p,unsigned length, Value *result);
-extern void Vector_Min(Value *p,unsigned length, Value *result);
-extern void Vector_Combine(Value *p1,Value *p2,Value *p3,Value
- lambda, Value mu, unsigned length);
-extern int Vector_Equal(Value *Vec1,Value *Vec2,unsigned n);
-extern void Vector_Min_Not_Zero(Value *p,unsigned length,int *index,Value
- *result);
-extern void Vector_Gcd(Value *p,unsigned length,Value *result);
-extern void Vector_Map(Value *p1,Value *p2,Value *p3,unsigned
- length, Value *(*f)(Value,Value));
-extern void Vector_Normalize(Value *p,unsigned length);
-extern void Vector_Normalize_Positive(Value *p,int length,
- int pos);
-extern void Vector_Reduce(Value *p,unsigned length,
- void(*f)(Value,Value *),Value *result);
-extern void Vector_Sort(Value *vector,unsigned n);
-extern int Vector_IsZero(Value * v, unsigned length);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _vector_H_ */
diff --git a/source/polylib_mod/polyparam.c b/source/polylib_mod/polyparam.c
deleted file mode 100644
index 321159a..0000000
--- a/source/polylib_mod/polyparam.c
+++ /dev/null
@@ -1,1957 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/***********************************************************************/
-/* Parametrized polyhedra V4.20 */
-/* copyright 1995-2000 Vincent Loechner */
-/* copyright 1996-1997, Doran Wilde */
-/* Permission is granted to copy, use, and distribute */
-/* for any commercial or noncommercial purpose under the terms */
-/* of the GNU General Public license, version 2, June 1991 */
-/* (see file : LICENSING). */
-/***********************************************************************/
-
-/********************* -----------USER #DEFS-------- ***********************/
-/* These are mainly for debug purposes. You shouldn't need to change */
-/* anything for daily usage... */
-/***************************************************************************/
-
-/* you may define each macro independently */
-/* #define DEBUGPP */
-/* #define DEBUGPP3 */ /* initialization of domain, context, ... */
-/* #define DEBUGPP31 */ /* even more init-domains */
-/* #define DEBUGPP32 */ /* even even more... (Elim_Columns) */
-/* #define DEBUGPP4 */ /* m-faces scan */
-/* #define DEBUGPP41 */ /* inverse Di in scan */
-/* #define DEBUGPP5 */ /* Compute_PDomains */
-/********************* ---------END USER #DEFS------ ***********************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#ifdef DEBUGPP
-#include <time.h>
-#endif
-
-#include <polylib/polylib.h>
-
-static void traite_m_face(Polyhedron *, unsigned int *, unsigned int *);
-static void scan_m_face(int,int,Polyhedron *,unsigned int *);
-
-/*
- * Return the intersection of two polyhedral domains 'Pol1' and 'Pol2' such
- * that if the intersection is a polyhedron of lower dimension (a degenerate
- * polyhedron) than the operands, it is discarded from the resulting polyhedra
- * list.
- */
-Polyhedron *PDomainIntersection(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
-
- Polyhedron *p1, *p2, *p3, *d;
-
- if (!Pol1 || !Pol2) return (Polyhedron*) 0;
- if((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
- fprintf(stderr,
- "? PDomainIntersection: operation on different dimensions\n");
- return (Polyhedron*) 0;
- }
-
- POL_ENSURE_FACETS(Pol1);
- POL_ENSURE_VERTICES(Pol1);
- POL_ENSURE_FACETS(Pol2);
- POL_ENSURE_VERTICES(Pol2);
-
- d = (Polyhedron *)0;
- for (p1=Pol1; p1; p1=p1->next) {
- for (p2=Pol2; p2; p2=p2->next) {
- p3 = AddConstraints(p2->Constraint[0],
- p2->NbConstraints,p1,NbMaxRays);
- if (!p3) continue;
-
- /* If the new polyhedron 'p3' has lower dimension, discard it */
- if (p3->NbEq!=Pol1->NbEq)
- Polyhedron_Free(p3) ;
-
- /* Otherwise add it to the new polyhderal domain 'd'. */
- else
- d = AddPolyToDomain(p3,d);
- }
- }
- return d;
-} /* PDomainIntersection */
-
-/*
- * Given polyhderal domains 'Pol1' and 'Pol2', return the difference of the
- * two domains with a modification that the resulting polyhedra in the new
- * domain don't have a 1 unit space around cut and the degenerate results
- * (of smaller dimension) are discarded.
- */
-Polyhedron *PDomainDifference(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
-
- Polyhedron *p1, *p2, *p3, *d;
- int i;
-
- if (!Pol1 || !Pol2)
- return (Polyhedron*) 0;
- if((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
- fprintf(stderr,
- "? PDomainDifference: operation on different dimensions\n");
- return (Polyhedron*) 0;
- }
-
- POL_ENSURE_FACETS(Pol1);
- POL_ENSURE_VERTICES(Pol1);
- POL_ENSURE_FACETS(Pol2);
- POL_ENSURE_VERTICES(Pol2);
-
- d = (Polyhedron *)0;
- for (p2=Pol2; p2; p2=p2->next) {
- for (p1=Pol1; p1; p1=p1->next) {
- for (i=0; i<p2->NbConstraints; i++) {
-
- /* Add the constraint (-p2->Constraint[i]) >= 0 in 'p1' */
- p3 = SubConstraint(p2->Constraint[i],p1,NbMaxRays,2);
- if (!p3) continue;
-
- /* If the new polyhedron 'p3' is empty or is a polyhedron of lower */
- /* dimension, discard it. */
- if (emptyQ(p3) || p3->NbEq!=Pol1->NbEq)
- Polyhedron_Free(p3);
-
- /* Otherwise add 'p3' to the new polyhderal domain 'd' */
- else
- d = AddPolyToDomain(p3,d);
- }
- }
- if (p2 != Pol2)
- Domain_Free(Pol1);
- Pol1 = d;
- d = (Polyhedron *)0;
- }
- return Pol1;
-} /* PDomainDifference */
-
-/*
- * Return 1 if matrix 'Mat' is full column ranked, otherwise return 0.
- */
-static int TestRank(Matrix *Mat) {
-
- int i,j,k;
- Value m1,m2,m3,gcd,tmp;
-
- /* Initialize all the 'Value' variables */
- value_init(m1); value_init(m2);
- value_init(m3); value_init(gcd); value_init(tmp);
-
- for(k=0;k<Mat->NbColumns;++k) {
-
- /* If the digonal entry (k,k) is zero, search down the column(k) */
- /* starting from row(k) to find a non-zero entry */
- if(value_zero_p(Mat->p[k][k])) {
- for(j=k+1;j<Mat->NbRows;++j) {
-
- /* If a non-zero entry (j,k) is found */
- if(value_notzero_p(Mat->p[j][k])) {
-
- /* Exchange row(k) and row(j) */
- for(i=k;i<Mat->NbColumns;++i) {
- value_assign(tmp,Mat->p[j][i]);
- value_assign(Mat->p[j][i],Mat->p[k][i]);
- value_assign(Mat->p[k][i],tmp);
- }
- break;
- }
- }
-
- /* If no non-zero entry is found then the matrix 'Mat' is not full */
- /* ranked. Return zero. */
- if(j>=Mat->NbRows) {
-
- /* Clear all the 'Value' variables */
- value_clear(m1); value_clear(m2);
- value_clear(m3); value_clear(gcd); value_clear(tmp);
- return 0;
- }
- }
-
- /* Now Mat[k][k] is the pivot element */
- for(j=k+1;j<Mat->NbRows;++j) {
-
- /* Make every other entry (below row(k)) in column(k) zero */
- value_gcd(gcd, Mat->p[j][k], Mat->p[k][k]);
- for(i=k+1;i<Mat->NbColumns;++i) {
-
- /* pour tous les indices i > k */
- value_multiply(m1,Mat->p[j][i],Mat->p[k][k]);
- value_multiply(m2,Mat->p[j][k],Mat->p[k][i]);
- value_subtract(m3,m1,m2);
- value_division(Mat->p[j][i],m3,gcd);
- }
- }
- }
-
- /* Clear all the 'Value' variables */
- value_clear(m1); value_clear(m2);
- value_clear(m3); value_clear(gcd); value_clear(tmp);
-
- /* The matrix 'Mat' is full ranked, return 1 */
- return 1;
-} /* TestRank */
-
-/*
- * The Saturation matrix is defined to be an integer (int type) matrix. It is
- * a boolean matrix which has a row for every constraint and a column for
- * every line or ray. The bits in the binary format of each integer in the
- * saturation matrix stores the information whether the corresponding constr-
- * aint is saturated by ray(line) or not.
- */
-typedef struct {
- unsigned int NbRows;
- unsigned int NbColumns;
- unsigned int **p;
- unsigned int *p_init;
-} SatMatrix;
-
-static SatMatrix *SMAlloc(int rows,int cols) {
-
- unsigned int **q, *p;
- int i;
-
- SatMatrix *result = (SatMatrix *)malloc(sizeof(SatMatrix));
- assert (result != NULL);
-
- result->NbRows = rows;
- result->NbColumns = cols;
- result->p = q = (unsigned int **)malloc(rows * sizeof(unsigned int *));
- assert (result->p != NULL);
- result->p_init = p = (unsigned int *)malloc(rows * cols * sizeof(unsigned int));
- assert (result->p_init != NULL);
-
- for (i=0;i<rows;i++) {
- *q++ = p;
- p += cols;
- }
-
- return result;
-} /* SMAlloc */
-
-static void SMPrint (SatMatrix *matrix) {
-
- unsigned int *p;
- int i, j;
- unsigned NbRows, NbColumns;
-
- fprintf(stderr,"%d %d\n",NbRows=matrix->NbRows, NbColumns=matrix->NbColumns);
- for (i=0;i<NbRows;i++) {
- p = *(matrix->p+i);
- for (j=0;j<NbColumns;j++)
- fprintf(stderr, " %10X ", *p++);
- fprintf(stderr, "\n");
- }
-} /* SMPrint */
-
-
-static void SMFree (SatMatrix *matrix) {
-
- free ((char *) matrix->p_init);
- free ((char *) matrix->p);
- free ((char *) matrix);
- return;
-} /* SMFree */
-
-/* -------------------------------------------------------------------------
- * Shared Global Variables:
- * Used by procedures: Find_m_face, scan_m_face, Poly2Sat, traite_m_face,
- * count_sat
- * -------------------------------------------------------------------------
- */
-static int m; /* number of parameters */
-static int m_dim; /* dimension of m-face */
-static int n; /* dimension (not including parameters) */
-static int ws; /* Working Space size */
-static int nr; /* (NbRays-1)/32 + 1 */
-
-static Polyhedron *CEqualities;/* Equalities in the context */
-static SatMatrix *Sat; /* Saturation Matrix (row=constraint, col=ray)*/
-static unsigned int *egalite; /* Bool vector marking constraints in m-face */
-static Matrix *Xi, *Pi; /* Xi and Pi */
-static Matrix *PiTest; /* Matrix used to test if Pi is full ranked? */
-static Matrix *CTest;
-static Matrix *PiInv; /* Matrix inverse Pi, with the last col of */
- /* each line = denominator of the line */
-static Matrix *RaysDi; /* Constraint matrix for computing Di */
-
-static int KD; /* Flag : keep the full domains in memory ? */
- /* 1 = yes; 0 = no, keep constraints only */
-
-static int nbPV; /* The number of parameterized vertices */
-static Param_Vertices *PV_Result; /* List of parameterized vertices */
-static Param_Domain *PDomains; /* List of domains. */
-
-#ifdef DEBUGPP
-static int nbfaces;
-#endif
-
-/*
- * Add the constraints from the context polyhedron 'CEqualities' to the
- * constraints of polyhedra in the polyhedral domain 'D' and return the new
- * polyhedral domain. Polyhedral domain 'D' is subsequently deleted from memory
- */
-static Polyhedron *Add_CEqualities(Polyhedron *D) {
-
- Polyhedron *d,*r,*tmp;
-
- if(!CEqualities)
- return D;
- else {
- if(!D || emptyQ(D)) {
- if(D)
- Domain_Free(D);
- return(Polyhedron_Copy(CEqualities));
- }
- r = AddConstraints(D->Constraint[0],D->NbConstraints,
- CEqualities,ws);
- tmp = r;
- for(d=D->next;d;d=d->next) {
- tmp->next = AddConstraints(d->Constraint[0],d->NbConstraints,
- CEqualities,ws);
- tmp = tmp->next;
- }
- Domain_Free(D);
- return(r);
- }
-} /* Add_CEqualities */
-
-#define INT_BITS (sizeof(unsigned) * 8)
-
-unsigned int *int_array2bit_vector(unsigned int *array, int n)
-{
- int i, ix;
- unsigned bx;
- int words = (n+INT_BITS-1)/INT_BITS;
- unsigned int *bv = (unsigned int *)calloc(words, sizeof(unsigned));
- assert(bv);
- for (i = 0, ix = 0, bx = MSB; i < n; ++i) {
- if (array[i])
- bv[ix] |= bx;
- NEXT(ix, bx);
- }
- return bv;
-}
-
-/*----------------------------------------------------------------------*/
-/* traite_m_face */
-/* Given an m-face, compute the parameterized vertex */
-/* D - The entire domain */
-/* mf - Bit vector marking the lines/rays in the m-face */
-/* egalite - boolean vector marking saturated constraints in m-face */
-/*----------------------------------------------------------------------*/
-static void traite_m_face(Polyhedron *D, unsigned int *mf,
- unsigned int *egalite)
-{
- Matrix *Si; /* Solution */
- Polyhedron *PDi; /* polyhedron Di */
- Param_Vertices *PV;
- int j,k,c,r;
- unsigned kx, bx;
-
-#ifdef DEBUGPP
- ++nbfaces;
-#endif
-
- /* Extract Xi, Pi, and RaysDi from D */
- RaysDi->NbRows = 0;
- for(k=0,c=0,kx=0,bx=MSB;k<D->NbRays;++k) {
- if(mf[kx]&bx) { /* this ray is in the current m-face */
- if(c<m+1) {
- int i;
-
- /* tester si cette nouvelle colonne est lin. indep. des autres */
- /* i.e. si gauss ne donne pas de '0' sur la colonne Pi */
- /* jusqu'a l'indice 'c' */
-
- /* construit PiTest */
- for(j=0;j<m+1;++j) {
- for(i=0;i<c;++i)
-
- /* les c premieres colonnes */
- value_assign(PiTest->p[j][i],Pi->p[j][i]);
-
- /* la nouvelle */
- value_assign(PiTest->p[j][c],D->Ray[k][j+1+n]);
- }
- PiTest->NbColumns = c+1;
- r = TestRank(PiTest);
- if(r /* TestRank(PiTest) */) {
-
- /* Ok, c'est lin. indep. */
- for (j=0;j<n;j++)
- value_assign(Xi->p[j][c],D->Ray[k][j+1]); /* Xi */
- for (j=0;j<m;j++)
- value_assign(Pi->p[j][c],D->Ray[k][j+1+n]); /* Pi */
- value_assign(Xi->p[n][c],D->Ray[k][n+m+1]); /* const */
- value_assign(Pi->p[m][c],D->Ray[k][n+m+1]); /* const */
- c++;
- }
- }
-
- /* Status bit */
- value_assign(RaysDi->p[RaysDi->NbRows][0],D->Ray[k][0]);
- Vector_Copy(&D->Ray[k][n+1],&RaysDi->p[RaysDi->NbRows][1],(m+1));
- ++RaysDi->NbRows;
- }
- NEXT(kx,bx);
- }
-
-#ifdef DEBUGPP41
- fprintf(stderr, "\nRaysDi=\n");
- Matrix_Print(stderr,P_VALUE_FMT,RaysDi);
- if(c < m+1)
- fprintf(stderr, "Invalid ");
- fprintf(stderr, "Pi=\n");
- Matrix_Print(stderr,P_VALUE_FMT,Pi);
-#endif
-
-#ifdef DEBUGPP4
- if(c < m+1)
- fprintf(stderr,"Eliminated because of no vertex\n");
-#endif
-
- if(c < m+1)
- return;
-
- /* RaysDi->numColumns = m+2; */ /* stays the same */
-
- /* Xi->NbColumns = m+1;*/ /* VIN100: stays the same. was 'c'! */
- /* Xi->NbRows = n+1; */ /* stays the same */
- /* Pi->NbColumns = m+1;*/ /* VIN100: stays the same. was 'c'! */
- /* Pi->NbRows = m+1; */ /* stays the same */
-
-#ifdef DEBUGPP4
- fprintf(stderr,"Xi = ");
- Matrix_Print(stderr,P_VALUE_FMT,Xi);
- fprintf(stderr,"Pi = ");
- Matrix_Print(stderr,P_VALUE_FMT,Pi);
-#endif
-
- /* (Right) invert Pi if POSSIBLE, if not then next m-face */
- /* Pi is destroyed */
- if(!MatInverse(Pi,PiInv)) {
-
-#ifdef DEBUGPP4
- fprintf(stderr, "Eliminated because of no inverse Pi\n");
-#endif
-
- return;
- }
-
-#ifdef DEBUGPP4
- fprintf(stderr,"FACE GENERATED!\n");
- fprintf(stderr,"PiInv = ");
- Matrix_Print(stderr,P_VALUE_FMT,PiInv);
-#endif
-
- /* Compute Si (now called Ti in the paper) */
- Si = Matrix_Alloc(Xi->NbRows,PiInv->NbColumns);
- rat_prodmat(Si,Xi,PiInv);
-
-#ifdef DEBUGPP4
- fprintf(stderr,"Si = ");
- Matrix_Print(stderr,P_VALUE_FMT,Si);
-#endif
-
- Si->NbRows--; /* throw out the last row = 0 ... 0 1 */
-
- /* Copy all of that into the PV structure */
- PV = (Param_Vertices *) malloc(sizeof(Param_Vertices));
- PV->next = PV_Result;
- PV->Vertex = Si;
- PV->Domain = NULL;
- PV->Facets = int_array2bit_vector(egalite, D->NbConstraints);
- PV_Result = PV;
- nbPV++; /* increment vertex count */
-
- /* Ok... now compute the parameter domain */
- PDi = Rays2Polyhedron(RaysDi,ws);
-
-#ifdef DEBUGPP3
- fprintf(stderr,"RaysDi = ");
- Matrix_Print(stderr,P_VALUE_FMT,RaysDi);
- fprintf(stderr,"PDi = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,PDi);
-#endif
-
- if(KD==0) {
-
- /* Add the equalities again to the domain */
- PDi = Add_CEqualities(PDi);
- PV->Domain = Polyhedron2Constraints(PDi);
- Polyhedron_Free(PDi);
- }
- else {
- Param_Domain *PD;
- PD = (Param_Domain *) malloc(sizeof(Param_Domain));
- PD->Domain = PDi;
- PD->F = NULL;
- PD->next = PDomains;
- PDomains = PD;
- }
- return;
-} /* traite_m_face */
-
-/*----------------------------------------------------------------------*/
-/* count_sat */
-/* count the number of saturated rays in the bit vector mf */
-/* Uses nr from global area */
-/*----------------------------------------------------------------------*/
-int cntbit[256] = { /* counts for 8 bits */
-0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
-1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-
-1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-
-1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-
-2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
-4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 };
-
-static int count_sat (unsigned int *mf) {
-
- register unsigned int i, tmp, cnt=0;
-
- for (i=0; i<nr; i++) {
- tmp = mf[i];
- cnt = cnt
- + cntbit[ tmp & 0xff ]
- + cntbit[ (tmp>>8) & 0xff ]
- + cntbit[ (tmp>>16) & 0xff ]
- + cntbit[ (tmp>>24) & 0xff ]
- ;
- }
- return cnt;
-} /* count_sat */
-
-/* Returns true if all bits in part are also set in bv */
-static int bit_vector_includes(unsigned int *bv, int len, unsigned int *part)
-{
- int j;
-
- for (j = 0; j < len; j++) {
-#ifdef DEBUGPP4
- fprintf(stderr, "mf=%08X Sat=%08X &=%08X\n",
- part[j],bv[j], (part[j] & bv[j]));
-#endif
- if ((part[j] & bv[j]) != part[j])
- return 0;
- }
- return 1;
-}
-
-/*----------------------------------------------------------------------*/
-/* let D + E + L be the dimension of the polyhedron */
-/* D = Dimension of polytope (ray space) */
-/* L = Dimension of Lineality space (number of lines, bid) */
-/* E = Dimension of Affine hull (number of equations) */
-/* n = number of data indices */
-/* m = number of parameters */
-/* full domain: */
-/* n + m = D + E + L */
-/* projected domains: */
-/* m = D_m + E_m + L_m */
-/* n = D_n + E_n + L_n */
-/* What dimension M-face, when projected onto parameter space, */
-/* will give an L_m-face? */
-/* What are the conditions? */
-/* - at least one vertex */
-/* - number of rays >= D_m+1 after removal of redundants */
-/* */
-/* dim of face nb saturated constraints nb saturated lines,rays */
-/* ----------- ------------------------ ----------------------- */
-/* (0+L)-face all E eqns + >=D ineq all L lines + 1 ray */
-/* (M+L)-face all E eqns + >=(D-M) ineq all L lines + >=(M+1) rays */
-/* (D+L)-face all E eqns + 0 ineq all L lines + >=(D+1) rays */
-/*----------------------------------------------------------------------*/
-/*----------------------------------------------------------------------*/
-/* scan_m_face */
-/* pos : the next candidate constraint position */
-/* nb_un : number of saturated constraints needed to finish a face */
-/* D : the source polyhedron (context included ) */
-/* mf : bit-array marking rays which are saturated so far */
-/* From Global area: */
-/* ---------------- */
-/* n : number of data indices */
-/* m : number of parameters */
-/* egalite : boolean vector marking saturated constraints in m-face */
-/* Sat : Saturation Matrix (row=constraints, col=rays) */
-/* ws : working space size */
-/* nr : (NbRays-1)/32 + 1 */
-/* */
-/* Recursive function to find the rays and vertices of each m-face */
-/*----------------------------------------------------------------------*/
-static void scan_m_face(int pos,int nb_un,Polyhedron *D,unsigned int *mf) {
- /* pos - the next candidate constraint position */
- /* nb_un - the number of constraints needed to finish a face */
- /* D - the source polyhedron */
- /* mf - (bit vector) marks rays that are saturated so far */
-
- unsigned int *new_mf;
-
-#ifdef DEBUGPP4
- fprintf(stderr,"Start scan_m_face(pos=%d, nb_un=%d, n=%d, m=%d\n",
- pos,nb_un,n,m);
- fprintf(stderr,"mf = ");
- {
- int i;
- for(i=0;i<nr;i++)
- fprintf(stderr,"%08X", mf[i]);
- fprintf(stderr,"\nequality = [");
- for(i=0;i<D->NbConstraints;i++)
- fprintf(stderr," %1d",egalite[i]);
- fprintf(stderr,"]\n");
- }
-#endif
-
- if(nb_un == 0) { /* Base case */
- int i;
-
- /*********** ELIMINATION OF REDUNDANT FACES ***********/
- /* if all these vertices also verify a previous constraint */
- /* which is NOT already selected, we eliminate this face */
- /* This keeps the lexicographically greatest selection */
- for(i=0;i<pos-1;i++)
- {
- if(egalite[i])
- continue; /* already selected */
-
- /* if Sat[i] & mf == mf then it's redundant */
-#ifdef DEBUGPP4
- fprintf(stderr, "Sat[%d]\n", i);
-#endif
- if (bit_vector_includes(Sat->p[i], nr, mf)) {
-#ifdef DEBUGPP4
- fprintf(stderr, "Redundant with constraint %d\n", i);
-#endif
- return; /* it is redundant */
- }
- }
- /********* END OF ELIMINATION OF DEGENERATE FACES *********/
- /* Now check for other constraints that are verified */
- for (i = pos; i < D->NbConstraints; ++i) {
- if (bit_vector_includes(Sat->p[i], nr, mf))
- egalite[i] = 1;
- }
- /* if we haven't found a constraint verified by all */
- /* the rays, its OK, it's a new face. */
- traite_m_face(D, mf, egalite);
- for (i = pos; i < D->NbConstraints; ++i)
- egalite[i] = 0;
- return;
- }
-
- /* See if there are enough constraints left to finish */
- if((pos+nb_un)>D->NbConstraints) return;
-
- /* Recurring part of the procedure */
- /* Add the pos'th constraint, compute new saturation vector */
- {
- int k;
- new_mf = (unsigned int *)malloc(nr*sizeof(unsigned int));
- for (k=0; k<nr; k++)
- new_mf[k] = mf[k] & Sat->p[pos][k];
- }
-#ifdef DEBUGPP4
-fprintf(stderr,"new_mf = ");
- {
- int i;
- for(i=0;i<nr;i++) {
- fprintf(stderr,"%08X", new_mf[i]);
- }
- fprintf(stderr,"\ncount(new_mf) = %d\n",count_sat(new_mf));
- }
-#endif
-
- {
- int c;
- c = count_sat(new_mf);
- /* optimization : at least m_dim+1 rays must be saturated to add this constraint */
- if (c>m_dim )
- {
- int redundant = 0;
-
- egalite[pos]=1; /* Try it with the pos-th constraint */
-
- /* If this constraint does not change anything,
- * it is redundant with respect to the selected
- * equalities and the remaining inequalities.
- * Check whether it is redundant with respect
- * to just the selected equalities.
- */
- if( c==count_sat(mf) ) {
- int i, c, j;
-
- for (i = 0, c = 0; i < D->NbConstraints; ++i) {
- if (egalite[i] == 0 || egalite[i] == -1)
- continue;
- for (j = 0; j < D->Dimension+1; ++j)
- value_assign(CTest->p[j][c],
- D->Constraint[i][j+1]);
- ++c;
- }
- CTest->NbColumns = c;
-#ifdef DEBUGPP41
- Matrix_Print(stderr,P_VALUE_FMT,CTest);
-#endif
- redundant = !TestRank(CTest);
- }
-
- /* Do not decrement nb_un if equality is redundant. */
- if( redundant )
- {
- egalite[pos]=-1; /* Don't use in further redundance test
- */
- scan_m_face(pos+1,nb_un,D,new_mf);
- }
- else
- {
- scan_m_face(pos+1,nb_un-1,D,new_mf);
- }
- }
- }
- free(new_mf);
- egalite[pos]=0; /* Try it without the pos-th constraint */
- if ((pos+nb_un)>=D->NbConstraints) return;
- scan_m_face(pos+1,nb_un,D,mf);
- return;
-} /* scan_m_face */
-
-/*
- * Create a saturation matrix with rows correspond to the constraints and
- * columns correspond to the rays of the polyhedron 'Pol'. Global variable
- * 'nr' is set in the function.
- */
-static SatMatrix *Poly2Sat(Polyhedron *Pol,unsigned int **L) {
-
- SatMatrix *Sat;
- int i, j, k, kx;
- unsigned int *Temp;
- Value *p1, *p2, p3,tmp;
- unsigned Dimension, NbRay, NbCon, bx;
-
- /* Initialize all the 'Value' variables */
- value_init(p3); value_init(tmp);
-
- NbRay = Pol->NbRays;
- NbCon = Pol->NbConstraints;
- Dimension = Pol->Dimension+1; /* Homogeneous Dimension */
-
- /* Build the Sat matrix */
- nr = (NbRay - 1)/(sizeof(int)*8) + 1; /* Set globally */
- Sat = SMAlloc(NbCon,nr);
- Temp = (unsigned int *)malloc(nr*sizeof(unsigned int));
- memset(Sat->p_init,0,nr*NbCon*sizeof(int));
- memset(Temp,0,nr*sizeof(unsigned int));
- kx=0; bx=MSB;
- for (k=0; k<NbRay; k++) {
- for (i=0; i<NbCon; i++) {
- p1 = &Pol->Constraint[i][1];
- p2 = &Pol->Ray[k][1];
- value_set_si(p3,0);
- for (j=0;j<Dimension;j++) {
- value_multiply(tmp,*p1,*p2);
- value_addto(p3,p3,tmp);
- p1++; p2++;
- }
- if (value_zero_p(p3))
- Sat->p[i][kx]|=bx;
- }
- Temp[kx] |= bx;
- NEXT(kx, bx);
- }
-
- /* Set 'L' to an array containing ones in every bit position of its */
- /* elements. */
- *L = Temp;
-
- /* Clear all the 'Value' variables */
- value_clear(p3); value_clear(tmp);
-
- return Sat;
-} /* Poly2Sat */
-
-/*
- * Create a parametrized polyhedron with zero parameters. This function was
- * first written by Xavier Redon, and was later modified by others.
- */
-Param_Polyhedron *GenParamPolyhedron(Polyhedron *Pol, Matrix *Rays)
-{
- Param_Polyhedron *result;
- int nbRows, nbColumns;
- int i, size, rays;
-
- nbRows=Pol->NbRays;
- nbColumns=Pol->Dimension+2;
-
- /* Count the number of rays */
- for(i=0, rays=0; i<nbRows; i++)
- if(value_notone_p(Pol->Ray[i][0]) ||
- value_zero_p(Pol->Ray[i][nbColumns-1]))
- ++rays;
-
- /* Initialize the result */
- result=(Param_Polyhedron *)malloc(sizeof(Param_Polyhedron));
- result->nbV=nbRows-rays;
- result->V=NULL;
- result->Constraints = Polyhedron2Constraints(Pol);
- result->Rays = Rays;
-
- /* Build the parametric vertices */
- for(i=0;i<nbRows;i++) {
- Matrix *vertex;
- Param_Vertices *paramVertex;
- int j;
-
- if (value_notone_p(Pol->Ray[i][0]) ||
- value_zero_p(Pol->Ray[i][nbColumns-1]))
- continue;
-
- vertex=Matrix_Alloc(nbColumns-2,2);
- for(j=1;j<nbColumns-1;j++) {
- value_assign(vertex->p[j-1][0],Pol->Ray[i][j]);
- value_assign(vertex->p[j-1][1],Pol->Ray[i][nbColumns-1]);
- }
- paramVertex=(Param_Vertices *)malloc(sizeof(Param_Vertices));
- paramVertex->Vertex=vertex;
-
- /* There is one validity domain : universe of dimension 0 */
- paramVertex->Domain=Matrix_Alloc(1,2);
- value_set_si(paramVertex->Domain->p[0][0],1);
- value_set_si(paramVertex->Domain->p[0][1],1);
- paramVertex->Facets = NULL;
- paramVertex->next=result->V;
- result->V=paramVertex;
- }
-
- /* Build the parametric domains (only one here) */
- if (nbRows > 1)
- size=(nbRows-1)/(8*sizeof(int))+1;
- else
- size = 1;
- result->D=(Param_Domain *)malloc(sizeof(Param_Domain));
- result->D->next=NULL;
- result->D->Domain=Universe_Polyhedron(0);
- result->D->F=(unsigned int *)malloc(size*sizeof(int));
- memset(&result->D->F[0],0xFF,size*sizeof(int));
-
- return result;
-} /* GenParamPolyhedron */
-
-
-/*----------------------------------------------------------------------*/
-/* PreElim_Columns */
-/* function being called before Elim_Columns */
-/* Equalities in E are analysed to initialize ref and p. */
-/* These two vectors are used to construct the new constraint matrix */
-/* PreElim_Columns returns the transformation matrix to re-convert the */
-/* resulting domains in the same format (by adding empty columns) */
-/* in the parameter space */
-/*----------------------------------------------------------------------*/
-Matrix *PreElim_Columns(Polyhedron *E,int *p,int *ref,int m) {
-
- int i,j,l;
- Matrix *T;
-
- /* find which columns to eliminate */
- /* p contains, for each line in E, the column to eliminate */
- /* (i.e. the corresponding parameter index to eliminate) */
- /* 0 <= i <= E->NbEq, and 1 <= p[i] <= E->Dimension */
- memset(p,0,sizeof(int)*(E->NbEq));
-
-#ifdef DEBUGPP32
- fprintf(stderr,"\n\nPreElim_Columns starting\n");
- fprintf(stderr,"E =\n");
- Polyhedron_Print(stderr,P_VALUE_FMT,E);
-#endif
-
- for(l=0;l<E->NbEq;++l) {
- if(value_notzero_p(E->Constraint[l][0])) {
- fprintf(stderr,"Internal error: Elim_Columns (polyparam.c), expecting equalities first in E.\n");
- free(p);
- return(NULL);
- }
- for(i=1;value_zero_p(E->Constraint[l][i]);++i) {
- if(i==E->Dimension+1) {
- fprintf(stderr,"Internal error: Elim_Columns (polyparam.c), expecting non-empty constraint in E.\n");
- free(p);
- return( NULL );
- }
- }
- p[l] = i;
-
-#ifdef DEBUGPP32
- fprintf(stderr,"p[%d] = %d,",l,p[l]);
-#endif
- }
-
- /* Reference vector: column ref[i] in A corresponds to column i in M */
- for(i=0;i<E->Dimension+2-E->NbEq;++i) {
- ref[i]=i;
- for(j=0;j<E->NbEq;++j)
- if(p[j]<=ref[i])
- ref[i]++;
-
-#ifdef DEBUGPP32
- fprintf(stderr,"ref[%d] = %d,",i,ref[i]);
-#endif
- }
-
- /* Size of T : phdim-nbEq * phdim */
- T = Matrix_Alloc(m+1-E->NbEq,m+1);
- for(i=0;i<T->NbColumns;i++)
- for(j=0;j<T->NbRows;j++)
- if(ref[E->Dimension-m+j+1] == E->Dimension-m+i+1)
- value_set_si(T->p[j][i],1);
- else
- value_set_si(T->p[j][i],0);
-
-#ifdef DEBUGPP32
- fprintf(stderr,"\nTransMatrix =\n");
- Matrix_Print(stderr,P_VALUE_FMT,T);
-#endif
-
- return(T);
-
-} /* PreElim_Columns */
-
-/*----------------------------------------------------------------------*/
-/* Elim_Columns */
-/* Eliminate columns from A, using the equalities in E. */
-/* ref and p are precalculated by PreElim_Columns, using E; */
-/* these two vectors are used to construct the new constraint matrix */
-/*----------------------------------------------------------------------*/
-Polyhedron *Elim_Columns(Polyhedron *A,Polyhedron *E,int *p,int *ref) {
-
- int i,l,c;
- Matrix *M, *C;
- Polyhedron *R;
- Value tmp1,tmp2;
-
- /* Initialize all the 'Value' variables */
- value_init(tmp1); value_init(tmp2);
-
-#ifdef DEBUGPP32
- fprintf(stderr,"\nElim_Columns starting\n");
- fprintf(stderr,"A =\n" );
- Polyhedron_Print(stderr,P_VALUE_FMT,A);
-#endif
-
- /* Builds M = constraint matrix of A, useless columns zeroed */
- M = Polyhedron2Constraints(A);
- for(l=0;l<E->NbEq;++l) {
- for(c=0;c<M->NbRows;++c) {
- if(value_notzero_p(M->p[c][p[l]])) {
-
- /* A parameter to eliminate here ! */
- for(i=1;i<M->NbColumns;++i) {
- value_multiply(tmp1,M->p[c][i],E->Constraint[l][p[l]]);
- value_multiply(tmp2,E->Constraint[l][i],M->p[c][p[l]]);
- value_subtract(M->p[c][i],tmp1,tmp2);
- }
- }
- }
- }
-
-#ifdef DEBUGPP32
- fprintf(stderr,"\nElim_Columns after zeroing columns of A.\n");
- fprintf(stderr,"M =\n");
- Matrix_Print(stderr,P_VALUE_FMT,M);
-#endif
-
- /* Builds C = constraint matrix, useless columns eliminated */
- C = Matrix_Alloc(M->NbRows,M->NbColumns - E->NbEq);
- for(l=0;l<C->NbRows;++l)
- for(c=0;c<C->NbColumns;++c) {
- value_assign(C->p[l][c],M->p[l][ref[c]]);
- }
-
-#ifdef DEBUGPP32
- fprintf(stderr,"\nElim_Columns after eliminating columns of A.\n");
- fprintf(stderr,"C =\n");
- Matrix_Print(stderr,P_VALUE_FMT,C);
-#endif
-
- R = Constraints2Polyhedron(C,ws);
- Matrix_Free(C);
- Matrix_Free(M);
- value_clear(tmp1); value_clear(tmp2);
- return(R);
-} /* Elim_Columns */
-
-
-static Polyhedron *Recession_Cone(Polyhedron *P, unsigned nvar, unsigned MaxRays)
-{
- int i;
- Matrix *M = Matrix_Alloc(P->NbConstraints, 1 + nvar + 1);
- Polyhedron *R;
- for (i = 0; i < P->NbConstraints; ++i)
- Vector_Copy(P->Constraint[i], M->p[i], 1+nvar);
- R = Constraints2Polyhedron(M, MaxRays);
- Matrix_Free(M);
- return R;
-}
-
-/* Compute lines/unidirectional rays of the (non parametric) polyhedron */
-/* Input :
- * D1 : combined polyhedron,
- * Output :
- * Rays : non parametric ray matrix
- * return value : number of lines
- */
-static int ComputeNPLinesRays(int n, Polyhedron *D1, Matrix **Rays)
-{
- int i, j, nbr, dimfaces;
- Polyhedron *RC; /* Recession Cone */
-
- RC = Recession_Cone(D1, n, ws);
-
- /* get the rays/lines from RC */
- nbr = 0;
- for (i = 0; i < RC->NbRays ;i++)
- if (value_zero_p(RC->Ray[i][n+1]))
- nbr++;
- *Rays=Matrix_Alloc(nbr, n+2);
- for (i = 0, j = 0; j < nbr ;i++)
- if (value_zero_p(RC->Ray[i][n+1]))
- Vector_Copy(RC->Ray[i], (*Rays)->p[j++], n+2);
-
- dimfaces = RC->NbBid;
- Polyhedron_Free(RC);
-
-#ifdef DEBUGPP31
- fprintf(stderr, "Rays = ");
- Matrix_Print(stderr, P_VALUE_FMT, *Rays);
- fprintf(stderr, "dimfaces = %d\n", dimfaces);
-#endif
-
- return dimfaces;
-}
-
-/*
- * Given a polyhedron 'Di' in combined data and parameter space and a context
- * polyhedron 'C' representing the constraints on the parameter space, create
- * a list of parameterized vertices and assign values to global variables:
- * m,n,ws,Sat,egalite,mf,Xi,Pi,PiInv,RaysDi,CEqualities.
- */
-Param_Polyhedron *Find_m_faces(Polyhedron **Di,Polyhedron *C,int keep_dom,int working_space,Polyhedron **CEq,Matrix **CT) {
-
- unsigned int *mf;
- int i, j, dimfaces;
- Polyhedron *D=*Di,
- *C1, /* true context */
- *D1; /* the combined polyhedron, including context C */
- Matrix *Rays, /* lines/rays (non parametric) */
- *M;
- Param_Polyhedron *res;
- int *p, *ref;
-
- CEqualities = NULL;
-
- if(CT) {
- *CEq = NULL;
- *CT = NULL;
- }
-
- if(!D || !C)
- return (Param_Polyhedron *) 0;
-
- ws = working_space;
- m = C->Dimension;
- n = D->Dimension - m;
- if(n<0) {
- fprintf(stderr,
- "Find_m_faces: ?%d parameters of a %d-polyhedron !\n",m,n);
- return (Param_Polyhedron *) 0;
- }
- if (m==0)
- return GenParamPolyhedron(D,Matrix_Alloc(0,2));
-
- /* Add constraints from Context to D -> result in D1 */
- C1 = align_context(C,D->Dimension,ws);
-
-#ifdef DEBUGPP31
- fprintf(stderr,"m = %d\n",m);
- fprintf(stderr, "D = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,D);
- fprintf(stderr,"C1 = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,C1);
-#endif
-
- D1 = DomainIntersection(D,C1,ws);
-
-#ifdef DEBUGPP31
- fprintf(stderr,"D1 = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,D1);
-#endif
-
- Domain_Free(C1);
-
- if (!D1)
- return(NULL);
- if (emptyQ(D1)) {
- Polyhedron_Free(D1);
- return(NULL);
- }
-
- /* Compute the true context C1 */
- /* M : lines in the direction of the first n indices (index space) */
- M = Matrix_Alloc(n, D1->Dimension+2);
- for (i=0; i<n; i++)
- value_set_si(M->p[i][i+1],1);
- C1 = DomainAddRays(D1,M,ws);
- Matrix_Free(M);
-
-#ifdef DEBUGPP31
- fprintf(stderr,"True context C1 = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,C1);
-#endif
-
- dimfaces = ComputeNPLinesRays(n, D1, &Rays);
-
- /* CEqualities contains the constraints (to be added again later) */
- /* *CT is the transformation matrix to add the removed parameters */
- if(!CT) {
- if (C1->NbEq == 0) {
- Polyhedron_Free(C1);
- C1 = NULL;
- } else {
- Polyhedron *CEq1, /* CEqualities, in homogeneous dim */
- *D2; /* D1, (temporary) simplified */
-
- /* Remove equalities from true context C1 and from D1 */
- /* Compute CEqualities = matrix of equalities in C1, projected in */
- /* the parameter space */
- M = Matrix_Alloc(C1->NbEq,m+2);
- for(j=0,i=0;i<C1->NbEq;++i,++j) {
- while(value_notzero_p(C1->Constraint[j][0]))
- ++j;
- value_assign(M->p[i][0],C1->Constraint[j][0]);
- Vector_Copy(&C1->Constraint[j][D->Dimension-m+1],&M->p[i][1],(m+1));
- }
- CEqualities = Constraints2Polyhedron(M,ws);
- Matrix_Free(M);
- CEq1 = align_context(CEqualities,D->Dimension,ws);
-
- /* Simplify D1 and C1 (remove the equalities) */
- D2 = DomainSimplify(D1,CEq1,ws);
- Polyhedron_Free(D1);
- Polyhedron_Free(C1);
- Polyhedron_Free(CEq1);
- D1 = D2;
- C1 = NULL;
- }
- }
- else { /* if( CT ) */
- Polyhedron *CEq1, /* CEqualities */
- *D2; /* D1, (temporary) simplified */
-
- /* Suppress all useless constraints in parameter domain */
- /* when CT is not NULL (ehrhart) */
- /* Vin100, march 01 */
- CEq1 = C1;
- M = Matrix_Alloc(C1->NbConstraints,m+2);
- for(i=0;i<C1->NbConstraints;++i) {
- value_assign(M->p[i][0],C1->Constraint[i][0]);
- Vector_Copy(&C1->Constraint[i][D->Dimension-m+1],&M->p[i][1],(m+1));
- }
- CEqualities = Constraints2Polyhedron( M, ws );
- Matrix_Free(M);
-
- D2 = DomainSimplify(D1,CEq1,ws);
- Polyhedron_Free(D1);
- D1 = D2;
- C1 = Universe_Polyhedron(D2->Dimension);
-
- /* if CT is not NULL, the constraints are eliminated */
- /* *CT will contain the transformation matrix to come back to the */
- /* original dimension (for a polyhedron, in the parameter space) */
- if( CEq1->NbEq )
- {
- m -= CEq1->NbEq;
- p = (int *)malloc(sizeof(int)*(CEq1->NbEq));
- }
- else
- p = NULL;
- ref = (int*) malloc(sizeof(int)*
- (CEq1->Dimension+2-CEq1->NbEq));
- *CT = PreElim_Columns(CEq1,p,ref,CEqualities->Dimension);
- D2 = Elim_Columns(D1,CEq1,p,ref);
- if (p)
- free(p);
- free(ref);
-
-#ifdef DEBUGPP3
- fprintf(stderr,"D2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n",
- D2->Dimension,D2->NbEq,D2->NbBid);
- C2 = Elim_Columns(C1,CEq1,p,ref);
- fprintf(stderr,"C2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n",
- C2->Dimension,C2->NbEq,C2->NbBid);
- Polyhedron_Free(C2);
-#endif
-
- Polyhedron_Free(D1);
- Polyhedron_Free(C1);
- D1 = D2;
- C1 = NULL;
- *CEq = CEqualities;
-
-#ifdef DEBUGPP3
- fprintf(stderr,"Polyhedron CEq = ");
- Polyhedron_Print(stderr,P_VALUE_FMT,*CEq);
- fprintf(stderr,"Matrix CT = ");
- Matrix_Print(stderr,P_VALUE_FMT,*CT);
-#endif
-
- Polyhedron_Free(CEq1);
- CEqualities = NULL; /* don't simplify ! */
-
- /* m changed !!! */
- if(m==0) {
- /* return the new D1 too */
- *Di = D1;
-
- return GenParamPolyhedron(D1, Rays);
- }
- }
-
-#ifdef DEBUGPP3
- fprintf(stderr,"Polyhedron D1 (D AND C) = ");
- Polyhedron_Print(stderr,P_VALUE_FMT, D1);
- fprintf(stderr,"Polyhedron CEqualities = ");
- if(CEqualities) Polyhedron_Print(stderr,P_VALUE_FMT, CEqualities);
- else fprintf(stderr,"NULL\n");
-#endif
-
- KD = keep_dom;
- PDomains = NULL;
- PV_Result = NULL;
- nbPV = 0;
-
- if (emptyQ(D1)) {
- Polyhedron_Free(D1);
- Matrix_Free(Rays);
- return NULL;
- }
-
- /* mf : a bit array indicating which rays are part of the m-face */
- /* Poly2Sat initializes mf to all ones */
- /* set global variable nr to size (number of words) of mf */
- Sat = Poly2Sat(D1,&mf);
-
-#ifdef DEBUGPP4
- fprintf(stderr,"Sat = ");
- SMPrint(Sat);
-
- fprintf(stderr,"mf = ");
- for (i=0; i<nr; i++)
- fprintf(stderr,"%08X", mf[i]);
- fprintf(stderr, "\n");
-#endif
-
- /* A boolean array saying which constraints are part of the m-face */
- egalite = (unsigned int *)malloc(sizeof(int)*D1->NbConstraints);
- memset(egalite,0, sizeof(int)*D1->NbConstraints);
-
- for (i=0; i<D1->NbEq; i++)
- egalite[i] = 1;
-
- Xi = Matrix_Alloc(n+1,m+1);
- Pi = Matrix_Alloc(m+1,m+1);
- PiTest = Matrix_Alloc(m+1,m+1);
- CTest = Matrix_Alloc(D->Dimension+1,D->NbConstraints);
- PiInv = Matrix_Alloc(m+1,m+2);
- RaysDi = Matrix_Alloc(D1->NbRays,m+2);
- m_dim = m;
-
- /* m_dim has to be increased by the dimension of the smallest faces
- * of the (non parametric) polyhedron
- */
- m_dim += dimfaces;
-
- /* if the smallest face is of smaller dimension than m_dim,
- * then increase m_dim (I think this should never happen --Vincent)
- */
-#ifdef DEBUGPP3
- if (m_dim < D1->NbBid)
- fprintf(stderr, "m_dim (%d) < D1->NbBid (%d)\n", m_dim, D1->NbBid );
-#endif
- if (m_dim < D1->NbBid)
- m_dim = D1->NbBid;
-
-#ifdef DEBUGPP
- nbfaces=0;
-#endif
-#ifdef DEBUGPP3
- fprintf(stderr, "m_dim = %d\n", m_dim);
- fprintf(stderr,
- "Target: find faces that saturate %d constraints and %d rays/lines\n",
- D1->Dimension - m_dim,m_dim+1);
-#endif
-
- /* D1->NbEq constraints already saturated ! */
- scan_m_face(D1->NbEq,(D1->Dimension - m_dim - D1->NbEq),D1,mf);
-
- /* pos, number of constraints needed */
-
-#ifdef DEBUGPP
- fprintf( stderr, "Number of m-faces: %d\n", nbfaces );
-#endif
-
- Matrix_Free(RaysDi);
- Matrix_Free(PiInv);
- Matrix_Free(PiTest);
- Matrix_Free(CTest);
- Matrix_Free(Pi);
- Matrix_Free(Xi);
- free(egalite);
- free(mf);
- SMFree(Sat);
-
- /* if(CEqualities && keep_dom==0) {
- Domain_Free(CEqualities);
- }
- */
-
- res = (Param_Polyhedron *) malloc (sizeof(Param_Polyhedron));
- res->nbV = nbPV;
- res->V = PV_Result;
- res->D = PDomains;
- res->Constraints = Polyhedron2Constraints(D1);
- res->Rays = Rays;
-
- if(CT) /* return the new D1 too ! */
- *Di = D1;
- else
- Domain_Free(D1);
-
- return(res);
-} /* Find_m_faces */
-
-/*
- * Given parametric domain 'PD' and number of parametric vertices 'nb_domains',
- * find the vertices that belong to distinct sub-domains.
- */
-void Compute_PDomains(Param_Domain *PD,int nb_domains,int working_space) {
-
- unsigned bx;
- int i, ix, nv;
- Polyhedron *dx, *d1, *d2;
- Param_Domain *p1, *p2, *p2prev, *PDNew;
-
- if (nb_domains==0) {
-
-#ifdef DEBUGPP5
- fprintf(stderr,"No domains\n");
-#endif
-
- return;
- }
-
- /* Already filled out by GenParamPolyhedron */
- if (!PD->next && PD->F)
- return;
-
- /* Initialization */
- nv = (nb_domains - 1)/(8*sizeof(int)) + 1;
-
-#ifdef DEBUGPP5
- fprintf(stderr,"nv = %d\n",nv);
-#endif
-
- for(p1=PD,i=0,ix=0,bx=MSB;p1;p1=p1->next,i++) {
-
- /* Assign a bit array 'p1->F' of suitable size to include the vertices */
- p1->F = (unsigned *) malloc (nv * sizeof(unsigned));
-
- /* Set the bit array to zeros */
- memset(p1->F,0,nv * sizeof(unsigned));
- p1->F[ix] |= bx; /* Set i'th bit to one */
- NEXT(ix, bx);
- }
-
-#ifdef DEBUGPP5
- fprintf(stderr,"nb of vertices=%d\n",i);
-#endif
-
- /* Walk the PD list with two pointers */
- ix = 0; bx=MSB;
- for (p1=PD;p1;p1=p1->next) {
- for (p2prev=p1,p2=p1->next;p2;p2prev=p2,p2=p2->next) {
-
- /* Find intersection */
- dx = PDomainIntersection(p1->Domain,p2->Domain,working_space);
-
- if (!dx || emptyQ(dx)) {
-
-#ifdef DEBUGPP5
- fprintf( stderr, "Empty dx (p1 inter p2). Continuing\n");
-#endif
- if(dx)
- Domain_Free(dx);
- continue;
- }
-
-#ifdef DEBUGPP5
- fprintf(stderr,"Begin PDomainDifference\n");
- fprintf(stderr, "p1=");
- Polyhedron_Print(stderr,P_VALUE_FMT,p1->Domain);
- fprintf(stderr,"p2=");
- Polyhedron_Print(stderr,P_VALUE_FMT,p2->Domain);
-#endif
- d1 = PDomainDifference(p1->Domain,p2->Domain,working_space);
- d2 = PDomainDifference(p2->Domain,p1->Domain,working_space);
-
-#ifdef DEBUGPP5
- fprintf(stderr,"p1\\p2=");
- Polyhedron_Print(stderr,P_VALUE_FMT,d1);
- fprintf(stderr,"p2\\p1=");
- Polyhedron_Print(stderr,P_VALUE_FMT,d2);
- fprintf(stderr,"END PDomainDifference\n\n");
-#endif
- if (!d1 || emptyQ(d1) || d1->NbEq!=0) {
-
-#ifdef DEBUGPP5
- fprintf(stderr,"Empty d1\n");
-#endif
- if (d1)
- Domain_Free(d1);
- Domain_Free(dx);
-
- if (!d2 || emptyQ(d2) || d2->NbEq!=0) {
-
-#ifdef DEBUGPP5
- fprintf( stderr, "Empty d2 (deleting)\n");
-#endif
- /* dx = p1->Domain = p2->Domain */
- if (d2) Domain_Free(d2);
-
- /* Update p1 */
- for (i=0;i<nv;i++)
- p1->F[i] |= p2->F[i];
-
- /* Delete p2 */
- p2prev->next = p2->next;
- Domain_Free(p2->Domain);
- free(p2->F);
- free(p2);
- p2 = p2prev;
- }
- else { /* d2 is not empty --> dx==p1->domain */
-
-#ifdef DEBUGPP5
- fprintf( stderr, "p2 replaced by d2\n");
-#endif
- /* Update p1 */
- for(i=0;i<nv;i++)
- p1->F[i] |= p2->F[i];
-
- /* Replace p2 with d2 */
- Domain_Free( p2->Domain );
- p2->Domain = d2;
- }
- }
- else { /* d1 is not empty */
- if (!d2 || emptyQ(d2) || d2->NbEq!=0) {
-
-#ifdef DEBUGPP5
- fprintf( stderr, "p1 replaced by d1\n");
-#endif
- if (d2) Domain_Free(d2);
-
- /* dx = p2->domain */
- Domain_Free(dx);
-
- /* Update p2 */
- for(i=0;i<nv;i++)
- p2->F[i] |= p1->F[i];
-
- /* Replace p1 with d1 */
- Domain_Free(p1->Domain);
- p1->Domain = d1;
- }
- else { /*d2 is not empty-->d1,d2,dx are distinct */
-
-#ifdef DEBUGPP5
- fprintf(stderr,"Non-empty d1 and d2\nNew node created\n");
-#endif
- /* Create a new node for dx */
- PDNew = (Param_Domain *) malloc( sizeof(Param_Domain) );
- PDNew->F = (unsigned int *)malloc( nv*sizeof(int) );
- memset(PDNew->F,0,nv*sizeof(int));
- PDNew->Domain = dx;
-
- for (i=0;i<nv;i++)
- PDNew->F[i] = p1->F[i] | p2->F[i];
-
- /* Replace p1 with d1 */
- Domain_Free( p1->Domain );
- p1->Domain = d1;
-
- /* Replace p2 with d2 */
- Domain_Free( p2->Domain );
- p2->Domain = d2;
-
- /* Insert new node after p1 */
- PDNew->next = p1->next;
- p1->next = PDNew;
- }
- }
- } /* end of p2 scan */
- if (p1->Domain->next) {
- Polyhedron *C = DomainConvex(p1->Domain, working_space);
- Domain_Free(p1->Domain);
- p1->Domain = C;
- }
- } /* end of p1 scan */
-} /* Compute_PDomains */
-
-/*
- * Given a polyhedron 'Din' in combined data and parametre space, a context
- * polyhedron 'Cin' representing the constraints on the parameter space and
- * a working space size 'working_space', return a parametric polyhedron with
- * a list of parametric vertices and their defining domains.
- */
-Param_Polyhedron *Polyhedron2Param_Vertices(Polyhedron *Din,Polyhedron *Cin,int working_space) {
-
- Param_Polyhedron *result;
-
- POL_ENSURE_FACETS(Din);
- POL_ENSURE_VERTICES(Din);
- POL_ENSURE_FACETS(Cin);
- POL_ENSURE_VERTICES(Cin);
-
-#ifdef DEBUGPP
- fprintf(stderr,"Polyhedron2Param_Vertices algorithm starting at : %.2fs\n",
- (float)clock()/CLOCKS_PER_SEC);
-#endif
-
- /***************** Scan the m-faces ****************/
- result = Find_m_faces(&Din,Cin,0,working_space,NULL,NULL);
-
-#ifdef DEBUGPP
- fprintf(stderr, "nb of points : %d\n",result->nbV);
-#endif
-
-#ifdef DEBUGPP
- fprintf(stderr, "end main loop : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
-#endif
-
- return(result);
-} /* Polyhedron2Param_Vertices */
-
-/*
- * Free the memory allocated to a list of parametrized vertices
- */
-void Param_Vertices_Free(Param_Vertices *PV) {
-
- Param_Vertices *next_pv;
-
- while(PV) {
- next_pv = PV->next;
- if (PV->Vertex) Matrix_Free(PV->Vertex);
- if (PV->Domain) Matrix_Free(PV->Domain);
- if (PV->Facets) free(PV->Facets);
- free(PV);
- PV = next_pv;
- }
-} /* Param_Vertices_Free */
-
-/*
- * Print a list of parametrized vertices *
- */
-void Print_Vertex(FILE *DST, Matrix *V, const char **param_names)
-{
- int l, v;
- int first;
- Value gcd,tmp;
-
- value_init(gcd); value_init(tmp);
-
- fprintf(DST, "[" );
- for(l=0;l<V->NbRows;++l){
-
- /* Variables */
- first=1;
- fprintf(DST, " " );
- for(v=0;v < V->NbColumns-2;++v) {
- if(value_notzero_p(V->p[l][v])) {
- value_gcd(gcd, V->p[l][v], V->p[l][V->NbColumns-1]);
- value_divexact(tmp, V->p[l][v], gcd);
- if(value_posz_p(tmp)) {
- if(!first)
- fprintf(DST, "+");
- if(value_notone_p(tmp)) {
- value_print(DST,VALUE_FMT,tmp);
- }
- }
- else { /* V->p[l][v]/gcd<0 */
- if(value_mone_p(tmp))
- fprintf(DST, "-" );
- else {
- value_print(DST,VALUE_FMT,tmp);
- }
- }
- value_divexact(tmp, V->p[l][V->NbColumns-1], gcd);
- if(value_notone_p(tmp)) {
- fprintf(DST, "%s/", param_names[v]);
- value_print(DST,VALUE_FMT,tmp);
- }
- else
- fprintf(DST, "%s", param_names[v]);
- first=0;
- }
- }
-
- /* Constant */
- if(value_notzero_p(V->p[l][v]) || first) {
- if(value_posz_p(V->p[l][v]) && !first)
- fprintf(DST,"+");
- value_gcd(gcd, V->p[l][v], V->p[l][V->NbColumns-1]);
- value_divexact(tmp, V->p[l][v], gcd);
- value_print(DST,VALUE_FMT,tmp);
- value_divexact(tmp, V->p[l][V->NbColumns-1], gcd);
- if(value_notone_p(tmp)) {
- fprintf(DST,"/");
- value_print(DST,VALUE_FMT,tmp);
- fprintf(DST," ");
- }
- }
- if (l<V->NbRows-1)
- fprintf(DST, ", ");
- }
- fprintf(DST, " ]");
- value_clear(gcd); value_clear(tmp);
- return;
-} /* Print_Vertex */
-
-/*----------------------------------------------------------------------*/
-/* VertexCT */
-/* convert a paramvertex from reduced space to normal m-space */
-/*----------------------------------------------------------------------*/
-Matrix *VertexCT(Matrix *V,Matrix *CT) {
-
- Matrix *Vt;
- int i,j,k;
-
- if(CT) {
-
- /* Have to transform the vertices to original dimension */
- Vt = Matrix_Alloc(V->NbRows,CT->NbColumns+1);
- for(i=0;i<V->NbRows;++i) {
- value_assign(Vt->p[i][CT->NbColumns],V->p[i][V->NbColumns-1]);
- for(j=0;j<CT->NbColumns;j++) {
- for(k=0;k<CT->NbRows;k++)
- if(value_notzero_p(CT->p[k][j]))
- break;
- if(k<CT->NbRows)
- value_assign(Vt->p[i][j],V->p[i][k]);
- else
- value_set_si(Vt->p[i][j],0);
- }
- }
- return(Vt);
- }
- else
- return(NULL);
-} /* VertexCT */
-
-/*
- * Print the validity Domain 'D' of a parametric polyhedron
- */
-void Print_Domain(FILE *DST, Polyhedron *D, const char **pname)
-{
- int l, v;
- int first;
-
- POL_ENSURE_FACETS(D);
- POL_ENSURE_VERTICES(D);
-
- for(l=0;l<D->NbConstraints;++l) {
- fprintf(DST, " ");
- first = 1;
- for(v=1;v<=D->Dimension;++v) {
- if(value_notzero_p(D->Constraint[l][v])) {
- if(value_one_p(D->Constraint[l][v])) {
- if(first)
- fprintf(DST, "%s ", pname[v-1]);
- else
- fprintf(DST, "+ %s ", pname[v-1] );
- }
- else if(value_mone_p(D->Constraint[l][v]))
- fprintf(DST, "- %s ", pname[v-1] );
- else {
- if(value_pos_p(D->Constraint[l][v]) && !first )
- fprintf(DST, "+ " );
- value_print(DST,VALUE_FMT,D->Constraint[l][v]);
- fprintf(DST,"%s ",pname[v-1]);
- }
- first = 0;
- }
- }
- if(value_notzero_p(D->Constraint[l][v])) {
- if(value_pos_p(D->Constraint[l][v]) && !first)
- fprintf(DST,"+");
- fprintf(DST," ");
- value_print(DST,VALUE_FMT,D->Constraint[l][v]);
- }
- fprintf(DST,(value_notzero_p(D->Constraint[l][0])) ?" >= 0":" = 0");
- fprintf(DST, "\n" );
- }
- fprintf(DST, "\n");
-
- if( D->next )
- {
- fprintf( DST, "UNION\n" );
- Print_Domain( DST, D->next, pname );
- }
- return;
-} /* Print_Domain */
-
-/*
- * Given a list of parametrized vertices and an array of parameter names, Print
- * a list of parametrized vertices in a comprehensible format.
- */
-void Param_Vertices_Print(FILE *DST, Param_Vertices *PV, const char **param_names)
-{
- Polyhedron *poly;
-
- while(PV) {
- fprintf(DST, "Vertex :\n" );
- Print_Vertex(DST,PV->Vertex,param_names);
-
- /* Pour le domaine : */
- fprintf(DST, " If :\n" );
- poly = Constraints2Polyhedron(PV->Domain,200);
- Print_Domain(DST,poly,param_names);
- Domain_Free(poly);
- PV = PV->next;
- }
- return;
-} /* Param_Vertices_Print */
-
-/*
- * Given a polyhedron 'Din' in combined data and parametre space, a context
- * polyhedron 'Cin' representing the constraints on the parameter space and
- * a working space size 'working_space', return a parametric polyhedron with
- * a list of distinct validity domains and a complete list of valid vertices
- * associated to each validity domain.
- */
-Param_Polyhedron *Polyhedron2Param_Domain(Polyhedron *Din,Polyhedron *Cin,int working_space) {
-
- Param_Polyhedron *result;
- Param_Domain *D;
-
- POL_ENSURE_FACETS(Din);
- POL_ENSURE_VERTICES(Din);
- POL_ENSURE_FACETS(Cin);
- POL_ENSURE_VERTICES(Cin);
-
- if (emptyQ(Din) || emptyQ(Cin))
- return NULL;
-
-#ifdef DEBUGPP
- fprintf(stderr,"Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
- (float)clock()/CLOCKS_PER_SEC);
-#endif
-
- /* Find the m-faces, keeping the corresponding domains */
- /* in the linked list PDomains */
- result = Find_m_faces(&Din,Cin,1,working_space,NULL,NULL);
-
-#ifdef DEBUGPP
- if(result) fprintf(stderr, "Number of vertices : %d\n",result->nbV);
- fprintf(stderr,"Vertices found at : %.2fs\n",(float)clock()/CLOCKS_PER_SEC);
-#endif
-
- /* Processing of PVResult and PDomains */
- if(result && Cin->Dimension>0) /* at least 1 parameter */
- Compute_PDomains(result->D,result->nbV,working_space);
- if(result && CEqualities)
- for(D=result->D;D;D=D->next)
- D->Domain = Add_CEqualities(D->Domain);
- Polyhedron_Free(CEqualities);
-
-#ifdef DEBUGPP
- fprintf(stderr, "domains found at : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
-#endif
-
- return(result);
-} /* Polyhedon2Param_Domain */
-
-/*
- *
- */
-Param_Polyhedron *Polyhedron2Param_SimplifiedDomain(Polyhedron **Din,Polyhedron *Cin,int working_space,Polyhedron **CEq,Matrix **CT) {
-
- Param_Polyhedron *result;
-
- assert(CEq != NULL);
- assert(CT != NULL);
-
- POL_ENSURE_FACETS(*Din);
- POL_ENSURE_VERTICES(*Din);
- POL_ENSURE_FACETS(Cin);
- POL_ENSURE_VERTICES(Cin);
-
-#ifdef DEBUGPP
- fprintf(stderr,"Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
- (float)clock()/CLOCKS_PER_SEC);
-#endif
-
- /* Find the m-faces, keeping the corresponding domains */
- /* in the linked list PDomains */
- result = Find_m_faces(Din,Cin,1,working_space,CEq,CT);
-
-#ifdef DEBUGPP
- if(result) fprintf(stderr, "Number of vertices : %d\n",result->nbV);
- fprintf(stderr,"Vertices found at : %.2fs\n",(float)clock()/CLOCKS_PER_SEC);
-#endif
-
- /* Processing of PVResult and PDomains */
- if(result && Cin->Dimension>0) /* at least 1 parameter */
- Compute_PDomains(result->D,result->nbV,working_space);
-
- /* Removed this, Vin100, March 01 */
- /* if(result && CEqualities )
- for(D=result->D;D;D=D->next)
- D->Domain = Add_CEqualities(D->Domain);
- */
-
-#ifdef DEBUGPP
- fprintf(stderr, "domains found at : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
-#endif
-
- return(result);
-} /* Polyhedron2Param_SimplifiedDomain */
-
-/*
- * Free the memory allocated to a list of validity domain of a parametrized
- * polyhedron.
- */
-void Param_Domain_Free(Param_Domain *PD) {
-
- Param_Domain *next_pd;
-
- while(PD) {
- free(PD->F);
- Domain_Free(PD->Domain);
- next_pd = PD->next;
- free(PD);
- PD = next_pd;
- }
- return;
-} /* Param_Domain_Free */
-
-/*
- * Free the memory allocated to a parametric polyhedron 'P'
- */
-void Param_Polyhedron_Free(Param_Polyhedron *P) {
-
- if (!P) return;
- Param_Vertices_Free(P->V);
- Param_Domain_Free(P->D);
- if (P->Constraints)
- Matrix_Free(P->Constraints);
- if (P->Rays)
- Matrix_Free(P->Rays);
- free(P);
- return;
-} /* Param_Polyhedron_Free */
-
-/*
- * Scales the parametric polyhedron such that all vertices are integer.
- */
-void Param_Polyhedron_Scale_Integer(Param_Polyhedron *PP, Polyhedron **P,
- Value *det, unsigned MaxRays)
-{
- int i;
- int nb_param, nb_vars;
- Vector *denoms;
- Param_Vertices *V;
- Value global_var_lcm;
- Matrix *expansion;
-
- value_set_si(*det, 1);
- if (!PP->nbV)
- return;
-
- nb_param = PP->D->Domain->Dimension;
- nb_vars = PP->V->Vertex->NbRows;
-
- /* Scan the vertices and make an orthogonal expansion of the variable
- space */
- /* a- prepare the array of common denominators */
- denoms = Vector_Alloc(nb_vars);
- value_init(global_var_lcm);
-
- /* b- scan the vertices and compute the variables' global lcms */
- for (V = PP->V; V; V = V->next)
- for (i = 0; i < nb_vars; i++)
- value_lcm(denoms->p[i], denoms->p[i], V->Vertex->p[i][nb_param+1]);
-
- value_set_si(global_var_lcm, 1);
- for (i = 0; i < nb_vars; i++) {
- value_multiply(*det, *det, denoms->p[i]);
- value_lcm(global_var_lcm, global_var_lcm, denoms->p[i]);
- }
-
- /* scale vertices */
- for (V = PP->V; V; V = V->next)
- for (i = 0; i < nb_vars; i++) {
- Vector_Scale(V->Vertex->p[i], V->Vertex->p[i], denoms->p[i], nb_param+1);
- Vector_Normalize(V->Vertex->p[i], nb_param+2);
- }
-
- /* the expansion can be actually writen as global_var_lcm.L^{-1} */
- /* this is equivalent to multiply the rows of P by denoms_det */
- for (i = 0; i < nb_vars; i++)
- value_division(denoms->p[i], global_var_lcm, denoms->p[i]);
-
- /* OPT : we could use a vector instead of a diagonal matrix here (c- and d-).*/
- /* c- make the quick expansion matrix */
- expansion = Matrix_Alloc(nb_vars+nb_param+1, nb_vars+nb_param+1);
- for (i = 0; i < nb_vars; i++)
- value_assign(expansion->p[i][i], denoms->p[i]);
- for (i = nb_vars; i < nb_vars+nb_param+1; i++)
- value_assign(expansion->p[i][i], global_var_lcm);
-
- /* d- apply the variable expansion to the polyhedron */
- if (P)
- *P = Polyhedron_Preimage(*P, expansion, MaxRays);
-
- Matrix_Free(expansion);
- value_clear(global_var_lcm);
- Vector_Free(denoms);
-}
diff --git a/source/polylib_mod/ranking.c b/source/polylib_mod/ranking.c
deleted file mode 100644
index d174ef8..0000000
--- a/source/polylib_mod/ranking.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Tools to compute the ranking function of an iteration J: the number of
- * integer points in P that are lexicographically inferior to J
- * B. Meister
- * 6/2005
- * LSIIT-ICPS, UMR 7005 CNRS Universite Louis Pasteur
- * HiPEAC Network
- */
-
-#include <polylib/polylib.h>
-#include <polylib/ranking.h>
-
-/**
- * Returns a list of polytopes needed to compute
- * the number of points in P that are lexicographically
- * smaller than a given point in D.
- * Only the first dim dimensions are taken into account
- * for computing the lexsmaller relation.
- * The remaining variables are assumed to be extra
- * existential/control variables.
- * When P == D, this is the conventional ranking function.
- * P and D are assumed to have the same parameter domain C.
- *
- * The first polyhedron in the list returned is the
- * updated context: a combination of D and C or an extended C.
- *
- * The order of the variables in the remaining polyhedra is
- * - first dim variables of P
- * - existential variables of P
- * - existential variables of D
- * - first dim variables of D
- * - the parameters
- */
-Polyhedron *LexSmaller(Polyhedron *P, Polyhedron *D, unsigned dim,
- Polyhedron *C, unsigned MAXRAYS)
-{
- unsigned i, j, k, r;
- unsigned nb_parms = C->Dimension;
- unsigned nb_vars = dim;
- unsigned P_extra = P->Dimension - nb_vars - nb_parms;
- unsigned D_extra = D->Dimension - nb_vars - nb_parms;
- unsigned nb_new_parms;
- unsigned ncons;
- Matrix * cur_element, * C_times_J, * Klon;
- Polyhedron * P1, *C1;
- Polyhedron * lexico_lesser_union = NULL;
-
- POL_ENSURE_INEQUALITIES(C);
- POL_ENSURE_INEQUALITIES(D);
- POL_ENSURE_INEQUALITIES(P);
-
- assert(P->Dimension >= C->Dimension + dim);
- assert(D->Dimension >= C->Dimension + dim);
- nb_new_parms = nb_vars;
-
- /* the number of variables must be positive */
- if (nb_vars<=0) {
- printf("\nRanking > No variables, returning NULL.\n");
- return NULL;
- }
- /*
- * if D has extra variables, then we can't squeeze the contraints
- * of D in the new context, so we simply add them to each element.
- */
- if (D_extra)
- cur_element = Matrix_Alloc(P->NbConstraints+D->NbConstraints+nb_new_parms,
- P->Dimension+D_extra+nb_new_parms+2);
- else
- cur_element = Matrix_Alloc(P->NbConstraints+nb_new_parms,
- P->Dimension+D_extra+nb_new_parms+2);
-
-
- /* 0- Put P in the first rows of cur_element */
- for (i=0; i < P->NbConstraints; i++) {
- Vector_Copy(P->Constraint[i], cur_element->p[i], nb_vars+P_extra+1);
- Vector_Copy(P->Constraint[i]+1+nb_vars+P_extra,
- cur_element->p[i]+1+nb_vars+P_extra+D_extra+nb_new_parms,
- nb_parms+1);
- }
- ncons = P->NbConstraints;
- if (D_extra) {
- for (i=0; i < D->NbConstraints; i++) {
- r = P->NbConstraints + i;
- Vector_Copy(D->Constraint[i], cur_element->p[r], 1);
- Vector_Copy(D->Constraint[i]+1,
- cur_element->p[r]+1+nb_vars+P_extra+D_extra, nb_new_parms);
- Vector_Copy(D->Constraint[i]+1+nb_new_parms,
- cur_element->p[r]+1+nb_vars+P_extra, D_extra);
- Vector_Copy(D->Constraint[i]+1+nb_new_parms+D_extra,
- cur_element->p[r]+1+nb_vars+P_extra+D_extra+nb_new_parms,
- nb_parms+1);
- }
- ncons += D->NbConstraints;
- }
-
- /* 1- compute the Ehrhart polynomial of each disjoint polyhedron defining the
- lexicographic order */
- for (k=0, r = ncons; k < nb_vars; k++, r++) {
-
- /* a- build the corresponding matrix
- * the nb of rows of cur_element is fake, so that we do not have to
- * re-allocate it. */
- cur_element->NbRows = r+1;
-
- /* convert the previous (strict) inequality into an equality */
- if (k>=1) {
- value_set_si(cur_element->p[r-1][0], 0);
- value_set_si(cur_element->p[r-1][cur_element->NbColumns-1], 0);
- }
- /* build the k-th inequality from P */
- value_set_si(cur_element->p[r][0], 1);
- value_set_si(cur_element->p[r][k+1], -1);
- value_set_si(cur_element->p[r][nb_vars+P_extra+D_extra+k+1], 1);
- /* we want a strict inequality */
- value_set_si(cur_element->p[r][cur_element->NbColumns-1], -1);
-#ifdef ERDEBUG
- show_matrix(cur_element);
-#endif
-
- /* b- add it to the current union
- as Constraints2Polyhedron modifies its input, we must clone cur_element */
- Klon = Matrix_Copy(cur_element);
- P1 = Constraints2Polyhedron(Klon, MAXRAYS);
- Matrix_Free(Klon);
- P1->next = lexico_lesser_union;
- lexico_lesser_union = P1;
- }
-
- /* 2- as we introduce n parameters, we must introduce them into the context
- * as well.
- * The added constraints are P.M.(J N 1 )^T >=0 */
- if (D_extra)
- C_times_J = Matrix_Alloc(C->NbConstraints, nb_new_parms+nb_parms+2);
- else
- C_times_J = Matrix_Alloc(C->NbConstraints + D->NbConstraints, D->Dimension+2);
- /* copy the initial context while adding the new parameters */
- for (i = 0; i < C->NbConstraints; i++) {
- value_assign(C_times_J->p[i][0], C->Constraint[i][0]);
- Vector_Copy(C->Constraint[i]+1, C_times_J->p[i]+1+nb_new_parms, nb_parms+1);
- }
-
- /* copy constraints from evaluation domain */
- if (!D_extra)
- for (i = 0; i < D->NbConstraints; i++)
- Vector_Copy(D->Constraint[i], C_times_J->p[C->NbConstraints+i],
- D->Dimension+2);
-
-#ifdef ERDEBUG
- show_matrix(C_times_J);
-#endif
- C1 = Constraints2Polyhedron(C_times_J, POL_NO_DUAL);
-
- /* 4- clean up */
- Matrix_Free(cur_element);
- Matrix_Free(C_times_J);
-
- C1->next = P1;
-
- return C1;
-} /* LexSmaller */
-
-
-/**
- * Returns the number of points in P that are lexicographically
- * smaller than a given point in D.
- * Only the first dim dimensions are taken into account
- * for computing the lexsmaller relation.
- * The remaining variables are assumed to be extra
- * existential/control variables.
- * When P == D, this is the conventional ranking function.
- * P and D are assumed to have the same parameter domain C.
- * The variables in the Enumeration correspond to the first dim variables
- * in D followed by the parameters of D (the variables of C).
- */
-Enumeration *Polyhedron_LexSmallerEnumerate(Polyhedron *P, Polyhedron *D,
- unsigned dim,
- Polyhedron *C, unsigned MAXRAYS)
-{
- Enumeration * ranking;
- Polyhedron *RC, *RD;
-
- RC = LexSmaller(P, D, dim, C, MAXRAYS);
- RD = RC->next;
- RC->next = NULL;
-
- /* Compute the ranking, which is the sum of the Ehrhart polynomials of the n
- disjoint polyhedra we just put in P1. */
- /* OPT : our polyhdera are (already) disjoint, so Domain_Enumerate does
- probably too much work uselessly */
- ranking = Domain_Enumerate(RD, RC, MAXRAYS, NULL);
-
- Domain_Free(RD);
- Polyhedron_Free(RC);
-
- return ranking;
-}
-
-
-/*
- * Returns a function that assigns a unique number to each point in the
- * polytope P ranging from zero to (number of points in P)-1.
- * The order of the numbers corresponds to the lexicographical order.
- *
- * C is the parameter context of the polytope
- */
-Enumeration *Polyhedron_Ranking(Polyhedron *P, Polyhedron *C, unsigned MAXRAYS)
-{
- return Polyhedron_LexSmallerEnumerate(P, P, P->Dimension-C->Dimension,
- C, MAXRAYS);
-}
diff --git a/source/polylib_mod/vector.c b/source/polylib_mod/vector.c
deleted file mode 100644
index a7d5d62..0000000
--- a/source/polylib_mod/vector.c
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- This file is part of PolyLib.
-
- PolyLib 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.
-
- PolyLib 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 PolyLib. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* vector.c
- COPYRIGHT
- Both this software and its documentation are
-
- Copyrighted 1993 by IRISA /Universite de Rennes I - France,
- Copyright 1995,1996 by BYU, Provo, Utah
- all rights reserved.
-
- Permission is granted to copy, use, and distribute
- for any commercial or noncommercial purpose under the terms
- of the GNU General Public license, version 2, June 1991
- (see file : LICENSING).
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <polylib/polylib.h>
-
-#ifdef MAC_OS
- #define abs __abs
-#endif
-
-/*
- * Compute n!
- */
-void Factorial(int n, Value *fact) {
-
- int i;
- Value tmp;
-
- value_init(tmp);
-
- value_set_si(*fact,1);
- for (i=1;i<=n;i++) {
- value_set_si(tmp,i);
- value_multiply(*fact,*fact,tmp);
- }
- value_clear(tmp);
-} /* Factorial */
-
-/*
- * Compute n!/(p!(n-p)!)
- */
-void Binomial(int n, int p, Value *result) {
-
- int i;
- Value tmp;
- Value f;
-
- value_init(tmp);value_init(f);
-
- if (n-p<p)
- p=n-p;
- if (p!=0) {
- value_set_si(*result,(n-p+1));
- for (i=n-p+2;i<=n;i++) {
- value_set_si(tmp,i);
- value_multiply(*result,*result,tmp);
- }
- Factorial(p,&f);
- value_division(*result,*result,f);
- }
- else
- value_set_si(*result,1);
- value_clear(f);value_clear(tmp);
-} /* Binomial */
-
-/*
- * Return the number of ways to choose 'b' items from 'a' items, that is,
- * return a!/(b!(a-b)!)
- */
-void CNP(int a,int b, Value *result) {
-
- int i;
- Value tmp;
- value_init(tmp);
-
- value_set_si(*result,1);
-
- /* If number of items is less than the number to be choosen, return 1 */
- if(a <= b) {
- value_clear(tmp);
- return;
- }
- for(i=a;i>b;--i) {
- value_set_si(tmp,i);
- value_multiply(*result,*result,tmp);
- }
- for(i=1;i<=(a-b);++i) {
- value_set_si(tmp,i);
- value_division(*result,*result,tmp);
- }
- value_clear(tmp);
-} /* CNP */
-
-/*
- * Compute GCD of 'a' and 'b'
- */
-void Gcd(Value a,Value b,Value *result) {
-
- Value acopy, bcopy;
-
- value_init(acopy);
- value_init(bcopy);
- value_assign(acopy,a);
- value_assign(bcopy,b);
- while(value_notzero_p(acopy)) {
- value_modulus(*result,bcopy,acopy);
- value_assign(bcopy,acopy);
- value_assign(acopy,*result);
- }
- value_absolute(*result,bcopy);
- value_clear(acopy);
- value_clear(bcopy);
-} /* Gcd */
-
-/*
- * Return the smallest component index in 'p' whose value is non-zero
- */
-int First_Non_Zero(Value *p,unsigned length) {
-
- Value *cp;
- int i;
-
- cp = p;
- for (i=0;i<length;i++) {
- if (value_notzero_p(*cp))
- break;
- cp++;
- }
- return((i==length) ? -1 : i );
-} /* First_Non_Zero */
-
-/*
- * Allocate memory space for Vector
- */
-Vector *Vector_Alloc(unsigned length) {
-
- int i;
- Vector *vector;
-
- vector = (Vector *)malloc(sizeof(Vector));
- if (!vector) {
- errormsg1("Vector_Alloc", "outofmem", "out of memory space");
- return 0;
- }
- vector->Size=length;
- vector->p=(Value *)malloc(length * sizeof(Value));
- if (!vector->p) {
- errormsg1("Vector_Alloc", "outofmem", "out of memory space");
- free(vector);
- return 0;
- }
- for(i=0;i<length;i++)
- value_init(vector->p[i]);
- return vector;
-} /* Vector_Alloc */
-
-/*
- * Free the memory space occupied by Vector
- */
-void Vector_Free(Vector *vector) {
-
- int i;
-
- if (!vector) return;
- for(i=0;i<vector->Size;i++)
- value_clear(vector->p[i]);
- free(vector->p);
- free(vector);
-} /* Vector_Free */
-
-/*
- * Print the contents of a Vector
- */
-void Vector_Print(FILE *Dst, const char *Format, Vector *vector)
-{
- int i;
- Value *p;
- unsigned length;
-
- fprintf(Dst, "%d\n", length=vector->Size);
- p = vector->p;
- for (i=0;i<length;i++) {
- if (Format) {
- value_print(Dst,Format,*p++);
- }
- else {
- value_print(Dst,P_VALUE_FMT,*p++);
- }
- }
- fprintf(Dst, "\n");
-} /* Vector_Print */
-
-/*
- * Read the contents of a Vector
- */
-Vector *Vector_Read() {
-
- Vector *vector;
- unsigned length;
- int i;
- char str[1024];
- Value *p;
-
- scanf("%d", &length);
- vector = Vector_Alloc(length);
- if (!vector) {
- errormsg1("Vector_Read", "outofmem", "out of memory space");
- return 0;
- }
- p = vector->p;
- for (i=0;i<length;i++) {
- scanf("%s",str);
- value_read(*(p++),str);
- }
- return vector;
-} /* Vector_Read */
-
-/*
- * Assign 'n' to each component of Vector 'p'
- */
-void Vector_Set(Value *p,int n,unsigned length) {
-
- Value *cp;
- int i;
-
- cp = p;
- for (i=0;i<length;i++) {
- value_set_si(*cp,n);
- cp++;
- }
- return;
-} /* Vector_Set */
-
-/*
- * Exchange the components of the vectors 'p1' and 'p2' of length 'length'
- */
-void Vector_Exchange(Value *p1, Value *p2, unsigned length) {
-
- int i;
-
- for(i=0;i<length;i++) {
- value_swap(p1[i],p2[i]);
- }
- return;
-}
-
-/*
- * Copy Vector 'p1' to Vector 'p2'
- */
-void Vector_Copy(Value *p1,Value *p2,unsigned length) {
-
- int i;
- Value *cp1, *cp2;
-
- cp1 = p1;
- cp2 = p2;
-
- for(i=0;i<length;i++)
- value_assign(*cp2++,*cp1++);
-
- return;
-}
-
-/*
- * Add two vectors 'p1' and 'p2' and store the result in 'p3'
- */
-void Vector_Add(Value *p1,Value *p2,Value *p3,unsigned length) {
-
- Value *cp1, *cp2, *cp3;
- int i;
-
- cp1=p1;
- cp2=p2;
- cp3=p3;
- for (i=0;i<length;i++) {
-
- /* *cp3++ = *cp1++ + *cp2++ */
- value_addto(*cp3,*cp1,*cp2);
- cp1++; cp2++; cp3++;
- }
-} /* Vector_Add */
-
-/*
- * Subtract two vectors 'p1' and 'p2' and store the result in 'p3'
- */
-void Vector_Sub(Value *p1,Value *p2,Value *p3,unsigned length) {
-
- Value *cp1, *cp2, *cp3;
- int i;
-
- cp1=p1;
- cp2=p2;
- cp3=p3;
- for (i=0;i<length;i++) {
-
- /* *cp3++= *cp1++ - *cp2++ */
- value_subtract(*cp3,*cp1,*cp2);
- cp1++; cp2++; cp3++;
- }
-} /* Vector_Sub */
-
-/*
- * Compute Bitwise OR of Vectors 'p1' and 'p2' and store in 'p3'
- */
-void Vector_Or(Value *p1,Value *p2,Value *p3,unsigned length) {
-
- Value *cp1, *cp2, *cp3;
- int i;
-
- cp1=p1;
- cp2=p2;
- cp3=p3;
- for (i=0;i<length;i++) {
-
- /* *cp3++=*cp1++ | *cp2++ */
- value_orto(*cp3,*cp1,*cp2);
- cp1++; cp2++; cp3++;
- }
-} /* Vector_Or */
-
-/*
- * Scale Vector 'p1' lambda times and store in 'p2'
- */
-void Vector_Scale(Value *p1,Value *p2,Value lambda,unsigned length) {
-
- Value *cp1, *cp2;
- int i;
-
- cp1=p1;
- cp2=p2;
- for (i=0;i<length;i++) {
-
- /* *cp2++=*cp1++ * lambda */
- value_multiply(*cp2,*cp1,lambda);
- cp1++; cp2++;
- }
-} /* Vector_Scale */
-
-/*
- * Antiscale Vector 'p1' by lambda and store in 'p2'
- * Assumes all elements of 'p1' are divisble by lambda.
- */
-void Vector_AntiScale(Value *p1, Value *p2, Value lambda, unsigned length)
-{
- int i;
-
- for (i = 0; i < length; i++)
- value_divexact(p2[i], p1[i], lambda);
-} /* Vector_AntiScale */
-
-/*
- * Puts negative of 'p1' in 'p2'
- */
-void Vector_Oppose(Value *p1, Value *p2, unsigned len)
-{
- unsigned i;
-
- for (i = 0; i < len; ++i)
- value_oppose(p2[i], p1[i]);
-}
-
-/*
- * Return the inner product of the two Vectors 'p1' and 'p2'
- */
-void Inner_Product(Value *p1, Value *p2, unsigned length, Value *ip)
-{
- int i;
-
- if (length != 0)
- value_multiply(*ip, p1[0], p2[0]);
- else
- value_set_si(*ip, 0);
- for(i = 1; i < length; i++)
- value_addmul(*ip, p1[i], p2[i]);
-} /* Inner_Product */
-
-/*
- * Return the maximum of the components of 'p'
- */
-void Vector_Max(Value *p,unsigned length, Value *max) {
-
- Value *cp;
- int i;
-
- cp=p;
- value_assign(*max,*cp);
- cp++;
- for (i=1;i<length;i++) {
- value_maximum(*max,*max,*cp);
- cp++;
- }
-} /* Vector_Max */
-
-/*
- * Return the minimum of the components of Vector 'p'
- */
-void Vector_Min(Value *p,unsigned length,Value *min) {
-
- Value *cp;
- int i;
-
- cp=p;
- value_assign(*min,*cp);
- cp++;
- for (i=1;i<length;i++) {
- value_minimum(*min,*min,*cp);
- cp++;
- }
- return;
-} /* Vector_Min */
-
-/*
- * Given Vectors 'p1' and 'p2', return Vector 'p3' = lambda * p1 + mu * p2.
- */
-void Vector_Combine(Value *p1, Value *p2, Value *p3, Value lambda, Value mu,
- unsigned length)
-{
- Value tmp;
- int i;
-
- value_init(tmp);
- for (i = 0; i < length; i++) {
- value_multiply(tmp, lambda, p1[i]);
- value_addmul(tmp, mu, p2[i]);
- value_assign(p3[i], tmp);
- }
- value_clear(tmp);
- return;
-} /* Vector_Combine */
-
-/*
- * Return 1 if 'Vec1' equals 'Vec2', otherwise return 0
- */
-int Vector_Equal(Value *Vec1, Value *Vec2, unsigned n)
-{
- int i;
-
- for (i = 0; i < n; ++i)
- if (value_ne(Vec1[i], Vec2[i]))
- return 0;
-
- return 1;
-} /* Vector_Equal */
-
-/*
- * Return the component of 'p' with minimum non-zero absolute value. 'index'
- * points to the component index that has the minimum value. If no such value
- * and index is found, Value 1 is returned.
- */
-void Vector_Min_Not_Zero(Value *p,unsigned length,int *index,Value *min)
-{
- Value aux;
- int i;
-
-
- i = First_Non_Zero(p, length);
- if (i == -1) {
- value_set_si(*min,1);
- return;
- }
- *index = i;
- value_absolute(*min, p[i]);
- value_init(aux);
- for (i = i+1; i < length; i++) {
- if (value_zero_p(p[i]))
- continue;
- value_absolute(aux, p[i]);
- if (value_lt(aux,*min)) {
- value_assign(*min,aux);
- *index = i;
- }
- }
- value_clear(aux);
-} /* Vector_Min_Not_Zero */
-
-/*
- * Return the GCD of components of Vector 'p'
- */
-void Vector_Gcd(Value *p,unsigned length,Value *min) {
-
- Value *q,*cq, *cp;
- int i, Not_Zero, Index_Min=0;
-
- q = (Value *)malloc(length*sizeof(Value));
-
- /* Initialize all the 'Value' variables */
- for(i=0;i<length;i++)
- value_init(q[i]);
-
- /* 'cp' points to vector 'p' and cq points to vector 'q' that holds the */
- /* absolute value of elements of vector 'p'. */
- cp=p;
- for (cq = q,i=0;i<length;i++) {
- value_absolute(*cq,*cp);
- cq++;
- cp++;
- }
- do {
- Vector_Min_Not_Zero(q,length,&Index_Min,min);
-
- /* if (*min != 1) */
- if (value_notone_p(*min)) {
-
- cq=q;
- Not_Zero=0;
- for (i=0;i<length;i++,cq++)
- if (i!=Index_Min) {
-
- /* Not_Zero |= (*cq %= *min) */
- value_modulus(*cq,*cq,*min);
- Not_Zero |= value_notzero_p(*cq);
- }
- }
- else
- break;
- } while (Not_Zero);
-
- /* Clear all the 'Value' variables */
- for(i=0;i<length;i++)
- value_clear(q[i]);
- free(q);
-} /* Vector_Gcd */
-
-/*
- * Given vectors 'p1', 'p2', and a pointer to a function returning 'Value type,
- * compute p3[i] = f(p1[i],p2[i]).
- */
-void Vector_Map(Value *p1,Value *p2,Value *p3,unsigned length,
- Value *(*f)(Value,Value))
-{
- Value *cp1, *cp2, *cp3;
- int i;
-
- cp1=p1;
- cp2=p2;
- cp3=p3;
- for(i=0;i<length;i++) {
- value_assign(*cp3,*(*f)(*cp1, *cp2));
- cp1++; cp2++; cp3++;
- }
- return;
-} /* Vector_Map */
-
-/*
- * Reduce a vector by dividing it by GCD. There is no restriction on
- * components of Vector 'p'. Making the last element positive is *not* OK
- * for equalities.
- */
-void Vector_Normalize(Value *p,unsigned length) {
-
- Value gcd;
- int i;
-
- value_init(gcd);
-
- Vector_Gcd(p,length,&gcd);
-
- if (value_notone_p(gcd))
- Vector_AntiScale(p, p, gcd, length);
-
- value_clear(gcd);
-} /* Vector_Normalize */
-
-/*
- * Reduce a vector by dividing it by GCD and making sure its pos-th
- * element is positive.
- */
-void Vector_Normalize_Positive(Value *p,int length,int pos) {
-
- Value gcd;
- int i;
-
- value_init(gcd);
- Vector_Gcd(p,length,&gcd);
- if (value_neg_p(p[pos]))
- value_oppose(gcd,gcd);
- if(value_notone_p(gcd))
- Vector_AntiScale(p, p, gcd, length);
- value_clear(gcd);
-} /* Vector_Normalize_Positive */
-
-/*
- * Reduce 'p' by operating binary function on its components successively
- */
-void Vector_Reduce(Value *p,unsigned length,void(*f)(Value,Value *),Value *r) {
-
- Value *cp;
- int i;
-
- cp = p;
- value_assign(*r,*cp);
- for(i=1;i<length;i++) {
- cp++;
- (*f)(*cp,r);
- }
-} /* Vector_Reduce */
-
-/*
- * Sort the components of a Vector 'vector' using Heap Sort.
- */
-void Vector_Sort(Value *vector,unsigned n) {
-
- int i, j;
- Value temp;
- Value *current_node=(Value *)0;
- Value *left_son,*right_son;
-
- value_init(temp);
-
- for (i=(n-1)/2;i>=0;i--) {
-
- /* Phase 1 : build the heap */
- j=i;
- value_assign(temp,*(vector+i));
-
- /* While not a leaf */
- while (j<=(n-1)/2) {
- current_node = vector+j;
- left_son = vector+(j<<1)+1;
-
- /* If only one son */
- if ((j<<1)+2>=n) {
- if (value_lt(temp,*left_son)) {
- value_assign(*current_node,*left_son);
- j=(j<<1)+1;
- }
- else
- break;
- }
- else {
-
- /* If two sons */
- right_son=left_son+1;
- if (value_lt(*right_son,*left_son)) {
- if (value_lt(temp,*left_son)) {
- value_assign(*current_node,*left_son);
- j=(j<<1)+1;
- }
- else
- break;
- }
- else {
- if (value_lt(temp,*right_son)) {
- value_assign(*current_node,*right_son );
- j=(j<<1)+2;
- }
- else
- break;
- }
- }
- }
- value_assign(*current_node,temp);
- }
- for(i=n-1;i>0;i--) {
-
- /* Phase 2 : sort the heap */
- value_assign(temp, *(vector+i));
- value_assign(*(vector+i),*vector);
- j=0;
-
- /* While not a leaf */
- while (j<i/2) {
- current_node=vector+j;
- left_son=vector+(j<<1)+1;
-
- /* If only one son */
- if ((j<<1)+2>=i) {
- if (value_lt(temp,*left_son)) {
- value_assign(*current_node,*left_son);
- j=(j<<1)+1;
- }
- else
- break;
- }
- else {
-
- /* If two sons */
- right_son=left_son+1;
- if (value_lt(*right_son,*left_son)) {
- if (value_lt(temp,*left_son)) {
- value_assign(*current_node,*left_son);
- j=(j<<1)+1;
- }
- else
- break;
- }
- else {
- if (value_lt(temp,*right_son)) {
- value_assign(*current_node,*right_son );
- j=(j<<1)+2;
- }
- else
- break;
- }
- }
- }
- value_assign(*current_node,temp);
- }
- value_clear(temp);
- return;
-} /* Vector_Sort */
-
-/*
- * Replaces constraint a x >= c by x >= ceil(c/a)
- * where "a" is a common factor in the coefficients
- * old is the constraint; v points to an initialized
- * value that this procedure can use.
- * Return non-zero if something changed.
- * Result is placed in newp.
- */
-int ConstraintSimplify(Value *old, Value *newp, int len, Value* v)
-{
- /* first remove common factor of all coefficients (including "c") */
- Vector_Gcd(old+1, len - 1, v);
- if (value_notone_p(*v))
- Vector_AntiScale(old+1, newp+1, *v, len-1);
-
- Vector_Gcd(old+1, len - 2, v);
-
- if (value_one_p(*v))
- return 0;
-
- Vector_AntiScale(old+1, newp+1, *v, len-2);
- value_pdivision(newp[len-1], old[len-1], *v);
- return 1;
-}
-
-int Vector_IsZero(Value * v, unsigned length) {
- unsigned i;
- if (value_notzero_p(v[0])) return 0;
- else {
- value_set_si(v[0], 1);
- for (i=length-1; value_zero_p(v[i]); i--);
- value_set_si(v[0], 0);
- return (i==0);
- }
-}
-
-#define MAX_CACHE_SIZE 20
-static struct {
- Value *p;
- int size;
-} cache[MAX_CACHE_SIZE];
-static int cache_size = 0;
-
-Value* value_alloc(int want, int *got)
-{
- int i;
- Value *p;
-
- if (cache_size) {
- int best;
- for (i = 0; i < cache_size; ++i) {
- if (cache[i].size >= want) {
- Value *p = cache[i].p;
- *got = cache[i].size;
- if (--cache_size != i)
- cache[i] = cache[cache_size];
- Vector_Set(p, 0, want);
- return p;
- }
- if (i == 0)
- best = 0;
- else if (cache[i].size > cache[best].size)
- best = i;
- }
-
- p = (Value *)realloc(cache[best].p, want * sizeof(Value));
- *got = cache[best].size;
- if (--cache_size != best)
- cache[best] = cache[cache_size];
- Vector_Set(p, 0, *got);
- } else {
- p = (Value *)malloc(want * sizeof(Value));
- *got = 0;
- }
-
- if (!p)
- return p;
-
- for (i = *got; i < want; ++i)
- value_init(p[i]);
- *got = want;
-
- return p;
-}
-
-void value_free(Value *p, int size)
-{
- int i;
-
- if (cache_size < MAX_CACHE_SIZE) {
- cache[cache_size].p = p;
- cache[cache_size].size = size;
- ++cache_size;
- return;
- }
-
- for (i=0; i < size; i++)
- value_clear(p[i]);
- free(p);
-}
-
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/cohomcalg.git
More information about the debian-science-commits
mailing list