/* A collection of useful convex polyhedra algorithms: inline functions. Copyright (C) 2001-2004 Roberto Bagnara This file is part of the Parma Polyhedra Library (PPL). The PPL is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The PPL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. For the most up-to-date information see the Parma Polyhedra Library site: http://www.cs.unipr.it/ppl/ . */ #ifndef PPL_algorithms_hh #define PPL_algorithms_hh 1 #include "NNC_Polyhedron.defs.hh" #include "Polyhedra_PowerSet.defs.hh" #include "Constraint.defs.hh" #include "LinExpression.defs.hh" #include "ConSys.defs.hh" #include #include namespace Parma_Polyhedra_Library { //! Partitions \p q with respect to \p p. /*! \relates Polyhedra_PowerSet Let \p p and \p q be two polyhedra. The function returns an object r of type std::pair\ \> such that - r.first is the intersection of \p p and \p q; - r.second has the property that all its elements are not empty, pairwise disjoint, and disjoint from \p p; - the union of r.first with all the elements of r.second gives \p q (i.e., r is the representation of a partition of \p q). \if Include_Implementation_Details See this paper for more information about the implementation. \endif */ template std::pair > linear_partition(const PH& p, const PH& q); namespace { template void linear_partition_aux(const Constraint& c, PH& qq, Polyhedra_PowerSet& r) { LinExpression le(c); Constraint neg_c = c.is_strict_inequality() ? (le <= 0) : (le < 0); NNC_Polyhedron qqq(qq); if (qqq.add_constraint_and_minimize(neg_c)) r.add_disjunct(qqq); qq.add_constraint(c); } } // namespace /*! \relates Polyhedra_PowerSet */ template std::pair > linear_partition(const PH& p, const PH& q) { Polyhedra_PowerSet r(p.space_dimension(), Polyhedron::EMPTY); PH qq = q; const ConSys& pcs = p.constraints(); for (ConSys::const_iterator i = pcs.begin(), pcs_end = pcs.end(); i != pcs_end; ++i) { const Constraint c = *i; if (c.is_equality()) { LinExpression le(c); linear_partition_aux(le <= 0, qq, r); linear_partition_aux(le >= 0, qq, r); } else linear_partition_aux(c, qq, r); } return std::pair >(qq, r); } //! If the poly-hull between \p p and \p q is exact it is assigned to \p p. /*! \relates Polyhedron */ template bool poly_hull_assign_if_exact(PH& p, const PH& q); /*! \relates Polyhedron */ template bool poly_hull_assign_if_exact(PH& p, const PH& q) { PH phull = p; NNC_Polyhedron nnc_p(p); phull.poly_hull_assign(q); std::pair > partition = linear_partition(q, phull); const Polyhedra_PowerSet& s = partition.second; typedef Polyhedra_PowerSet::const_iterator iter; for (iter i = s.begin(), s_end = s.end(); i != s_end; ++i) // The polyhedral hull is exact if and only if all the elements // of the partition of the polyhedral hull of `p' and `q' with // respect to `q' are included in `p' if (!nnc_p.contains(i->element())) return false; p = phull; return true; } template bool check_containment(const PH& ph, const Polyhedra_PowerSet& ps); template bool check_containment(const PH& ph, const Polyhedra_PowerSet& ps) { Polyhedra_PowerSet tmp(ph.space_dimension(), Polyhedron::EMPTY); tmp.add_disjunct(NNC_Polyhedron(ph)); for (typename Polyhedra_PowerSet::const_iterator i = ps.begin(), ps_end = ps.end(); i != ps_end; ++i) { const NNC_Polyhedron pi(i->element()); for (typename Polyhedra_PowerSet::iterator j = tmp.begin(), jn = j; j != tmp.end(); j = jn) { ++jn; const NNC_Polyhedron& pj = j->element(); if (pi.contains(pj)) tmp.erase(j); } if (tmp.empty()) return true; else { Polyhedra_PowerSet new_disjuncts(ph.space_dimension(), Polyhedron::EMPTY); for (Polyhedra_PowerSet::iterator j = tmp.begin(), jn = j; j != tmp.end(); j = jn) { ++jn; const NNC_Polyhedron& pj = j->element(); if (!pj.is_disjoint_from(pi)) { std::pair > partition = linear_partition(pi, pj); tmp.erase(j); new_disjuncts.add_disjunct(partition.first); new_disjuncts.upper_bound_assign(partition.second); } } tmp.upper_bound_assign(new_disjuncts); } } return false; } } // namespace Parma_Polyhedra_Library #endif // !defined(PPL_algorithms_hh)