#include <BD_Shape.defs.hh>

Exception Throwers | |
| void | throw_dimension_incompatible (const char *method, const BD_Shape &x) const |
| void | throw_dimension_incompatible (const char *method, dimension_type required_dim) const |
| void | throw_dimension_incompatible (const char *method, const Constraint &c) const |
| void | throw_dimension_incompatible (const char *method, const Congruence &cg) const |
| void | throw_dimension_incompatible (const char *method, const Generator &g) const |
| void | throw_dimension_incompatible (const char *method, const char *name_row, const Linear_Expression &y) const |
| static void | throw_expression_too_complex (const char *method, const Linear_Expression &e) |
| static void | throw_generic (const char *method, const char *reason) |
Public Types | |
| typedef T | coefficient_type_base |
| The numeric base type upon which bounded differences are built. | |
| typedef N | coefficient_type |
| The (extended) numeric type of the inhomogeneous term of the inequalities defining a BDS. | |
Public Member Functions | |
| void | ascii_dump () const |
Writes to std::cerr an ASCII representation of *this. | |
| void | ascii_dump (std::ostream &s) const |
Writes to s an ASCII representation of *this. | |
| void | print () const |
Prints *this to std::cerr using operator<<. | |
| bool | ascii_load (std::istream &s) |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise. | |
| memory_size_type | total_memory_in_bytes () const |
Returns the total size in bytes of the memory occupied by *this. | |
| memory_size_type | external_memory_in_bytes () const |
Returns the size in bytes of the memory managed by *this. | |
| int32_t | hash_code () const |
Returns a 32-bit hash code for *this. | |
Constructors, Assignment, Swap and Destructor | |
| BD_Shape (dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE) | |
| Builds a universe or empty BDS of the specified space dimension. | |
| BD_Shape (const BD_Shape &y, Complexity_Class complexity=ANY_COMPLEXITY) | |
| Ordinary copy-constructor. | |
| template<typename U> | |
| BD_Shape (const BD_Shape< U > &y, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a conservative, upward approximation of y. | |
| BD_Shape (const Constraint_System &cs) | |
Builds a BDS from the system of constraints cs. | |
| BD_Shape (const Congruence_System &cgs) | |
| Builds a BDS from a system of congruences. | |
| BD_Shape (const Generator_System &gs) | |
Builds a BDS from the system of generators gs. | |
| BD_Shape (const Polyhedron &ph, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a BDS from the polyhedron ph. | |
| template<typename Interval> | |
| BD_Shape (const Box< Interval > &box, Complexity_Class complexity=ANY_COMPLEXITY) | |
| Builds a BDS out of a box. | |
| BD_Shape (const Grid &grid, Complexity_Class complexity=ANY_COMPLEXITY) | |
| Builds a BDS out of a grid. | |
| template<typename U> | |
| BD_Shape (const Octagonal_Shape< U > &os, Complexity_Class complexity=ANY_COMPLEXITY) | |
| Builds a BDS from an octagonal shape. | |
| BD_Shape & | operator= (const BD_Shape &y) |
The assignment operator (*this and y can be dimension-incompatible). | |
| void | swap (BD_Shape &y) |
Swaps *this with y (*this and y can be dimension-incompatible). | |
| ~BD_Shape () | |
| Destructor. | |
Member Functions that Do Not Modify the BD_Shape | |
| dimension_type | space_dimension () const |
Returns the dimension of the vector space enclosing *this. | |
| dimension_type | affine_dimension () const |
Returns , if *this is empty; otherwise, returns the affine dimension of *this. | |
| Constraint_System | constraints () const |
Returns a system of constraints defining *this. | |
| Constraint_System | minimized_constraints () const |
Returns a minimized system of constraints defining *this. | |
| Congruence_System | congruences () const |
Returns a system of (equality) congruences satisfied by *this. | |
| Congruence_System | minimized_congruences () const |
Returns a minimal system of (equality) congruences satisfied by *this with the same affine dimension as *this. | |
| bool | bounds_from_above (const Linear_Expression &expr) const |
Returns true if and only if expr is bounded from above in *this. | |
| bool | bounds_from_below (const Linear_Expression &expr) const |
Returns true if and only if expr is bounded from below in *this. | |
| bool | maximize (const Linear_Expression &expr, Coefficient &sup_n, Coefficient &sup_d, bool &maximum) const |
Returns true if and only if *this is not empty and expr is bounded from above in *this, in which case the supremum value is computed. | |
| bool | maximize (const Linear_Expression &expr, Coefficient &sup_n, Coefficient &sup_d, bool &maximum, Generator &g) const |
Returns true if and only if *this is not empty and expr is bounded from above in *this, in which case the supremum value and a point where expr reaches it are computed. | |
| bool | minimize (const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum) const |
Returns true if and only if *this is not empty and expr is bounded from below in *this, in which case the infimum value is computed. | |
| bool | minimize (const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum, Generator &g) const |
Returns true if and only if *this is not empty and expr is bounded from below in *this, in which case the infimum value and a point where expr reaches it are computed. | |
| bool | contains (const BD_Shape &y) const |
Returns true if and only if *this contains y. | |
| bool | strictly_contains (const BD_Shape &y) const |
Returns true if and only if *this strictly contains y. | |
| bool | is_disjoint_from (const BD_Shape &y) const |
Returns true if and only if *this and y are disjoint. | |
| Poly_Con_Relation | relation_with (const Constraint &c) const |
Returns the relations holding between *this and the constraint c. | |
| Poly_Con_Relation | relation_with (const Congruence &cg) const |
Returns the relations holding between *this and the congruence cg. | |
| Poly_Gen_Relation | relation_with (const Generator &g) const |
Returns the relations holding between *this and the generator g. | |
| bool | is_empty () const |
Returns true if and only if *this is an empty BDS. | |
| bool | is_universe () const |
Returns true if and only if *this is a universe BDS. | |
| bool | is_discrete () const |
Returns true if and only if *this is discrete. | |
| bool | is_topologically_closed () const |
Returns true if and only if *this is a topologically closed subset of the vector space. | |
| bool | is_bounded () const |
Returns true if and only if *this is a bounded BDS. | |
| bool | contains_integer_point () const |
Returns true if and only if *this contains at least one integer point. | |
| bool | constrains (Variable var) const |
Returns true if and only if var is constrained in *this. | |
| bool | OK () const |
Returns true if and only if *this satisfies all its invariants. | |
Space-Dimension Preserving Member Functions that May Modify the BD_Shape | |
| void | add_constraint (const Constraint &c) |
Adds a copy of constraint c to the system of bounded differences defining *this. | |
| bool | add_constraint_and_minimize (const Constraint &c) |
Adds a copy of constraint c to the system of bounded differences defining *this. | |
| void | add_congruence (const Congruence &cg) |
Adds a copy of congruence cg to the system of congruences of this (without minimizing the result). | |
| bool | add_congruence_and_minimize (const Congruence &cg) |
Adds a copy of congruence cg to the system of congruences of *this, minimizing the result. | |
| void | add_constraints (const Constraint_System &cs) |
Adds the constraints in cs to the system of bounded differences defining *this. | |
| void | add_recycled_constraints (Constraint_System &cs) |
Adds the constraints in cs to the system of constraints of *this (without minimizing the result). | |
| bool | add_constraints_and_minimize (const Constraint_System &cs) |
Adds the constraints in cs to the system of bounded differences defining *this. | |
| bool | add_recycled_constraints_and_minimize (Constraint_System &cs) |
Adds the constraints in cs to the system of constraints of *this, minimizing the result. | |
| void | add_congruences (const Congruence_System &cgs) |
Adds to *this constraints equivalent to the congruences in cgs (without minimizing the result). | |
| bool | add_congruences_and_minimize (const Congruence_System &cs) |
Adds a copy of the congruences in cs to the system of congruences of *this, minimizing the result. | |
| void | add_recycled_congruences (Congruence_System &cgs) |
Adds the congruences in cs to the system of congruences of *this (without minimizing the result). | |
| bool | add_recycled_congruences_and_minimize (Congruence_System &cgs) |
Adds the congruences in cs to the system of congruences of *this, minimizing the result. | |
| void | refine_with_constraint (const Constraint &c) |
Uses a copy of constraint c to refine the system of bounded differences defining *this. | |
| void | refine_with_congruence (const Congruence &cg) |
Uses a copy of congruence cg to refine the system of bounded differences of *this. | |
| void | refine_with_constraints (const Constraint_System &cs) |
Uses a copy of the constraints in cs to refine the system of bounded differences defining *this. | |
| void | refine_with_congruences (const Congruence_System &cgs) |
Uses a copy of the congruences in cgs to refine the system of bounded differences defining *this. | |
| void | unconstrain (Variable var) |
Computes the cylindrification of *this with respect to space dimension var, assigning the result to *this. | |
| void | unconstrain (const Variables_Set &to_be_unconstrained) |
Computes the cylindrification of *this with respect to the set of space dimensions to_be_unconstrained, assigning the result to *this. | |
| void | intersection_assign (const BD_Shape &y) |
Assigns to *this the intersection of *this and y. | |
| bool | intersection_assign_and_minimize (const BD_Shape &y) |
Assigns to *this the intersection of *this and y. | |
| void | upper_bound_assign (const BD_Shape &y) |
Assigns to *this the smallest BDS containing the union of *this and y. | |
| bool | upper_bound_assign_and_minimize (const BD_Shape &y) |
Assigns to *this the smallest BDS containing the convex union of *this and y. | |
| bool | upper_bound_assign_if_exact (const BD_Shape &y) |
If the upper bound of *this and y is exact, it is assigned to *this and true is returned, otherwise false is returned. | |
| void | difference_assign (const BD_Shape &y) |
Assigns to *this the smallest BD shape containing the set difference of *this and y. | |
| bool | simplify_using_context_assign (const BD_Shape &y) |
Assigns to *this a meet-preserving simplification of *this with respect to y. If false is returned, then the intersection is empty. | |
| void | affine_image (Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the affine image of *this under the function mapping variable var into the affine expression specified by expr and denominator. | |
| void | affine_preimage (Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the affine preimage of *this under the function mapping variable var into the affine expression specified by expr and denominator. | |
| void | generalized_affine_image (Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the image of *this with respect to the affine relation , where is the relation symbol encoded by relsym. | |
| void | generalized_affine_image (const Linear_Expression &lhs, Relation_Symbol relsym, const Linear_Expression &rhs) |
Assigns to *this the image of *this with respect to the affine relation , where is the relation symbol encoded by relsym. | |
| void | generalized_affine_preimage (Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the preimage of *this with respect to the affine relation , where is the relation symbol encoded by relsym. | |
| void | generalized_affine_preimage (const Linear_Expression &lhs, Relation_Symbol relsym, const Linear_Expression &rhs) |
Assigns to *this the preimage of *this with respect to the affine relation , where is the relation symbol encoded by relsym. | |
| void | bounded_affine_image (Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the image of *this with respect to the bounded affine relation . | |
| void | bounded_affine_preimage (Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the preimage of *this with respect to the bounded affine relation . | |
| void | time_elapse_assign (const BD_Shape &y) |
Assigns to *this the result of computing the time-elapse between *this and y. | |
| void | topological_closure_assign () |
Assigns to *this its topological closure. | |
| void | CC76_extrapolation_assign (const BD_Shape &y, unsigned *tp=0) |
Assigns to *this the result of computing the CC76-extrapolation between *this and y. | |
| template<typename Iterator> | |
| void | CC76_extrapolation_assign (const BD_Shape &y, Iterator first, Iterator last, unsigned *tp=0) |
Assigns to *this the result of computing the CC76-extrapolation between *this and y. | |
| void | BHMZ05_widening_assign (const BD_Shape &y, unsigned *tp=0) |
Assigns to *this the result of computing the BHMZ05-widening of *this and y. | |
| void | limited_BHMZ05_extrapolation_assign (const BD_Shape &y, const Constraint_System &cs, unsigned *tp=0) |
Improves the result of the BHMZ05-widening computation by also enforcing those constraints in cs that are satisfied by all the points of *this. | |
| void | CC76_narrowing_assign (const BD_Shape &y) |
Assigns to *this the result of restoring in y the constraints of *this that were lost by CC76-extrapolation applications. | |
| void | limited_CC76_extrapolation_assign (const BD_Shape &y, const Constraint_System &cs, unsigned *tp=0) |
Improves the result of the CC76-extrapolation computation by also enforcing those constraints in cs that are satisfied by all the points of *this. | |
| void | H79_widening_assign (const BD_Shape &y, unsigned *tp=0) |
Assigns to *this the result of computing the H79-widening between *this and y. | |
| void | widening_assign (const BD_Shape &y, unsigned *tp=0) |
| Same as H79_widening_assign(y, tp). | |
| void | limited_H79_extrapolation_assign (const BD_Shape &y, const Constraint_System &cs, unsigned *tp=0) |
Improves the result of the H79-widening computation by also enforcing those constraints in cs that are satisfied by all the points of *this. | |
Member Functions that May Modify the Dimension of the Vector Space | |
| void | add_space_dimensions_and_embed (dimension_type m) |
Adds m new dimensions and embeds the old BDS into the new space. | |
| void | add_space_dimensions_and_project (dimension_type m) |
Adds m new dimensions to the BDS and does not embed it in the new vector space. | |
| void | concatenate_assign (const BD_Shape &y) |
Assigns to *this the concatenation of *this and y, taken in this order. | |
| void | remove_space_dimensions (const Variables_Set &to_be_removed) |
| Removes all the specified dimensions. | |
| void | remove_higher_space_dimensions (dimension_type new_dimension) |
Removes the higher dimensions so that the resulting space will have dimension new_dimension. | |
| template<typename Partial_Function> | |
| void | map_space_dimensions (const Partial_Function &pfunc) |
| Remaps the dimensions of the vector space according to a partial function. | |
| void | expand_space_dimension (Variable var, dimension_type m) |
Creates m copies of the space dimension corresponding to var. | |
| void | fold_space_dimensions (const Variables_Set &to_be_folded, Variable var) |
Folds the space dimensions in to_be_folded into var. | |
Static Public Member Functions | |
| static dimension_type | max_space_dimension () |
| Returns the maximum space dimension that a BDS can handle. | |
| static bool | can_recycle_constraint_systems () |
Returns false indicating that this domain cannot recycle constraints. | |
| static bool | can_recycle_congruence_systems () |
Returns false indicating that this domain cannot recycle congruences. | |
Private Types | |
| typedef Checked_Number< T, Extended_Number_Policy > | N |
| The (extended) numeric type of the inhomogeneous term of the inequalities defining a BDS. | |
Private Member Functions | |
| bool | marked_zero_dim_univ () const |
Returns true if the BDS is the zero-dimensional universe. | |
| bool | marked_empty () const |
Returns true if the BDS is known to be empty. | |
| bool | marked_shortest_path_closed () const |
Returns true if the system of bounded differences is known to be shortest-path closed. | |
| bool | marked_shortest_path_reduced () const |
Returns true if the system of bounded differences is known to be shortest-path reduced. | |
| void | set_empty () |
Turns *this into an empty BDS. | |
| void | set_zero_dim_univ () |
Turns *this into an zero-dimensional universe BDS. | |
| void | set_shortest_path_closed () |
Marks *this as shortest-path closed. | |
| void | set_shortest_path_reduced () |
Marks *this as shortest-path closed. | |
| void | reset_shortest_path_closed () |
Marks *this as possibly not shortest-path closed. | |
| void | reset_shortest_path_reduced () |
Marks *this as possibly not shortest-path reduced. | |
| void | shortest_path_closure_assign () const |
Assigns to this->dbm its shortest-path closure. | |
| void | shortest_path_reduction_assign () const |
Assigns to this->dbm its shortest-path closure and records into this->redundancy_dbm which of the entries in this->dbm are redundant. | |
| bool | is_shortest_path_reduced () const |
Returns true if and only if this->dbm is shortest-path closed and this->redundancy_dbm correctly flags the redundant entries in this->dbm. | |
| bool | bounds (const Linear_Expression &expr, bool from_above) const |
Checks if and how expr is bounded in *this. | |
| bool | max_min (const Linear_Expression &expr, bool maximize, Coefficient &ext_n, Coefficient &ext_d, bool &included, Generator &g) const |
Maximizes or minimizes expr subject to *this. | |
| bool | max_min (const Linear_Expression &expr, bool maximize, Coefficient &ext_n, Coefficient &ext_d, bool &included) const |
Maximizes or minimizes expr subject to *this. | |
| void | refine_no_check (const Constraint &c) |
Uses the constraint c to refine *this. | |
| void | refine_no_check (const Congruence &cg) |
Uses the congruence cg to refine *this. | |
| void | add_dbm_constraint (dimension_type i, dimension_type j, const N &k) |
Adds the constraint dbm[i][j] <= k. | |
| void | add_dbm_constraint (dimension_type i, dimension_type j, Coefficient_traits::const_reference num, Coefficient_traits::const_reference den) |
Adds the constraint dbm[i][j] <= num/den. | |
| void | refine (Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Adds to the BDS the constraint . | |
| void | forget_all_dbm_constraints (dimension_type v) |
Removes all the constraints on row/column v. | |
| void | forget_binary_dbm_constraints (dimension_type v) |
Removes all binary constraints on row/column v. | |
| void | deduce_v_minus_u_bounds (dimension_type v, dimension_type last_v, const Linear_Expression &sc_expr, Coefficient_traits::const_reference sc_den, const N &ub_v) |
| An helper function for the computation of affine relations. | |
| void | deduce_u_minus_v_bounds (dimension_type v, dimension_type last_v, const Linear_Expression &sc_expr, Coefficient_traits::const_reference sc_den, const N &minus_lb_v) |
| An helper function for the computation of affine relations. | |
| void | get_limiting_shape (const Constraint_System &cs, BD_Shape &limiting_shape) const |
Adds to limiting_shape the bounded differences in cs that are satisfied by *this. | |
| void | compute_predecessors (std::vector< dimension_type > &predecessor) const |
| Compute the (zero-equivalence classes) predecessor relation. | |
| void | compute_leaders (std::vector< dimension_type > &leaders) const |
| Compute the leaders of zero-equivalence classes. | |
Private Attributes | |
| DB_Matrix< N > | dbm |
| The matrix representing the system of bounded differences. | |
| Status | status |
| The status flags to keep track of the internal state. | |
| Bit_Matrix | redundancy_dbm |
| A matrix indicating which constraints are redundant. | |
Friends | |
| class | Parma_Polyhedra_Library::BD_Shape |
| class | Parma_Polyhedra_Library::Box |
| bool | operator== (const BD_Shape< T > &x, const BD_Shape< T > &y) |
Returns true if and only if x and y are the same BDS. | |
| template<typename Temp, typename To, typename U> | |
| bool | rectilinear_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< U > &x, const BD_Shape< U > &y, const Rounding_Dir dir, Temp &tmp0, Temp &tmp1, Temp &tmp2) |
| template<typename Temp, typename To, typename U> | |
| bool | euclidean_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< U > &x, const BD_Shape< U > &y, const Rounding_Dir dir, Temp &tmp0, Temp &tmp1, Temp &tmp2) |
| template<typename Temp, typename To, typename U> | |
| bool | l_infinity_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< U > &x, const BD_Shape< U > &y, const Rounding_Dir dir, Temp &tmp0, Temp &tmp1, Temp &tmp2) |
| std::ostream & | operator<< (std::ostream &s, const BD_Shape< T > &c) |
| Output operator. | |
Related Functions | |
| (Note that these are not member functions.) | |
| template<typename T> | |
| bool | operator!= (const BD_Shape< T > &x, const BD_Shape< T > &y) |
Returns true if and only if x and y aren't the same BDS. | |
| template<typename To, typename T> | |
| bool | rectilinear_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< T > &x, const BD_Shape< T > &y, Rounding_Dir dir) |
Computes the rectilinear (or Manhattan) distance between x and y. | |
| template<typename Temp, typename To, typename T> | |
| bool | rectilinear_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< T > &x, const BD_Shape< T > &y, Rounding_Dir dir, Temp &tmp0, Temp &tmp1, Temp &tmp2) |
Computes the rectilinear (or Manhattan) distance between x and y. | |
| template<typename To, typename T> | |
| bool | euclidean_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< T > &x, const BD_Shape< T > &y, Rounding_Dir dir) |
Computes the euclidean distance between x and y. | |
| template<typename Temp, typename To, typename T> | |
| bool | euclidean_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< T > &x, const BD_Shape< T > &y, Rounding_Dir dir, Temp &tmp0, Temp &tmp1, Temp &tmp2) |
Computes the euclidean distance between x and y. | |
| template<typename To, typename T> | |
| bool | l_infinity_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< T > &x, const BD_Shape< T > &y, Rounding_Dir dir) |
Computes the distance between x and y. | |
| template<typename Temp, typename To, typename T> | |
| bool | l_infinity_distance_assign (Checked_Number< To, Extended_Number_Policy > &r, const BD_Shape< T > &x, const BD_Shape< T > &y, Rounding_Dir dir, Temp &tmp0, Temp &tmp1, Temp &tmp2) |
Computes the distance between x and y. | |
| bool | extract_bounded_difference (const Constraint &c, dimension_type c_space_dim, dimension_type &c_num_vars, dimension_type &c_first_var, dimension_type &c_second_var, Coefficient &c_coeff) |
Decodes the constraint c as a bounded difference. | |
| void | compute_leader_indices (const std::vector< dimension_type > &predecessor, std::vector< dimension_type > &indices) |
| Extracts leader indices from the predecessor relation. | |
| template<typename T> | |
| void | swap (Parma_Polyhedra_Library::BD_Shape< T > &x, Parma_Polyhedra_Library::BD_Shape< T > &y) |
Specializes std::swap. | |
Classes | |
| class | Status |
| A conjunctive assertion about a BD_Shape<T> object. More... | |
The class template BD_Shape<T> allows for the efficient representation of a restricted kind of topologically closed convex polyhedra called bounded difference shapes (BDSs, for short). The name comes from the fact that the closed affine half-spaces that characterize the polyhedron can be expressed by constraints of the form
or
, where the inhomogeneous term
is a rational number.
Based on the class template type parameter T, a family of extended numbers is built and used to approximate the inhomogeneous term of bounded differences. These extended numbers provide a representation for the value
, as well as rounding-aware implementations for several arithmetic functions. The value of the type parameter T may be one of the following:
int32_t or int64_t);float or double);mpz_class or mpq_class).The user interface for BDSs is meant to be as similar as possible to the one developed for the polyhedron class C_Polyhedron. At the interface level, bounded differences are specified using objects of type Constraint: such a constraint is a bounded difference if it is of the form
where
and
,
,
are integer coefficients such that
, or
, or
. The user is warned that the above Constraint object will be mapped into a correct approximation that, depending on the expressive power of the chosen template argument T, may loose some precision. In particular, constraint objects that do not encode a bounded difference will be simply (and safely) ignored.
For instance, a Constraint object encoding
will be approximated by:
, if T is a (bounded or unbounded) integer type;
, if T is the unbounded rational type mpq_class;
, where
, if T is a floating point type (having no exact representation for
).
On the other hand, a Constraint object encoding
will be safely ignored in all of the above cases.
In the following examples it is assumed that the type argument T is one of the possible instances listed above and that variables x, y and z are defined (where they are used) as follows:
Variable x(0);
Variable y(1);
Variable z(2);
, given as a system of constraints: Constraint_System cs;
cs.insert(x >= 0);
cs.insert(x <= 1);
cs.insert(y >= 0);
cs.insert(y <= 1);
cs.insert(z >= 0);
cs.insert(z <= 1);
BD_Shape<T> bd(cs);
Constraint_System cs;
cs.insert(x >= 0);
cs.insert(x <= 1);
cs.insert(y >= 0);
cs.insert(y <= 1);
cs.insert(z >= 0);
cs.insert(z <= 1);
cs.insert(x + y <= 0); // 7
cs.insert(x - z + x >= 0); // 8
cs.insert(3*z - y <= 1); // 9
BD_Shape<T> bd(cs);
Definition at line 392 of file BD_Shape.defs.hh.
typedef Checked_Number<T, Extended_Number_Policy> Parma_Polyhedra_Library::BD_Shape< T >::N [private] |
The (extended) numeric type of the inhomogeneous term of the inequalities defining a BDS.
Definition at line 398 of file BD_Shape.defs.hh.
| typedef T Parma_Polyhedra_Library::BD_Shape< T >::coefficient_type_base |
The numeric base type upon which bounded differences are built.
Definition at line 402 of file BD_Shape.defs.hh.
| typedef N Parma_Polyhedra_Library::BD_Shape< T >::coefficient_type |
The (extended) numeric type of the inhomogeneous term of the inequalities defining a BDS.
Definition at line 408 of file BD_Shape.defs.hh.
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | dimension_type | num_dimensions = 0, |
|
| Degenerate_Element | kind = UNIVERSE | |||
| ) | [inline, explicit] |
Builds a universe or empty BDS of the specified space dimension.
| num_dimensions | The number of dimensions of the vector space enclosing the BDS; | |
| kind | Specifies whether the universe or the empty BDS has to be built. |
Definition at line 112 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::EMPTY, Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed().
00114 : dbm(num_dimensions + 1), status(), redundancy_dbm() { 00115 if (kind == EMPTY) 00116 set_empty(); 00117 else { 00118 if (num_dimensions > 0) 00119 // A (non zero-dim) universe BDS is closed. 00120 set_shortest_path_closed(); 00121 } 00122 assert(OK()); 00123 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const BD_Shape< T > & | y, | |
| Complexity_Class | complexity = ANY_COMPLEXITY | |||
| ) | [inline] |
Ordinary copy-constructor.
The complexity argument is ignored.
Definition at line 127 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), and Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm.
00128 : dbm(y.dbm), status(y.status), redundancy_dbm() { 00129 if (y.marked_shortest_path_reduced()) 00130 redundancy_dbm = y.redundancy_dbm; 00131 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const BD_Shape< U > & | y, | |
| Complexity_Class | complexity = ANY_COMPLEXITY | |||
| ) | [inline, explicit] |
Builds a conservative, upward approximation of y.
The complexity argument is ignored.
Definition at line 136 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_zero_dim_univ(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::set_zero_dim_univ().
00139 : dbm((y.shortest_path_closure_assign(), y.dbm)), 00140 status(), 00141 redundancy_dbm() { 00142 // TODO: handle flags properly, possibly taking special cases into account. 00143 if (y.marked_empty()) 00144 set_empty(); 00145 else if (y.marked_zero_dim_univ()) 00146 set_zero_dim_univ(); 00147 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const Constraint_System & | cs | ) | [inline, explicit] |
Builds a BDS from the system of constraints cs.
The BDS inherits the space dimension of cs.
| cs | A system of constraints: constraints that are not bounded differences are ignored (even though they may have contributed to the space dimension). |
| std::invalid_argument | Thrown if the system of constraints cs contains strict inequalities. |
Definition at line 309 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().
00310 : dbm(cs.space_dimension() + 1), status(), redundancy_dbm() { 00311 if (cs.space_dimension() > 0) 00312 // A (non zero-dim) universe BDS is shortest-path closed. 00313 set_shortest_path_closed(); 00314 add_constraints(cs); 00315 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const Congruence_System & | cgs | ) | [inline, explicit] |
Builds a BDS from a system of congruences.
The BDS inherits the space dimension of cgs
| cgs | A system of congruences: some elements may be safely ignored. |
Definition at line 47 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_congruences().
00048 : dbm(cgs.space_dimension() + 1), 00049 status(), 00050 redundancy_dbm() { 00051 add_congruences(cgs); 00052 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const Generator_System & | gs | ) | [inline, explicit] |
Builds a BDS from the system of generators gs.
Builds the smallest BDS containing the polyhedron defined by gs. The BDS inherits the space dimension of gs.
| std::invalid_argument | Thrown if the system of generators is not empty but has no points. |
Definition at line 55 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Generator_System::begin(), Parma_Polyhedra_Library::Generator::CLOSURE_POINT, Parma_Polyhedra_Library::Generator::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::Generator::divisor(), Parma_Polyhedra_Library::Generator_System::end(), Parma_Polyhedra_Library::Generator::LINE, Parma_Polyhedra_Library::max_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), PLUS_INFINITY, Parma_Polyhedra_Library::Generator::POINT, Parma_Polyhedra_Library::Generator::RAY, Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_generic(), and Parma_Polyhedra_Library::Generator::type().
00056 : dbm(gs.space_dimension() + 1), status(), redundancy_dbm() { 00057 const Generator_System::const_iterator gs_begin = gs.begin(); 00058 const Generator_System::const_iterator gs_end = gs.end(); 00059 if (gs_begin == gs_end) { 00060 // An empty generator system defines the empty polyhedron. 00061 set_empty(); 00062 return; 00063 } 00064 00065 const dimension_type space_dim = space_dimension(); 00066 DB_Row<N>& dbm_0 = dbm[0]; 00067 DIRTY_TEMP(N, tmp); 00068 00069 bool dbm_initialized = false; 00070 bool point_seen = false; 00071 // Going through all the points and closure points. 00072 for (Generator_System::const_iterator gs_i = gs_begin; 00073 gs_i != gs_end; ++gs_i) { 00074 const Generator& g = *gs_i; 00075 switch (g.type()) { 00076 case Generator::POINT: 00077 point_seen = true; 00078 // Intentionally fall through. 00079 case Generator::CLOSURE_POINT: 00080 if (!dbm_initialized) { 00081 // When handling the first (closure) point, we initialize the DBM. 00082 dbm_initialized = true; 00083 const Coefficient& d = g.divisor(); 00084 for (dimension_type i = space_dim; i > 0; --i) { 00085 const Coefficient& g_i = g.coefficient(Variable(i-1)); 00086 DB_Row<N>& dbm_i = dbm[i]; 00087 for (dimension_type j = space_dim; j > 0; --j) 00088 if (i != j) 00089 div_round_up(dbm_i[j], g.coefficient(Variable(j-1)) - g_i, d); 00090 div_round_up(dbm_i[0], -g_i, d); 00091 } 00092 for (dimension_type j = space_dim; j > 0; --j) 00093 div_round_up(dbm_0[j], g.coefficient(Variable(j-1)), d); 00094 // Note: no need to initialize the first element of the main diagonal. 00095 } 00096 else { 00097 // This is not the first point: the DBM already contains 00098 // valid values and we must compute maxima. 00099 const Coefficient& d = g.divisor(); 00100 for (dimension_type i = space_dim; i > 0; --i) { 00101 const Coefficient& g_i = g.coefficient(Variable(i-1)); 00102 DB_Row<N>& dbm_i = dbm[i]; 00103 // The loop correctly handles the case when i == j. 00104 for (dimension_type j = space_dim; j > 0; --j) { 00105 div_round_up(tmp, g.coefficient(Variable(j-1)) - g_i, d); 00106 max_assign(dbm_i[j], tmp); 00107 } 00108 div_round_up(tmp, -g_i, d); 00109 max_assign(dbm_i[0], tmp); 00110 } 00111 for (dimension_type j = space_dim; j > 0; --j) { 00112 div_round_up(tmp, g.coefficient(Variable(j-1)), d); 00113 max_assign(dbm_0[j], tmp); 00114 } 00115 } 00116 break; 00117 default: 00118 // Lines and rays temporarily ignored. 00119 break; 00120 } 00121 } 00122 00123 if (!point_seen) 00124 // The generator system is not empty, but contains no points. 00125 throw_generic("BD_Shape(gs)", 00126 "the non-empty generator system gs contains no points."); 00127 00128 // Going through all the lines and rays. 00129 for (Generator_System::const_iterator gs_i = gs_begin; 00130 gs_i != gs_end; ++gs_i) { 00131 const Generator& g = *gs_i; 00132 switch (g.type()) { 00133 case Generator::LINE: 00134 for (dimension_type i = space_dim; i > 0; --i) { 00135 const Coefficient& g_i = g.coefficient(Variable(i-1)); 00136 DB_Row<N>& dbm_i = dbm[i]; 00137 // The loop correctly handles the case when i == j. 00138 for (dimension_type j = space_dim; j > 0; --j) 00139 if (g_i != g.coefficient(Variable(j-1))) 00140 assign_r(dbm_i[j], PLUS_INFINITY, ROUND_NOT_NEEDED); 00141 if (g_i != 0) 00142 assign_r(dbm_i[0], PLUS_INFINITY, ROUND_NOT_NEEDED); 00143 } 00144 for (dimension_type j = space_dim; j > 0; --j) 00145 if (g.coefficient(Variable(j-1)) != 0) 00146 assign_r(dbm_0[j], PLUS_INFINITY, ROUND_NOT_NEEDED); 00147 break; 00148 case Generator::RAY: 00149 for (dimension_type i = space_dim; i > 0; --i) { 00150 const Coefficient& g_i = g.coefficient(Variable(i-1)); 00151 DB_Row<N>& dbm_i = dbm[i]; 00152 // The loop correctly handles the case when i == j. 00153 for (dimension_type j = space_dim; j > 0; --j) 00154 if (g_i < g.coefficient(Variable(j-1))) 00155 assign_r(dbm_i[j], PLUS_INFINITY, ROUND_NOT_NEEDED); 00156 if (g_i < 0) 00157 assign_r(dbm_i[0], PLUS_INFINITY, ROUND_NOT_NEEDED); 00158 } 00159 for (dimension_type j = space_dim; j > 0; --j) 00160 if (g.coefficient(Variable(j-1)) > 0) 00161 assign_r(dbm_0[j], PLUS_INFINITY, ROUND_NOT_NEEDED); 00162 break; 00163 default: 00164 // Points and closure points already dealt with. 00165 break; 00166 } 00167 } 00168 set_shortest_path_closed(); 00169 assert(OK()); 00170 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const Polyhedron & | ph, | |
| Complexity_Class | complexity = ANY_COMPLEXITY | |||
| ) | [inline, explicit] |
Builds a BDS from the polyhedron ph.
Builds a BDS containing ph using algorithms whose complexity does not exceed the one specified by complexity. If complexity is ANY_COMPLEXITY, then the BDS built is the smallest one containing ph.
Definition at line 173 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::MIP_Problem::add_constraint(), Parma_Polyhedra_Library::MIP_Problem::add_constraints(), Parma_Polyhedra_Library::ANY_COMPLEXITY, Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Polyhedron::con_sys, Parma_Polyhedra_Library::Polyhedron::constraints(), Parma_Polyhedra_Library::Polyhedron::constraints_are_minimized(), Parma_Polyhedra_Library::Polyhedron::constraints_are_up_to_date(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::EMPTY, Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::MIP_Problem::evaluate_objective_function(), Parma_Polyhedra_Library::Polyhedron::generators(), Parma_Polyhedra_Library::Polyhedron::generators_are_up_to_date(), Parma_Polyhedra_Library::Polyhedron::has_pending_constraints(), Parma_Polyhedra_Library::Polyhedron::has_something_pending(), Parma_Polyhedra_Library::Constraint_System::has_strict_inequalities(), Parma_Polyhedra_Library::MIP_Problem::is_satisfiable(), Parma_Polyhedra_Library::Constraint::is_strict_inequality(), Parma_Polyhedra_Library::Polyhedron::is_universe(), Parma_Polyhedra_Library::Polyhedron::marked_empty(), Parma_Polyhedra_Library::MAXIMIZATION, Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::OPTIMIZED_MIP_PROBLEM, Parma_Polyhedra_Library::MIP_Problem::optimizing_point(), Parma_Polyhedra_Library::POLYNOMIAL_COMPLEXITY, Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints(), Parma_Polyhedra_Library::MIP_Problem::set_objective_function(), Parma_Polyhedra_Library::MIP_Problem::set_optimization_mode(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), Parma_Polyhedra_Library::SIMPLEX_COMPLEXITY, Parma_Polyhedra_Library::MIP_Problem::solve(), Parma_Polyhedra_Library::Polyhedron::space_dimension(), TEMP_INTEGER, and Parma_Polyhedra_Library::UNIVERSE.
00174 : dbm(), status(), redundancy_dbm() { 00175 const dimension_type num_dimensions = ph.space_dimension(); 00176 00177 if (ph.marked_empty()) { 00178 *this = BD_Shape<T>(num_dimensions, EMPTY); 00179 return; 00180 } 00181 00182 if (num_dimensions == 0) { 00183 *this = BD_Shape<T>(num_dimensions, UNIVERSE); 00184 return; 00185 } 00186 00187 // Build from generators when we do not care about complexity 00188 // or when the process has polynomial complexity. 00189 if (complexity == ANY_COMPLEXITY 00190 || (!ph.has_pending_constraints() && ph.generators_are_up_to_date())) { 00191 *this = BD_Shape<T>(ph.generators()); 00192 return; 00193 } 00194 00195 // We cannot afford exponential complexity, we do not have a complete set 00196 // of generators for the polyhedron, and the polyhedron is not trivially 00197 // empty or zero-dimensional. Constraints, however, are up to date. 00198 assert(ph.constraints_are_up_to_date()); 00199 00200 if (!ph.has_something_pending() && ph.constraints_are_minimized()) { 00201 // If the constraint system of the polyhedron is minimized, 00202 // the test `is_universe()' has polynomial complexity. 00203 if (ph.is_universe()) { 00204 *this = BD_Shape<T>(num_dimensions, UNIVERSE); 00205 return; 00206 } 00207 } 00208 00209 // See if there is at least one inconsistent constraint in `ph.con_sys'. 00210 for (Constraint_System::const_iterator i = ph.con_sys.begin(), 00211 cs_end = ph.con_sys.end(); i != cs_end; ++i) 00212 if (i->is_inconsistent()) { 00213 *this = BD_Shape<T>(num_dimensions, EMPTY); 00214 return; 00215 } 00216 00217 // If `complexity' allows it, use simplex to derive the exact (modulo 00218 // the fact that our BDSs are topologically closed) variable bounds. 00219 if (complexity == SIMPLEX_COMPLEXITY) { 00220 MIP_Problem lp(num_dimensions); 00221 lp.set_optimization_mode(MAXIMIZATION); 00222 00223 const Constraint_System& ph_cs = ph.constraints(); 00224 if (!ph_cs.has_strict_inequalities()) 00225 lp.add_constraints(ph_cs); 00226 else 00227 // Adding to `lp' a topologically closed version of `ph_cs'. 00228 for (Constraint_System::const_iterator i = ph_cs.begin(), 00229 ph_cs_end = ph_cs.end(); i != ph_cs_end; ++i) { 00230 const Constraint& c = *i; 00231 if (c.is_strict_inequality()) 00232 lp.add_constraint(Linear_Expression(c) >= 0); 00233 else 00234 lp.add_constraint(c); 00235 } 00236 00237 // Check for unsatisfiability. 00238 if (!lp.is_satisfiable()) { 00239 *this = BD_Shape<T>(num_dimensions, EMPTY); 00240 return; 00241 } 00242 00243 // Start with a universe BDS that will be refined by the simplex. 00244 *this = BD_Shape<T>(num_dimensions, UNIVERSE); 00245 // Get all the upper bounds. 00246 Generator g(point()); 00247 TEMP_INTEGER(num); 00248 TEMP_INTEGER(den); 00249 for (dimension_type i = 1; i <= num_dimensions; ++i) { 00250 Variable x(i-1); 00251 // Evaluate optimal upper bound for `x <= ub'. 00252 lp.set_objective_function(x); 00253 if (lp.solve() == OPTIMIZED_MIP_PROBLEM) { 00254 g = lp.optimizing_point(); 00255 lp.evaluate_objective_function(g, num, den); 00256 div_round_up(dbm[0][i], num, den); 00257 } 00258 // Evaluate optimal upper bound for `x - y <= ub'. 00259 for (dimension_type j = 1; j <= num_dimensions; ++j) { 00260 if (i == j) 00261 continue; 00262 Variable y(j-1); 00263 lp.set_objective_function(x - y); 00264 if (lp.solve() == OPTIMIZED_MIP_PROBLEM) { 00265 g = lp.optimizing_point(); 00266 lp.evaluate_objective_function(g, num, den); 00267 div_round_up(dbm[j][i], num, den); 00268 } 00269 } 00270 // Evaluate optimal upper bound for `-x <= ub'. 00271 lp.set_objective_function(-x); 00272 if (lp.solve() == OPTIMIZED_MIP_PROBLEM) { 00273 g = lp.optimizing_point(); 00274 lp.evaluate_objective_function(g, num, den); 00275 div_round_up(dbm[i][0], num, den); 00276 } 00277 } 00278 set_shortest_path_closed(); 00279 assert(OK()); 00280 return; 00281 } 00282 00283 // Extract easy-to-find bounds from constraints. 00284 assert(complexity == POLYNOMIAL_COMPLEXITY); 00285 *this = BD_Shape<T>(num_dimensions, UNIVERSE); 00286 refine_with_constraints(ph.constraints()); 00287 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const Box< Interval > & | box, | |
| Complexity_Class | complexity = ANY_COMPLEXITY | |||
| ) | [inline, explicit] |
Builds a BDS out of a box.
The BDS inherits the space dimension of the box. The built BDS is the most precise BDS that includes the box.
| box | The box representing the BDS to be built. | |
| complexity | This argument is ignored as the algorithm used has polynomial complexity. |
| std::length_error | Thrown if the space dimension of box exceeds the maximum allowed space dimension. |
Definition at line 320 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::Box< ITV >::constraints(), Parma_Polyhedra_Library::Box< ITV >::is_empty(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), and Parma_Polyhedra_Library::Box< ITV >::space_dimension().
00322 : dbm(box.space_dimension() + 1), status(), redundancy_dbm() { 00323 // Check for emptyness for maximum precision. 00324 if (box.is_empty()) 00325 set_empty(); 00326 else if (box.space_dimension() > 0) { 00327 // A (non zero-dim) universe BDS is shortest-path closed. 00328 set_shortest_path_closed(); 00329 refine_with_constraints(box.constraints()); 00330 } 00331 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const Grid & | grid, | |
| Complexity_Class | complexity = ANY_COMPLEXITY | |||
| ) | [inline, explicit] |
Builds a BDS out of a grid.
The BDS inherits the space dimension of the grid. The built BDS is the most precise BDS that includes the grid.
| grid | The grid used to build the BDS. | |
| complexity | This argument is ignored as the algorithm used has polynomial complexity. |
| std::length_error | Thrown if the space dimension of grid exceeds the maximum allowed space dimension. |
Definition at line 335 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::Grid::minimized_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), and Parma_Polyhedra_Library::Grid::space_dimension().
00337 : dbm(grid.space_dimension() + 1), status(), redundancy_dbm() { 00338 if (grid.space_dimension() > 0) 00339 // A (non zero-dim) universe BDS is shortest-path closed. 00340 set_shortest_path_closed(); 00341 // Taking minimized congruences ensures maximum precision. 00342 refine_with_congruences(grid.minimized_congruences()); 00343 }
| Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape | ( | const Octagonal_Shape< U > & | os, | |
| Complexity_Class | complexity = ANY_COMPLEXITY | |||
| ) | [inline, explicit] |
Builds a BDS from an octagonal shape.
The BDS inherits the space dimension of the octagonal shape. The built BDS is the most precise BDS that includes the octagonal shape.
| os | The octagonal shape used to build the BDS. | |
| complexity | This argument is ignored as the algorithm used has polynomial complexity. |
| std::length_error | Thrown if the space dimension of os exceeds the maximum allowed space dimension. |
Definition at line 348 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::Octagonal_Shape< T >::constraints(), Parma_Polyhedra_Library::Octagonal_Shape< T >::is_empty(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), and Parma_Polyhedra_Library::Octagonal_Shape< T >::space_dimension().
00350 : dbm(os.space_dimension() + 1), status(), redundancy_dbm() { 00351 // Check for emptyness for maximum precision. 00352 if (os.is_empty()) 00353 set_empty(); 00354 else if (os.space_dimension() > 0) { 00355 // A (non zero-dim) universe BDS is shortest-path closed. 00356 set_shortest_path_closed(); 00357 refine_with_constraints(os.constraints()); 00358 // After refining, shortest-path closure is possibly lost 00359 // (even when `os' was strongly closed: recall that U 00360 // is possibly different from T). 00361 } 00362 }
| Parma_Polyhedra_Library::BD_Shape< T >::~BD_Shape | ( | ) | [inline] |
| dimension_type Parma_Polyhedra_Library::BD_Shape< T >::max_space_dimension | ( | ) | [inline, static] |
Returns the maximum space dimension that a BDS can handle.
Definition at line 43 of file BD_Shape.inlines.hh.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension().
00043 { 00044 // One dimension is reserved to have a value of type dimension_type 00045 // that does not represent a legal dimension. 00046 return std::min(DB_Matrix<N>::max_num_rows() - 1, 00047 DB_Matrix<N>::max_num_columns() - 1); 00048 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::can_recycle_constraint_systems | ( | ) | [inline, static] |
Returns false indicating that this domain cannot recycle constraints.
Definition at line 296 of file BD_Shape.inlines.hh.
| bool Parma_Polyhedra_Library::BD_Shape< T >::can_recycle_congruence_systems | ( | ) | [inline, static] |
Returns false indicating that this domain cannot recycle congruences.
Definition at line 303 of file BD_Shape.inlines.hh.
| BD_Shape< T > & Parma_Polyhedra_Library::BD_Shape< T >::operator= | ( | const BD_Shape< T > & | y | ) | [inline] |
The assignment operator (*this and y can be dimension-incompatible).
Definition at line 366 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, and Parma_Polyhedra_Library::BD_Shape< T >::status.
00366 { 00367 dbm = y.dbm; 00368 status = y.status; 00369 if (y.marked_shortest_path_reduced()) 00370 redundancy_dbm = y.redundancy_dbm; 00371 return *this; 00372 }
| void Parma_Polyhedra_Library::BD_Shape< T >::swap | ( | BD_Shape< T > & | y | ) | [inline] |
Swaps *this with y (*this and y can be dimension-incompatible).
Definition at line 381 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, Parma_Polyhedra_Library::BD_Shape< T >::status, and Parma_Polyhedra_Library::swap().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::H79_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_H79_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::swap(), and Parma_Polyhedra_Library::BD_Shape< T >::time_elapse_assign().
00381 { 00382 std::swap(dbm, y.dbm); 00383 std::swap(status, y.status); 00384 std::swap(redundancy_dbm, y.redundancy_dbm); 00385 }
| dimension_type Parma_Polyhedra_Library::BD_Shape< T >::space_dimension | ( | ) | const [inline] |
Returns the dimension of the vector space enclosing *this.
Definition at line 389 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project(), Parma_Polyhedra_Library::BD_Shape< T >::affine_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::bounds(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::constrains(), Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::contains_integer_point(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::euclidean_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::BD_Shape< T >::hash_code(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::is_bounded(), Parma_Polyhedra_Library::BD_Shape< T >::is_disjoint_from(), Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::is_universe(), Parma_Polyhedra_Library::BD_Shape< T >::l_infinity_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::max_min(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints(), Parma_Polyhedra_Library::Octagonal_Shape< T >::Octagonal_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::rectilinear_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::refine(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::relation_with(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), Parma_Polyhedra_Library::BD_Shape< T >::time_elapse_assign(), Parma_Polyhedra_Library::BD_Shape< T >::unconstrain(), Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign_and_minimize().
00389 { 00390 return dbm.num_rows() - 1; 00391 }
| dimension_type Parma_Polyhedra_Library::BD_Shape< T >::affine_dimension | ( | ) | const [inline] |
Returns
, if *this is empty; otherwise, returns the affine dimension of *this.
Definition at line 291 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::compute_predecessors(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::is_discrete().
00291 { 00292 const dimension_type space_dim = space_dimension(); 00293 // A zero-space-dim shape always has affine dimension zero. 00294 if (space_dim == 0) 00295 return 0; 00296 00297 // Shortest-path closure is necessary to detect emptiness 00298 // and all (possibly implicit) equalities. 00299 shortest_path_closure_assign(); 00300 if (marked_empty()) 00301 return 0; 00302 00303 // The vector `predecessor' is used to represent equivalence classes: 00304 // `predecessor[i] == i' if and only if `i' is the leader of its 00305 // equivalence class (i.e., the minimum index in the class); 00306 std::vector<dimension_type> predecessor; 00307 compute_predecessors(predecessor); 00308 00309 // Due to the fictitious variable `0', the affine dimension is one 00310 // less the number of equivalence classes. 00311 dimension_type affine_dim = 0; 00312 // Note: disregard the first equivalence class. 00313 for (dimension_type i = 1; i <= space_dim; ++i) 00314 if (predecessor[i] == i) 00315 ++affine_dim; 00316 00317 return affine_dim; 00318 }
| Constraint_System Parma_Polyhedra_Library::BD_Shape< T >::constraints | ( | ) | const [inline] |
Returns a system of constraints defining *this.
Definition at line 4675 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::is_additive_inverse(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints(), Parma_Polyhedra_Library::numer_denom(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, and Parma_Polyhedra_Library::Constraint_System::zero_dim_empty().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::bounds(), Parma_Polyhedra_Library::C_Polyhedron::C_Polyhedron(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::H79_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_H79_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::max_min(), Parma_Polyhedra_Library::NNC_Polyhedron::NNC_Polyhedron(), Parma_Polyhedra_Library::Octagonal_Shape< T >::Octagonal_Shape(), and Parma_Polyhedra_Library::BD_Shape< T >::time_elapse_assign().
04675 { 04676 Constraint_System cs; 04677 const dimension_type space_dim = space_dimension(); 04678 if (space_dim == 0) { 04679 if (marked_empty()) 04680 cs = Constraint_System::zero_dim_empty(); 04681 } 04682 else if (marked_empty()) 04683 cs.insert(0*Variable(space_dim-1) <= -1); 04684 else if (marked_shortest_path_reduced()) 04685 // Disregard redundant constraints. 04686 cs = minimized_constraints(); 04687 else { 04688 // KLUDGE: in the future `cs' will be constructed of the right dimension. 04689 // For the time being, we force the dimension with the following line. 04690 cs.insert(0*Variable(space_dim-1) <= 0); 04691 04692 TEMP_INTEGER(a); 04693 TEMP_INTEGER(b); 04694 // Go through all the unary constraints in `dbm'. 04695 const DB_Row<N>& dbm_0 = dbm[0]; 04696 for (dimension_type j = 1; j <= space_dim; ++j) { 04697 const Variable x(j-1); 04698 const N& dbm_0j = dbm_0[j]; 04699 const N& dbm_j0 = dbm[j][0]; 04700 if (is_additive_inverse(dbm_j0, dbm_0j)) { 04701 // We have a unary equality constraint. 04702 numer_denom(dbm_0j, b, a); 04703 cs.insert(a*x == b); 04704 } 04705 else { 04706 // We have 0, 1 or 2 unary inequality constraints. 04707 if (!is_plus_infinity(dbm_0j)) { 04708 numer_denom(dbm_0j, b, a); 04709 cs.insert(a*x <= b); 04710 } 04711 if (!is_plus_infinity(dbm_j0)) { 04712 numer_denom(dbm_j0, b, a); 04713 cs.insert(-a*x <= b); 04714 } 04715 } 04716 } 04717 04718 // Go through all the binary constraints in `dbm'. 04719 for (dimension_type i = 1; i <= space_dim; ++i) { 04720 const Variable y(i-1); 04721 const DB_Row<N>& dbm_i = dbm[i]; 04722 for (dimension_type j = i + 1; j <= space_dim; ++j) { 04723 const Variable x(j-1); 04724 const N& dbm_ij = dbm_i[j]; 04725 const N& dbm_ji = dbm[j][i]; 04726 if (is_additive_inverse(dbm_ji, dbm_ij)) { 04727 // We have a binary equality constraint. 04728 numer_denom(dbm_ij, b, a); 04729 cs.insert(a*x - a*y == b); 04730 } 04731 else { 04732 // We have 0, 1 or 2 binary inequality constraints. 04733 if (!is_plus_infinity(dbm_ij)) { 04734 numer_denom(dbm_ij, b, a); 04735 cs.insert(a*x - a*y <= b); 04736 } 04737 if (!is_plus_infinity(dbm_ji)) { 04738 numer_denom(dbm_ji, b, a); 04739 cs.insert(a*y - a*x <= b); 04740 } 04741 } 04742 } 04743 } 04744 } 04745 return cs; 04746 }
| Constraint_System Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints | ( | ) | const [inline] |
Returns a minimized system of constraints defining *this.
Definition at line 4750 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::compute_leader_indices(), Parma_Polyhedra_Library::BD_Shape< T >::compute_leaders(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::numer_denom(), Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, and Parma_Polyhedra_Library::Constraint_System::zero_dim_empty().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::constraints().
04750 { 04751 shortest_path_reduction_assign(); 04752 Constraint_System cs; 04753 const dimension_type space_dim = space_dimension(); 04754 if (space_dim == 0) { 04755 if (marked_empty()) 04756 cs = Constraint_System::zero_dim_empty(); 04757 } 04758 else if (marked_empty()) 04759 cs.insert(0*Variable(space_dim-1) <= -1); 04760 else { 04761 // KLUDGE: in the future `cs' will be constructed of the right dimension. 04762 // For the time being, we force the dimension with the following line. 04763 cs.insert(0*Variable(space_dim-1) <= 0); 04764 04765 TEMP_INTEGER(num); 04766 TEMP_INTEGER(den); 04767 04768 // Compute leader information. 04769 std::vector<dimension_type> leaders; 04770 compute_leaders(leaders); 04771 std::vector<dimension_type> leader_indices; 04772 compute_leader_indices(leaders, leader_indices); 04773 const dimension_type num_leaders = leader_indices.size(); 04774 04775 // Go through the non-leaders to generate equality constraints. 04776 const DB_Row<N>& dbm_0 = dbm[0]; 04777 for (dimension_type i = 1; i <= space_dim; ++i) { 04778 const dimension_type leader = leaders[i]; 04779 if (i != leader) { 04780 // Generate the constraint relating `i' and its leader. 04781 if (leader == 0) { 04782 // A unary equality has to be generated. 04783 assert(!is_plus_infinity(dbm_0[i])); 04784 numer_denom(dbm_0[i], num, den); 04785 cs.insert(den*Variable(i-1) == num); 04786 } 04787 else { 04788 // A binary equality has to be generated. 04789 assert(!is_plus_infinity(dbm[i][leader])); 04790 numer_denom(dbm[i][leader], num, den); 04791 cs.insert(den*Variable(leader-1) - den*Variable(i-1) == num); 04792 } 04793 } 04794 } 04795 04796 // Go through the leaders to generate inequality constraints. 04797 // First generate all the unary inequalities. 04798 const Bit_Row& red_0 = redundancy_dbm[0]; 04799 for (dimension_type l_i = 1; l_i < num_leaders; ++l_i) { 04800 const dimension_type i = leader_indices[l_i]; 04801 if (!red_0[i]) { 04802 numer_denom(dbm_0[i], num, den); 04803 cs.insert(den*Variable(i-1) <= num); 04804 } 04805 if (!redundancy_dbm[i][0]) { 04806 numer_denom(dbm[i][0], num, den); 04807 cs.insert(-den*Variable(i-1) <= num); 04808 } 04809 } 04810 // Then generate all the binary inequalities. 04811 for (dimension_type l_i = 1; l_i < num_leaders; ++l_i) { 04812 const dimension_type i = leader_indices[l_i]; 04813 const DB_Row<N>& dbm_i = dbm[i]; 04814 const Bit_Row& red_i = redundancy_dbm[i]; 04815 for (dimension_type l_j = l_i + 1; l_j < num_leaders; ++l_j) { 04816 const dimension_type j = leader_indices[l_j]; 04817 if (!red_i[j]) { 04818 numer_denom(dbm_i[j], num, den); 04819 cs.insert(den*Variable(j-1) - den*Variable(i-1) <= num); 04820 } 04821 if (!redundancy_dbm[j][i]) { 04822 numer_denom(dbm[j][i], num, den); 04823 cs.insert(den*Variable(i-1) - den*Variable(j-1) <= num); 04824 } 04825 } 04826 } 04827 } 04828 return cs; 04829 }
| Congruence_System Parma_Polyhedra_Library::BD_Shape< T >::congruences | ( | ) | const [inline] |
Returns a system of (equality) congruences satisfied by *this.
Definition at line 151 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::minimized_congruences().
Referenced by Parma_Polyhedra_Library::Grid::Grid().
00151 { 00152 return minimized_congruences(); 00153 }
| Congruence_System Parma_Polyhedra_Library::BD_Shape< T >::minimized_congruences | ( | ) | const [inline] |
Returns a minimal system of (equality) congruences satisfied by *this with the same affine dimension as *this.
Definition at line 322 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::compute_leaders(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::numer_denom(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, and Parma_Polyhedra_Library::Congruence_System::zero_dim_empty().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::congruences().
00322 { 00323 // Shortest-path closure is necessary to detect emptiness 00324 // and all (possibly implicit) equalities. 00325 shortest_path_closure_assign(); 00326 00327 const dimension_type space_dim = space_dimension(); 00328 Congruence_System cgs; 00329 if (space_dim == 0) { 00330 if (marked_empty()) 00331 cgs = Congruence_System::zero_dim_empty(); 00332 } 00333 else if (marked_empty()) 00334 cgs.insert((0*Variable(space_dim-1) %= 1) / 0); 00335 else { 00336 // KLUDGE: in the future `cgs' will be constructed of the right dimension. 00337 // For the time being, we force the dimension with the following line. 00338 cgs.insert(0*Variable(space_dim-1) == 0); 00339 00340 TEMP_INTEGER(num); 00341 TEMP_INTEGER(den); 00342 00343 // Compute leader information. 00344 std::vector<dimension_type> leaders; 00345 compute_leaders(leaders); 00346 00347 // Go through the non-leaders to generate equality constraints. 00348 const DB_Row<N>& dbm_0 = dbm[0]; 00349 for (dimension_type i = 1; i <= space_dim; ++i) { 00350 const dimension_type leader = leaders[i]; 00351 if (i != leader) { 00352 // Generate the constraint relating `i' and its leader. 00353 if (leader == 0) { 00354 // A unary equality has to be generated. 00355 assert(!is_plus_infinity(dbm_0[i])); 00356 numer_denom(dbm_0[i], num, den); 00357 cgs.insert(den*Variable(i-1) == num); 00358 } 00359 else { 00360 // A binary equality has to be generated. 00361 assert(!is_plus_infinity(dbm[i][leader])); 00362 numer_denom(dbm[i][leader], num, den); 00363 cgs.insert(den*Variable(leader-1) - den*Variable(i-1) == num); 00364 } 00365 } 00366 } 00367 } 00368 return cgs; 00369 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::bounds_from_above | ( | const Linear_Expression & | expr | ) | const [inline] |
Returns true if and only if expr is bounded from above in *this.
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
Definition at line 402 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::bounds().
00402 { 00403 return bounds(expr, true); 00404 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::bounds_from_below | ( | const Linear_Expression & | expr | ) | const [inline] |
Returns true if and only if expr is bounded from below in *this.
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
Definition at line 408 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::bounds().
00408 { 00409 return bounds(expr, false); 00410 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::maximize | ( | const Linear_Expression & | expr, | |
| Coefficient & | sup_n, | |||
| Coefficient & | sup_d, | |||
| bool & | maximum | |||
| ) | const [inline] |
Returns true if and only if *this is not empty and expr is bounded from above in *this, in which case the supremum value is computed.
| expr | The linear expression to be maximized subject to *this; | |
| sup_n | The numerator of the supremum value; | |
| sup_d | The denominator of the supremum value; | |
| maximum | true if and only if the supremum is also the maximum value. |
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this is empty or expr is not bounded from above, false is returned and sup_n, sup_d and maximum are left untouched.
Definition at line 414 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::max_min().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::relation_with().
00416 { 00417 return max_min(expr, true, sup_n, sup_d, maximum); 00418 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::maximize | ( | const Linear_Expression & | expr, | |
| Coefficient & | sup_n, | |||
| Coefficient & | sup_d, | |||
| bool & | maximum, | |||
| Generator & | g | |||
| ) | const [inline] |
Returns true if and only if *this is not empty and expr is bounded from above in *this, in which case the supremum value and a point where expr reaches it are computed.
| expr | The linear expression to be maximized subject to *this; | |
| sup_n | The numerator of the supremum value; | |
| sup_d | The denominator of the supremum value; | |
| maximum | true if and only if the supremum is also the maximum value; | |
| g | When maximization succeeds, will be assigned the point or closure point where expr reaches its supremum value. |
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this is empty or expr is not bounded from above, false is returned and sup_n, sup_d, maximum and g are left untouched.
Definition at line 422 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::max_min().
00424 { 00425 return max_min(expr, true, sup_n, sup_d, maximum, g); 00426 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::minimize | ( | const Linear_Expression & | expr, | |
| Coefficient & | inf_n, | |||
| Coefficient & | inf_d, | |||
| bool & | minimum | |||
| ) | const [inline] |
Returns true if and only if *this is not empty and expr is bounded from below in *this, in which case the infimum value is computed.
| expr | The linear expression to be minimized subject to *this; | |
| inf_n | The numerator of the infimum value; | |
| inf_d | The denominator of the infimum value; | |
| minimum | true if and only if the infimum is also the minimum value. |
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this is empty or expr is not bounded from below, false is returned and inf_n, inf_d and minimum are left untouched.
Definition at line 430 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::max_min().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::relation_with().
00432 { 00433 return max_min(expr, false, inf_n, inf_d, minimum); 00434 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::minimize | ( | const Linear_Expression & | expr, | |
| Coefficient & | inf_n, | |||
| Coefficient & | inf_d, | |||
| bool & | minimum, | |||
| Generator & | g | |||
| ) | const [inline] |
Returns true if and only if *this is not empty and expr is bounded from below in *this, in which case the infimum value and a point where expr reaches it are computed.
| expr | The linear expression to be minimized subject to *this; | |
| inf_n | The numerator of the infimum value; | |
| inf_d | The denominator of the infimum value; | |
| minimum | true if and only if the infimum is also the minimum value; | |
| g | When minimization succeeds, will be assigned a point or closure point where expr reaches its infimum value. |
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this is empty or expr is not bounded from below, false is returned and inf_n, inf_d, minimum and g are left untouched.
Definition at line 438 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::max_min().
00440 { 00441 return max_min(expr, false, inf_n, inf_d, minimum, g); 00442 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::contains | ( | const BD_Shape< T > & | y | ) | const [inline] |
Returns true if and only if *this contains y.
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 577 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::strictly_contains().
00577 { 00578 const BD_Shape<T>& x = *this; 00579 const dimension_type x_space_dim = x.space_dimension(); 00580 00581 // Dimension-compatibility check. 00582 if (x_space_dim != y.space_dimension()) 00583 throw_dimension_incompatible("contains(y)", y); 00584 00585 // The zero-dimensional universe shape contains any other 00586 // dimension-compatible shape. 00587 // The zero-dimensional empty shape only contains another 00588 // zero-dimensional empty shape. 00589 if (x_space_dim == 0) { 00590 if (!marked_empty()) 00591 return true; 00592 else 00593 return y.marked_empty(); 00594 } 00595 00596 /* 00597 The `y' bounded difference shape need be closed. 00598 In fact if, for example, in `*this' we have the constraints: 00599 00600 x1 - x2 <= 1; 00601 x1 <= 3; 00602 x2 <= 2; 00603 00604 in `y' the constraints are: 00605 00606 x1 - x2 <= 0; 00607 x2 <= 1; 00608 00609 without closure it returns "false", instead if we close `y' we have 00610 the implicit constraint 00611 00612 x1 <= 1; 00613 00614 and so we obtain the right result "true". 00615 */ 00616 y.shortest_path_closure_assign(); 00617 00618 // An empty shape is contained in any other dimension-compatible shapes. 00619 if (y.marked_empty()) 00620 return true; 00621 00622 // `*this' contains `y' if and only if every cell of `dbm' 00623 // is greater than or equal to the correspondent one of `y.dbm'. 00624 for (dimension_type i = x_space_dim + 1; i-- > 0; ) { 00625 const DB_Row<N>& x_dbm_i = x.dbm[i]; 00626 const DB_Row<N>& y_dbm_i = y.dbm[i]; 00627 for (dimension_type j = x_space_dim + 1; j-- > 0; ) 00628 if (x_dbm_i[j] < y_dbm_i[j]) 00629 return false; 00630 } 00631 return true; 00632 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::strictly_contains | ( | const BD_Shape< T > & | y | ) | const [inline] |
Returns true if and only if *this strictly contains y.
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 743 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::contains().
| bool Parma_Polyhedra_Library::BD_Shape< T >::is_disjoint_from | ( | const BD_Shape< T > & | y | ) | const [inline] |
Returns true if and only if *this and y are disjoint.
| std::invalid_argument | Thrown if x and y are topology-incompatible or dimension-incompatible. |
Definition at line 636 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
00636 { 00637 const dimension_type space_dim = space_dimension(); 00638 // Dimension-compatibility check. 00639 if (space_dim != y.space_dimension()) 00640 throw_dimension_incompatible("is_disjoint_from(y)", y); 00641 00642 // If one of the two bounded difference shape is empty, 00643 // then the two bounded difference shape are disjoint. 00644 shortest_path_closure_assign(); 00645 if (marked_empty()) 00646 return true; 00647 y.shortest_path_closure_assign(); 00648 if (y.marked_empty()) 00649 return true; 00650 00651 // Two BDSs are disjoint when their intersection is empty. 00652 // That is if and only if there exists at least a bounded difference 00653 // such that the upper bound of the bounded difference in the first 00654 // BD_Shape is strictly less than the lower bound of 00655 // the corresponding bounded difference in the second BD_Shape 00656 // or vice versa. 00657 // For example: let be 00658 // in `*this': -a_j_i <= v_j - v_i <= a_i_j; 00659 // and in `y': -b_j_i <= v_j - v_i <= b_i_j; 00660 // `*this' and `y' are disjoint if 00661 // 1.) a_i_j < -b_j_i or 00662 // 2.) b_i_j < -a_j_i. 00663 DIRTY_TEMP(N, tmp); 00664 for (dimension_type i = space_dim+1; i-- > 0; ) { 00665 const DB_Row<N>& x_i = dbm[i]; 00666 for (dimension_type j = space_dim+1; j-- > 0; ) { 00667 neg_assign_r(tmp, y.dbm[j][i], ROUND_UP); 00668 if (x_i[j] < tmp) 00669 return true; 00670 } 00671 } 00672 00673 return false; 00674 }
| Poly_Con_Relation Parma_Polyhedra_Library::BD_Shape< T >::relation_with | ( | const Constraint & | c | ) | const [inline] |
Returns the relations holding between *this and the constraint c.
| std::invalid_argument | Thrown if *this and constraint c are dimension-incompatible. |
Definition at line 1272 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Constraint::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::extract_bounded_difference(), Parma_Polyhedra_Library::Constraint::inhomogeneous_term(), Parma_Polyhedra_Library::Poly_Con_Relation::is_disjoint(), Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), Parma_Polyhedra_Library::Constraint::is_inequality(), Parma_Polyhedra_Library::Constraint::is_nonstrict_inequality(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::Constraint::is_strict_inequality(), Parma_Polyhedra_Library::Checked::le(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::maximize(), Parma_Polyhedra_Library::BD_Shape< T >::minimize(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::numer_denom(), Parma_Polyhedra_Library::Poly_Con_Relation::saturates(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Constraint::space_dimension(), Parma_Polyhedra_Library::Poly_Con_Relation::strictly_intersects(), TEMP_INTEGER, and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::relation_with().
01272 { 01273 const dimension_type c_space_dim = c.space_dimension(); 01274 const dimension_type space_dim = space_dimension(); 01275 01276 // Dimension-compatibility check. 01277 if (c_space_dim > space_dim) 01278 throw_dimension_incompatible("relation_with(c)", c); 01279 01280 shortest_path_closure_assign(); 01281 01282 if (marked_empty()) 01283 return Poly_Con_Relation::saturates() 01284 && Poly_Con_Relation::is_included() 01285 && Poly_Con_Relation::is_disjoint(); 01286 01287 if (space_dim == 0) { 01288 if ((c.is_equality() && c.inhomogeneous_term() != 0) 01289 || (c.is_inequality() && c.inhomogeneous_term() < 0)) 01290 return Poly_Con_Relation::is_disjoint(); 01291 else if (c.is_strict_inequality() && c.inhomogeneous_term() == 0) 01292 // The constraint 0 > 0 implicitly defines the hyperplane 0 = 0; 01293 // thus, the zero-dimensional point also saturates it. 01294 return Poly_Con_Relation::saturates() 01295 && Poly_Con_Relation::is_disjoint(); 01296 else if (c.is_equality() || c.inhomogeneous_term() == 0) 01297 return Poly_Con_Relation::saturates() 01298 && Poly_Con_Relation::is_included(); 01299 else 01300 // The zero-dimensional point saturates 01301 // neither the positivity constraint 1 >= 0, 01302 // nor the strict positivity constraint 1 > 0. 01303 return Poly_Con_Relation::is_included(); 01304 } 01305 01306 dimension_type num_vars = 0; 01307 dimension_type i = 0; 01308 dimension_type j = 0; 01309 TEMP_INTEGER(coeff); 01310 if (!extract_bounded_difference(c, c_space_dim, num_vars, i, j, coeff)) { 01311 // Constraints that are not bounded differences. 01312 // Use maximize() and minimize() to do much of the work. 01313 01314 // Find the linear expression for the constraint and use that to 01315 // find if the expression is bounded from above or below and if it 01316 // is, find the maximum and minimum values. 01317 Linear_Expression le; 01318 for (dimension_type k = c_space_dim; k-- > 0; ) { 01319 Variable vk(k); 01320 le += c.coefficient(vk) * vk; 01321 } 01322 DIRTY_TEMP(Coefficient, max_num); 01323 DIRTY_TEMP(Coefficient, max_den); 01324 bool max_included; 01325 DIRTY_TEMP(Coefficient, min_num); 01326 DIRTY_TEMP(Coefficient, min_den); 01327 bool min_included; 01328 bool bounded_above = maximize(le, max_num, max_den, max_included); 01329 bool bounded_below = minimize(le, min_num, min_den, min_included); 01330 if (!bounded_above) { 01331 if (!bounded_below) 01332 return Poly_Con_Relation::strictly_intersects(); 01333 min_num += c.inhomogeneous_term() * min_den; 01334 switch (sgn(min_num)) { 01335 case 1: 01336 if (c.is_equality()) 01337 return Poly_Con_Relation::is_disjoint(); 01338 return Poly_Con_Relation::is_included(); 01339 case 0: 01340 if (c.is_strict_inequality() || c.is_equality()) 01341 return Poly_Con_Relation::strictly_intersects(); 01342 return Poly_Con_Relation::is_included(); 01343 case -1: 01344 return Poly_Con_Relation::strictly_intersects(); 01345 } 01346 } 01347 if (!bounded_below) { 01348 max_num += c.inhomogeneous_term() * max_den; 01349 switch (sgn(max_num)) { 01350 case 1: 01351 return Poly_Con_Relation::strictly_intersects(); 01352 case 0: 01353 if (c.is_strict_inequality()) 01354 return Poly_Con_Relation::is_disjoint(); 01355 return Poly_Con_Relation::strictly_intersects(); 01356 case -1: 01357 return Poly_Con_Relation::is_disjoint(); 01358 } 01359 } 01360 else { 01361 max_num += c.inhomogeneous_term() * max_den; 01362 min_num += c.inhomogeneous_term() * min_den; 01363 switch (sgn(max_num)) { 01364 case 1: 01365 switch (sgn(min_num)) { 01366 case 1: 01367 if (c.is_equality()) 01368 return Poly_Con_Relation::is_disjoint(); 01369 return Poly_Con_Relation::is_included(); 01370 case 0: 01371 if (c.is_equality()) 01372 return Poly_Con_Relation::strictly_intersects(); 01373 if (c.is_strict_inequality()) 01374 return Poly_Con_Relation::strictly_intersects(); 01375 return Poly_Con_Relation::is_included(); 01376 case -1: 01377 return Poly_Con_Relation::strictly_intersects(); 01378 } 01379 case 0: 01380 if (min_num == 0) { 01381 if (c.is_strict_inequality()) 01382 return Poly_Con_Relation::is_disjoint() 01383 && Poly_Con_Relation::saturates(); 01384 return Poly_Con_Relation::is_included() 01385 && Poly_Con_Relation::saturates(); 01386 } 01387 if (c.is_strict_inequality()) 01388 return Poly_Con_Relation::is_disjoint(); 01389 return Poly_Con_Relation::strictly_intersects(); 01390 case -1: 01391 return Poly_Con_Relation::is_disjoint(); 01392 } 01393 } 01394 } 01395 01396 // Constraints that are bounded differences. 01397 if (num_vars == 0) { 01398 // Dealing with a trivial constraint. 01399 switch (sgn(c.inhomogeneous_term())) { 01400 case -1: 01401 return Poly_Con_Relation::is_disjoint(); 01402 case 0: 01403 if (c.is_strict_inequality()) 01404 return Poly_Con_Relation::saturates() 01405 && Poly_Con_Relation::is_disjoint(); 01406 else 01407 return Poly_Con_Relation::saturates() 01408 && Poly_Con_Relation::is_included(); 01409 case 1: 01410 if (c.is_equality()) 01411 return Poly_Con_Relation::is_disjoint(); 01412 else 01413 return Poly_Con_Relation::is_included(); 01414 } 01415 } 01416 01417 // Select the cell to be checked for the "<=" part of the constraint, 01418 // and set `coeff' to the absolute value of itself. 01419 const bool negative = (coeff < 0); 01420 const N& x = negative ? dbm[i][j] : dbm[j][i]; 01421 const N& y = negative ? dbm[j][i] : dbm[i][j]; 01422 if (negative) 01423 neg_assign(coeff); 01424 // Deduce the relation/s of the constraint `c' of the form 01425 // `coeff*v - coeff*u </<=/== c.inhomogeneous_term()' 01426 // with the respectively constraints in `*this' 01427 // `-y <= v - u <= x'. 01428 // Let `d == c.inhomogeneous_term()/coeff' 01429 // and `d1 == -c.inhomogeneous_term()/coeff'. 01430 // The following variables of mpq_class type are used to be precise 01431 // when the bds is defined by integer constraints. 01432 DIRTY_TEMP0(mpq_class, q_x); 01433 DIRTY_TEMP0(mpq_class, q_y); 01434 DIRTY_TEMP0(mpq_class, d); 01435 DIRTY_TEMP0(mpq_class, d1); 01436 DIRTY_TEMP0(mpq_class, c_den); 01437 DIRTY_TEMP0(mpq_class, q_den); 01438 assign_r(c_den, coeff, ROUND_NOT_NEEDED); 01439 assign_r(d, c.inhomogeneous_term(), ROUND_NOT_NEEDED); 01440 neg_assign_r(d1, d, ROUND_NOT_NEEDED); 01441 div_assign_r(d, d, c_den, ROUND_NOT_NEEDED); 01442 div_assign_r(d1, d1, c_den, ROUND_NOT_NEEDED); 01443 01444 if (is_plus_infinity(x)) { 01445 if (!is_plus_infinity(y)) { 01446 // `*this' is in the following form: 01447 // `-y <= v - u'. 01448 // In this case `*this' is disjoint from `c' if 01449 // `-y > d' (`-y >= d' if c is a strict equality), i.e. if 01450 // `y < d1' (`y <= d1' if c is a strict equality). 01451 TEMP_INTEGER(numer); 01452 TEMP_INTEGER(denom); 01453 numer_denom(y, numer, denom); 01454 assign_r(q_den, denom, ROUND_NOT_NEEDED); 01455 assign_r(q_y, numer, ROUND_NOT_NEEDED); 01456 div_assign_r(q_y, q_y, q_den, ROUND_NOT_NEEDED); 01457 if (q_y < d1) 01458 return Poly_Con_Relation::is_disjoint(); 01459 if (q_y == d1 && c.is_strict_inequality()) 01460 return Poly_Con_Relation::is_disjoint(); 01461 } 01462 01463 // In all other cases `*this' intersects `c'. 01464 return Poly_Con_Relation::strictly_intersects(); 01465 } 01466 01467 // Here `x' is not plus-infinity. 01468 TEMP_INTEGER(numer); 01469 TEMP_INTEGER(denom); 01470 numer_denom(x, numer, denom); 01471 assign_r(q_den, denom, ROUND_NOT_NEEDED); 01472 assign_r(q_x, numer, ROUND_NOT_NEEDED); 01473 div_assign_r(q_x, q_x, q_den, ROUND_NOT_NEEDED); 01474 01475 if (!is_plus_infinity(y)) { 01476 numer_denom(y, numer, denom); 01477 assign_r(q_den, denom, ROUND_NOT_NEEDED); 01478 assign_r(q_y, numer, ROUND_NOT_NEEDED); 01479 div_assign_r(q_y, q_y, q_den, ROUND_NOT_NEEDED); 01480 if (q_x == d && q_y == d1) { 01481 if (c.is_strict_inequality()) 01482 return Poly_Con_Relation::saturates() 01483 && Poly_Con_Relation::is_disjoint(); 01484 else 01485 return Poly_Con_Relation::saturates() 01486 && Poly_Con_Relation::is_included(); 01487 } 01488 // `*this' is disjoint from `c' when 01489 // `-y > d' (`-y >= d' if c is a strict equality), i.e. if 01490 // `y < d1' (`y <= d1' if c is a strict equality). 01491 if (q_y < d1) 01492 return Poly_Con_Relation::is_disjoint(); 01493 if (q_y == d1 && c.is_strict_inequality()) 01494 return Poly_Con_Relation::is_disjoint(); 01495 } 01496 01497 // Here `y' can be also plus-infinity. 01498 // If `c' is an equality, `*this' is disjoint from `c' if 01499 // `x < d'. 01500 if (d > q_x) { 01501 if (c.is_equality()) 01502 return Poly_Con_Relation::is_disjoint(); 01503 else 01504 return Poly_Con_Relation::is_included(); 01505 } 01506 01507 if (d == q_x && c.is_nonstrict_inequality()) 01508 return Poly_Con_Relation::is_included(); 01509 01510 // In all other cases `*this' intersects `c'. 01511 return Poly_Con_Relation::strictly_intersects(); 01512 }
| Poly_Con_Relation Parma_Polyhedra_Library::BD_Shape< T >::relation_with | ( | const Congruence & | cg | ) | const [inline] |
Returns the relations holding between *this and the congruence cg.
| std::invalid_argument | Thrown if *this and congruence cg are dimension-incompatible. |
Definition at line 1205 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Congruence::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::extract_bounded_difference(), Parma_Polyhedra_Library::Congruence::inhomogeneous_term(), Parma_Polyhedra_Library::Poly_Con_Relation::is_disjoint(), Parma_Polyhedra_Library::Congruence::is_equality(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), Parma_Polyhedra_Library::Congruence::is_inconsistent(), Parma_Polyhedra_Library::Checked::le(), Parma_Polyhedra_Library::lower(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::minimize(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::relation_with(), Parma_Polyhedra_Library::Poly_Con_Relation::saturates(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Congruence::space_dimension(), Parma_Polyhedra_Library::Poly_Con_Relation::strictly_intersects(), TEMP_INTEGER, and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
01205 { 01206 const dimension_type cg_space_dim = cg.space_dimension(); 01207 const dimension_type space_dim = space_dimension(); 01208 01209 // Dimension-compatibility check. 01210 if (cg_space_dim > space_dim) 01211 throw_dimension_incompatible("relation_with(cg)", cg); 01212 01213 // If the congruence is a bounded difference equality, 01214 // find the relation with the equivalent equality constraint. 01215 if (cg.is_equality()) { 01216 Constraint c(cg); 01217 dimension_type num_vars = 0; 01218 dimension_type i = 0; 01219 dimension_type j = 0; 01220 TEMP_INTEGER(coeff); 01221 if (extract_bounded_difference(c, cg_space_dim, num_vars, 01222 i, j, coeff)) 01223 return relation_with(c); 01224 } 01225 01226 shortest_path_closure_assign(); 01227 01228 if (marked_empty()) 01229 return Poly_Con_Relation::saturates() 01230 && Poly_Con_Relation::is_included() 01231 && Poly_Con_Relation::is_disjoint(); 01232 01233 if (space_dim == 0) { 01234 if (cg.is_inconsistent()) 01235 return Poly_Con_Relation::is_disjoint(); 01236 else if (cg.inhomogeneous_term() % cg.modulus() == 0) 01237 return Poly_Con_Relation::saturates() 01238 && Poly_Con_Relation::is_included(); 01239 } 01240 01241 DIRTY_TEMP(Coefficient, min_num); 01242 DIRTY_TEMP(Coefficient, min_den); 01243 bool min_included; 01244 TEMP_INTEGER(mod); 01245 mod = cg.modulus(); 01246 Linear_Expression le; 01247 for (dimension_type i = cg_space_dim; i-- > 0; ) 01248 le += cg.coefficient(Variable(i)) * Variable(i); 01249 bool bounded_below = minimize(le, min_num, min_den, min_included); 01250 01251 if (!bounded_below) 01252 return Poly_Con_Relation::strictly_intersects(); 01253 01254 TEMP_INTEGER(v); 01255 TEMP_INTEGER(lower_num); 01256 TEMP_INTEGER(lower_den); 01257 TEMP_INTEGER(lower); 01258 assign_r(lower_num, min_num, ROUND_NOT_NEEDED); 01259 assign_r(lower_den, min_den, ROUND_NOT_NEEDED); 01260 neg_assign(v, cg.inhomogeneous_term()); 01261 lower = lower_num / lower_den; 01262 v += ((lower / mod) * mod); 01263 if (v * lower_den < lower_num) 01264 v += mod; 01265 const Constraint& c(le == v); 01266 return relation_with(c); 01267 }
| Poly_Gen_Relation Parma_Polyhedra_Library::BD_Shape< T >::relation_with | ( | const Generator & | g | ) | const [inline] |
Returns the relations holding between *this and the generator g.
| std::invalid_argument | Thrown if *this and generator g are dimension-incompatible. |
Definition at line 1516 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::Generator::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::Generator::divisor(), Parma_Polyhedra_Library::is_additive_inverse(), Parma_Polyhedra_Library::Generator::is_line(), Parma_Polyhedra_Library::Generator::is_line_or_ray(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::Poly_Gen_Relation::nothing(), Parma_Polyhedra_Library::numer_denom(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Generator::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Poly_Gen_Relation::subsumes(), TEMP_INTEGER, and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
01516 { 01517 const dimension_type space_dim = space_dimension(); 01518 const dimension_type g_space_dim = g.space_dimension(); 01519 01520 // Dimension-compatibility check. 01521 if (space_dim < g_space_dim) 01522 throw_dimension_incompatible("relation_with(g)", g); 01523 01524 shortest_path_closure_assign(); 01525 // The empty BDS cannot subsume a generator. 01526 if (marked_empty()) 01527 return Poly_Gen_Relation::nothing(); 01528 01529 // A universe BDS in a zero-dimensional space subsumes 01530 // all the generators of a zero-dimensional space. 01531 if (space_dim == 0) 01532 return Poly_Gen_Relation::subsumes(); 01533 01534 const bool is_line = g.is_line(); 01535 const bool is_line_or_ray = g.is_line_or_ray(); 01536 01537 // The relation between the BDS and the given generator is obtained 01538 // checking if the generator satisfies all the constraints in the BDS. 01539 // To check if the generator satisfies all the constraints it's enough 01540 // studying the sign of the scalar product between the generator and 01541 // all the constraints in the BDS. 01542 01543 // Allocation of temporaries done once and for all. 01544 TEMP_INTEGER(num); 01545 TEMP_INTEGER(den); 01546 TEMP_INTEGER(product); 01547 // We find in `*this' all the constraints. 01548 for (dimension_type i = 0; i <= space_dim; ++i) { 01549 const Coefficient& g_coeff_y = (i > g_space_dim || i == 0) 01550 ? Coefficient(0) : g.coefficient(Variable(i-1)); 01551 const DB_Row<N>& dbm_i = dbm[i]; 01552 for (dimension_type j = i + 1; j <= space_dim; ++j) { 01553 const Coefficient& g_coeff_x = (j > g_space_dim) 01554 ? Coefficient(0) : g.coefficient(Variable(j-1)); 01555 const N& dbm_ij = dbm_i[j]; 01556 const N& dbm_ji = dbm[j][i]; 01557 if (is_additive_inverse(dbm_ji, dbm_ij)) { 01558 // We have one equality constraint: den*x - den*y = num. 01559 // Compute the scalar product. 01560 numer_denom(dbm_ij, num, den); 01561 product = 0; 01562 add_mul_assign(product, den, g_coeff_y); 01563 add_mul_assign(product, -den, g_coeff_x); 01564 if (!is_line_or_ray) 01565 add_mul_assign(product, num, g.divisor()); 01566 if (product != 0) 01567 return Poly_Gen_Relation::nothing(); 01568 } 01569 else { 01570 // We have 0, 1 or 2 binary inequality constraint/s. 01571 if (!is_plus_infinity(dbm_ij)) { 01572 // We have the binary inequality constraint: den*x - den*y <= num. 01573 // Compute the scalar product. 01574 numer_denom(dbm_ij, num, den); 01575 product = 0; 01576 add_mul_assign(product, den, g_coeff_y); 01577 add_mul_assign(product, -den, g_coeff_x); 01578 if (!is_line_or_ray) 01579 add_mul_assign(product, num, g.divisor()); 01580 if (is_line) { 01581 if (product != 0) 01582 // Lines must saturate all constraints. 01583 return Poly_Gen_Relation::nothing(); 01584 } 01585 else 01586 // `g' is either a ray, a point or a closure point. 01587 if (product < 0) 01588 return Poly_Gen_Relation::nothing(); 01589 } 01590 01591 if (!is_plus_infinity(dbm_ji)) { 01592 // We have the binary inequality constraint: den*y - den*x <= b. 01593 // Compute the scalar product. 01594 numer_denom(dbm_ji, num, den); 01595 product = 0; 01596 add_mul_assign(product, den, g_coeff_x); 01597 add_mul_assign(product, -den, g_coeff_y); 01598 if (!is_line_or_ray) 01599 add_mul_assign(product, num, g.divisor()); 01600 if (is_line) { 01601 if (product != 0) 01602 // Lines must saturate all constraints. 01603 return Poly_Gen_Relation::nothing(); 01604 } 01605 else 01606 // `g' is either a ray, a point or a closure point. 01607 if (product < 0) 01608 return Poly_Gen_Relation::nothing(); 01609 } 01610 } 01611 } 01612 } 01613 01614 // The generator satisfies all the constraints. 01615 return Poly_Gen_Relation::subsumes(); 01616 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::is_empty | ( | ) | const [inline] |
Returns true if and only if *this is an empty BDS.
Definition at line 395 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruences_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::constrains(), Parma_Polyhedra_Library::BD_Shape< T >::contains_integer_point(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::Octagonal_Shape< T >::Octagonal_Shape(), and Parma_Polyhedra_Library::Pointset_Powerset< PS >::Pointset_Powerset().
00395 { 00396 shortest_path_closure_assign(); 00397 return marked_empty(); 00398 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::is_universe | ( | ) | const [inline] |
Returns true if and only if *this is a universe BDS.
Definition at line 678 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00678 { 00679 if (marked_empty()) 00680 return false; 00681 00682 const dimension_type space_dim = space_dimension(); 00683 // If the BDS is non-empty and zero-dimensional, 00684 // then it is necessarily the universe BDS. 00685 if (space_dim == 0) 00686 return true; 00687 00688 // A bounded difference shape defining the universe BDS can only 00689 // contain trivial constraints. 00690 for (dimension_type i = space_dim + 1; i-- > 0; ) { 00691 const DB_Row<N>& dbm_i = dbm[i]; 00692 for (dimension_type j = space_dim + 1; j-- > 0; ) 00693 if (!is_plus_infinity(dbm_i[j])) 00694 return false; 00695 } 00696 return true; 00697 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::is_discrete | ( | ) | const [inline] |
Returns true if and only if *this is discrete.
Definition at line 452 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::affine_dimension().
00452 { 00453 return affine_dimension() == 0; 00454 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::is_topologically_closed | ( | ) | const [inline] |
Returns true if and only if *this is a topologically closed subset of the vector space.
Definition at line 446 of file BD_Shape.inlines.hh.
| bool Parma_Polyhedra_Library::BD_Shape< T >::is_bounded | ( | ) | const [inline] |
Returns true if and only if *this is a bounded BDS.
Definition at line 701 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00701 { 00702 shortest_path_closure_assign(); 00703 const dimension_type space_dim = space_dimension(); 00704 // A zero-dimensional or empty BDS is bounded. 00705 if (marked_empty() || space_dim == 0) 00706 return true; 00707 00708 // A bounded difference shape defining the bounded BDS never can 00709 // contain trivial constraints. 00710 for (dimension_type i = space_dim + 1; i-- > 0; ) { 00711 const DB_Row<N>& dbm_i = dbm[i]; 00712 for (dimension_type j = space_dim + 1; j-- > 0; ) 00713 if (i != j) 00714 if (is_plus_infinity(dbm_i[j])) 00715 return false; 00716 } 00717 00718 return true; 00719 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::contains_integer_point | ( | ) | const [inline] |
Returns true if and only if *this contains at least one integer point.
Definition at line 723 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::is_empty(), Parma_Polyhedra_Library::is_integer(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00723 { 00724 // Force shortest-path closure. 00725 if (is_empty()) 00726 return false; 00727 00728 const dimension_type space_dim = space_dimension(); 00729 if (space_dim == 0) 00730 return true; 00731 00732 // A non-empty BD_Shape defined by integer constraints 00733 // necessarily contains an integer point. 00734 if (std::numeric_limits<T>::is_integer) 00735 return true; 00736 00737 // Build an integer BD_Shape z with bounds at least as tight as 00738 // those in *this and then recheck for emptiness. 00739 BD_Shape<mpz_class> bds_z(space_dim); 00740 typedef BD_Shape<mpz_class>::N Z; 00741 bds_z.reset_shortest_path_closed(); 00742 DIRTY_TEMP(N, tmp); 00743 bool all_integers = true; 00744 for (dimension_type i = space_dim + 1; i-- > 0; ) { 00745 DB_Row<Z>& z_i = bds_z.dbm[i]; 00746 const DB_Row<N>& dbm_i = dbm[i]; 00747 for (dimension_type j = space_dim + 1; j-- > 0; ) { 00748 const N& dbm_i_j = dbm_i[j]; 00749 if (is_plus_infinity(dbm_i_j)) 00750 continue; 00751 if (is_integer(dbm_i_j)) 00752 assign_r(z_i[j], dbm_i_j, ROUND_NOT_NEEDED); 00753 else { 00754 all_integers = false; 00755 Z& z_i_j = z_i[j]; 00756 // Copy dbm_i_j into z_i_j, but rounding downwards. 00757 neg_assign_r(tmp, dbm_i_j, ROUND_NOT_NEEDED); 00758 assign_r(z_i_j, tmp, ROUND_UP); 00759 neg_assign_r(z_i_j, z_i_j, ROUND_NOT_NEEDED); 00760 } 00761 } 00762 } 00763 return all_integers || !bds_z.is_empty(); 00764 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::constrains | ( | Variable | var | ) | const [inline] |
Returns true if and only if var is constrained in *this.
| std::invalid_argument | Thrown if var is not a space dimension of *this. |
Definition at line 768 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::is_empty(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
00768 { 00769 // `var' should be one of the dimensions of the polyhedron. 00770 const dimension_type var_space_dim = var.space_dimension(); 00771 if (space_dimension() < var_space_dim) 00772 throw_dimension_incompatible("constrains(v)", "v", var); 00773 00774 // A polyhedron known to be empty constrains all variables. 00775 // (Note: do not force emptiness check _yet_) 00776 if (marked_empty()) 00777 return true; 00778 00779 // Check whether `var' is syntactically constrained. 00780 const DB_Row<N>& dbm_v = dbm[var_space_dim]; 00781 for (dimension_type i = dbm.num_rows(); i-- > 0; ) { 00782 if (!is_plus_infinity(dbm_v[i]) 00783 || !is_plus_infinity(dbm[i][var_space_dim])) 00784 return true; 00785 } 00786 00787 // `var' is not syntactically constrained: 00788 // now force an emptiness check. 00789 return is_empty(); 00790 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::OK | ( | ) | const [inline] |
Returns true if and only if *this satisfies all its invariants.
Definition at line 5062 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::is_minus_infinity(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::Status::OK(), Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::status.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::H79_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_H79_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::refine(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::time_elapse_assign(), Parma_Polyhedra_Library::BD_Shape< T >::unconstrain(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
05062 { 05063 // Check whether the difference-bound matrix is well-formed. 05064 if (!dbm.OK()) 05065 return false; 05066 05067 // Check whether the status information is legal. 05068 if (!status.OK()) 05069 return false; 05070 05071 // An empty BDS is OK. 05072 if (marked_empty()) 05073 return true; 05074 05075 // MINUS_INFINITY cannot occur at all. 05076 for (dimension_type i = dbm.num_rows(); i-- > 0; ) 05077 for (dimension_type j = dbm.num_rows(); j-- > 0; ) 05078 if (is_minus_infinity(dbm[i][j])) { 05079 #ifndef NDEBUG 05080 using namespace Parma_Polyhedra_Library::IO_Operators; 05081 std::cerr << "BD_Shape::dbm[" << i << "][" << j << "] = " 05082 << dbm[i][j] << "!" 05083 << std::endl; 05084 #endif 05085 return false; 05086 } 05087 05088 // On the main diagonal only PLUS_INFINITY can occur. 05089 for (dimension_type i = dbm.num_rows(); i-- > 0; ) 05090 if (!is_plus_infinity(dbm[i][i])) { 05091 #ifndef NDEBUG 05092 using namespace Parma_Polyhedra_Library::IO_Operators; 05093 std::cerr << "BD_Shape::dbm[" << i << "][" << i << "] = " 05094 << dbm[i][i] << "! (+inf was expected.)" 05095 << std::endl; 05096 #endif 05097 return false; 05098 } 05099 05100 // Check whether the shortest-path closure information is legal. 05101 if (marked_shortest_path_closed()) { 05102 BD_Shape x = *this; 05103 x.reset_shortest_path_closed(); 05104 x.shortest_path_closure_assign(); 05105 if (x.dbm != dbm) { 05106 #ifndef NDEBUG 05107 std::cerr << "BD_Shape is marked as closed but it is not!" 05108 << std::endl; 05109 #endif 05110 return false; 05111 } 05112 } 05113 05114 // The following tests might result in false alarms when using floating 05115 // point coefficients: they are only meaningful if the coefficient type 05116 // base is exact (since otherwise shortest-path closure is approximated). 05117 if (std::numeric_limits<coefficient_type_base>::is_exact) { 05118 05119 // Check whether the shortest-path reduction information is legal. 05120 if (marked_shortest_path_reduced()) { 05121 // A non-redundant constraint cannot be equal to PLUS_INFINITY. 05122 for (dimension_type i = dbm.num_rows(); i-- > 0; ) 05123 for (dimension_type j = dbm.num_rows(); j-- > 0; ) 05124 if (!redundancy_dbm[i][j] && is_plus_infinity(dbm[i][j])) { 05125 #ifndef NDEBUG 05126 using namespace Parma_Polyhedra_Library::IO_Operators; 05127 std::cerr << "BD_Shape::dbm[" << i << "][" << j << "] = " 05128 << dbm[i][j] << " is marked as non-redundant!" 05129 << std::endl; 05130 #endif 05131 return false; 05132 } 05133 05134 BD_Shape x = *this; 05135 x.reset_shortest_path_reduced(); 05136 x.shortest_path_reduction_assign(); 05137 if (x.redundancy_dbm != redundancy_dbm) { 05138 #ifndef NDEBUG 05139 std::cerr << "BD_Shape is marked as reduced but it is not!" 05140 << std::endl; 05141 #endif 05142 return false; 05143 } 05144 } 05145 } 05146 05147 // All checks passed. 05148 return true; 05149 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_constraint | ( | const Constraint & | c | ) | [inline] |
Adds a copy of constraint c to the system of bounded differences defining *this.
| c | The constraint to be added. If it is not a bounded difference, it will be simply ignored. |
| std::invalid_argument | Thrown if *this and constraint c are dimension-incompatible, or if c is a strict inequality. |
Definition at line 373 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::BD_Shape< T >::extract_bounded_difference(), Parma_Polyhedra_Library::Constraint::inhomogeneous_term(), Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Constraint::is_inconsistent(), Parma_Polyhedra_Library::Constraint::is_strict_inequality(), Parma_Polyhedra_Library::Constraint::is_tautological(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Constraint::space_dimension(), TEMP_INTEGER, Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraint_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), and Parma_Polyhedra_Library::BD_Shape< T >::difference_assign().
00373 { 00374 const dimension_type c_space_dim = c.space_dimension(); 00375 // Dimension-compatibility check. 00376 if (c_space_dim > space_dimension()) 00377 throw_dimension_incompatible("add_constraint(c)", c); 00378 00379 // Get rid of strict inequalities. 00380 if (c.is_strict_inequality()) { 00381 if (c.is_inconsistent()) { 00382 set_empty(); 00383 return; 00384 } 00385 if (c.is_tautological()) 00386 return; 00387 // Nontrivial strict inequalities are not allowed. 00388 throw_generic("add_constraint(c)", "strict inequalities are not allowed"); 00389 } 00390 00391 dimension_type num_vars = 0; 00392 dimension_type i = 0; 00393 dimension_type j = 0; 00394 TEMP_INTEGER(coeff); 00395 // Constraints that are not bounded differences are not allowed. 00396 if (!extract_bounded_difference(c, c_space_dim, num_vars, i, j, coeff)) 00397 throw_generic("add_constraint(c)", 00398 "c is not a bounded difference constraint"); 00399 00400 const Coefficient& inhomo = c.inhomogeneous_term(); 00401 if (num_vars == 0) { 00402 // Dealing with a trivial constraint (not a strict inequality). 00403 if (inhomo < 0 00404 || (inhomo != 0 && c.is_equality())) 00405 set_empty(); 00406 return; 00407 } 00408 00409 // Select the cell to be modified for the "<=" part of the constraint, 00410 // and set `coeff' to the absolute value of itself. 00411 const bool negative = (coeff < 0); 00412 N& x = negative ? dbm[i][j] : dbm[j][i]; 00413 N& y = negative ? dbm[j][i] : dbm[i][j]; 00414 if (negative) 00415 neg_assign(coeff); 00416 00417 bool changed = false; 00418 // Compute the bound for `x', rounding towards plus infinity. 00419 DIRTY_TEMP(N, d); 00420 div_round_up(d, inhomo, coeff); 00421 if (x > d) { 00422 x = d; 00423 changed = true; 00424 } 00425 00426 if (c.is_equality()) { 00427 // Also compute the bound for `y', rounding towards plus infinity. 00428 TEMP_INTEGER(minus_c_term); 00429 neg_assign(minus_c_term, inhomo); 00430 div_round_up(d, minus_c_term, coeff); 00431 if (y > d) { 00432 y = d; 00433 changed = true; 00434 } 00435 } 00436 00437 // In general, adding a constraint does not preserve the shortest-path 00438 // closure or reduction of the bounded difference shape. 00439 if (changed && marked_shortest_path_closed()) 00440 reset_shortest_path_closed(); 00441 assert(OK()); 00442 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::add_constraint_and_minimize | ( | const Constraint & | c | ) | [inline] |
Adds a copy of constraint c to the system of bounded differences defining *this.
false if and only if the result is empty.| c | The constraint to be added. If it is not a bounded difference, it will be simply ignored. |
| std::invalid_argument | Thrown if *this and constraint c are dimension-incompatible, or if c is a strict inequality. |
Definition at line 157 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign().
00157 { 00158 add_constraint(c); 00159 shortest_path_closure_assign(); 00160 return !marked_empty(); 00161 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_congruence | ( | const Congruence & | cg | ) | [inline] |
Adds a copy of congruence cg to the system of congruences of this (without minimizing the result).
| cg | The congruence to be added. If it is not a bounded difference, it will be simply ignored. |
| std::invalid_argument | Thrown if *this and congruence cg are dimension-incompatible. |
Definition at line 446 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::Congruence::is_equality(), Parma_Polyhedra_Library::Congruence::is_inconsistent(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::Congruence::is_tautological(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Congruence::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence_and_minimize(), and Parma_Polyhedra_Library::BD_Shape< T >::add_congruences().
00446 { 00447 const dimension_type cg_space_dim = cg.space_dimension(); 00448 // Dimension-compatibility check: 00449 // the dimension of `cg' can not be greater than space_dim. 00450 if (space_dimension() < cg_space_dim) 00451 throw_dimension_incompatible("add_congruence(cg)", cg); 00452 00453 // Handle the case of proper congruences first. 00454 if (cg.is_proper_congruence()) { 00455 if (cg.is_tautological()) 00456 return; 00457 if (cg.is_inconsistent()) { 00458 set_empty(); 00459 return; 00460 } 00461 // Non-trivial and proper congruences are not allowed. 00462 throw_generic("add_congruence(cg)", 00463 "cg is a non-trivial, proper congruence"); 00464 } 00465 00466 assert(cg.is_equality()); 00467 Constraint c(cg); 00468 add_constraint(c); 00469 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::add_congruence_and_minimize | ( | const Congruence & | cg | ) | [inline] |
Adds a copy of congruence cg to the system of congruences of *this, minimizing the result.
| cg | The congruence to be added. If it is not a bounded difference, it will be simply ignored. |
false if and only if the result is empty.| std::invalid_argument | Thrown if *this and congruence c are topology-incompatible or dimension-incompatible. |
Definition at line 165 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign().
00165 { 00166 add_congruence(cg); 00167 shortest_path_closure_assign(); 00168 return !marked_empty(); 00169 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_constraints | ( | const Constraint_System & | cs | ) | [inline] |
Adds the constraints in cs to the system of bounded differences defining *this.
| cs | The constraints that will be added. Constraints that are not bounded differences will be simply ignored. |
| std::invalid_argument | Thrown if *this and cs are dimension-incompatible, or if cs contains a strict inequality. |
Definition at line 173 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::Constraint_System::begin(), and Parma_Polyhedra_Library::Constraint_System::end().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_constraints_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_constraints(), and Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape().
00173 { 00174 for (Constraint_System::const_iterator i = cs.begin(), 00175 cs_end = cs.end(); i != cs_end; ++i) 00176 add_constraint(*i); 00177 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_constraints | ( | Constraint_System & | cs | ) | [inline] |
Adds the constraints in cs to the system of constraints of *this (without minimizing the result).
| cs | The constraint system to be added to *this. The constraints in cs may be recycled. |
| std::invalid_argument | Thrown if *this and cs are topology-incompatible or dimension-incompatible. |
cs upon successful or exceptional return is that it can be safely destroyed. Definition at line 189 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraints().
00189 { 00190 add_constraints(cs); 00191 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::add_constraints_and_minimize | ( | const Constraint_System & | cs | ) | [inline] |
Adds the constraints in cs to the system of bounded differences defining *this.
false if and only if the result is empty.| cs | The constraints that will be added. Constraints that are not bounded differences will be simply ignored. |
| std::invalid_argument | Thrown if *this and cs are dimension-incompatible, or if cs contains a strict inequality. |
Definition at line 181 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_constraints_and_minimize().
00181 { 00182 add_constraints(cs); 00183 shortest_path_closure_assign(); 00184 return !marked_empty(); 00185 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_constraints_and_minimize | ( | Constraint_System & | cs | ) | [inline] |
Adds the constraints in cs to the system of constraints of *this, minimizing the result.
false if and only if the result is empty.| cs | The constraint system to be added to *this. The constraints in cs may be recycled. |
| std::invalid_argument | Thrown if *this and cs are topology-incompatible or dimension-incompatible. |
cs upon successful or exceptional return is that it can be safely destroyed.Definition at line 195 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraints_and_minimize().
00195 { 00196 return add_constraints_and_minimize(cs); 00197 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_congruences | ( | const Congruence_System & | cgs | ) | [inline] |
Adds to *this constraints equivalent to the congruences in cgs (without minimizing the result).
| cgs | Contains the congruences that will be added to the system of constraints of *this. |
| std::invalid_argument | Thrown if *this and cgs are topology-incompatible or dimension-incompatible. |
Definition at line 201 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_congruence(), Parma_Polyhedra_Library::Congruence_System::begin(), and Parma_Polyhedra_Library::Congruence_System::end().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruences_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_congruences(), and Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape().
00201 { 00202 for (Congruence_System::const_iterator i = cgs.begin(), 00203 cgs_end = cgs.end(); i != cgs_end; ++i) 00204 add_congruence(*i); 00205 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::add_congruences_and_minimize | ( | const Congruence_System & | cs | ) | [inline] |
Adds a copy of the congruences in cs to the system of congruences of *this, minimizing the result.
false if and only if the result is empty.| cs | Contains the congruences that will be added to the system of congruences of *this. |
| std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
Definition at line 209 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_congruences(), and Parma_Polyhedra_Library::BD_Shape< T >::is_empty().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_congruences_and_minimize().
00209 { 00210 add_congruences(cgs); 00211 return !is_empty(); 00212 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_congruences | ( | Congruence_System & | cgs | ) | [inline] |
Adds the congruences in cs to the system of congruences of *this (without minimizing the result).
| cgs | The congruence system to be added to *this. The congruences in cgs may be recycled. |
| std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
cs upon successful or exceptional return is that it can be safely destroyed. Definition at line 216 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_congruences().
00216 { 00217 add_congruences(cgs); 00218 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::add_recycled_congruences_and_minimize | ( | Congruence_System & | cgs | ) | [inline] |
Adds the congruences in cs to the system of congruences of *this, minimizing the result.
false if and only if the result is empty.| cgs | The congruence system to be added to *this. The congruences in cgs may be recycled. |
| std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
cs upon successful or exceptional return is that it can be safely destroyed.Definition at line 222 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_congruences_and_minimize().
00222 { 00223 return add_congruences_and_minimize(cgs); 00224 }
| void Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraint | ( | const Constraint & | c | ) | [inline] |
Uses a copy of constraint c to refine the system of bounded differences defining *this.
| c | The constraint. If it is not a bounded difference, it will be ignored. |
| std::invalid_argument | Thrown if *this and constraint c are dimension-incompatible. |
Definition at line 228 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Constraint::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
00228 { 00229 const dimension_type c_space_dim = c.space_dimension(); 00230 // Dimension-compatibility check. 00231 if (c_space_dim > space_dimension()) 00232 throw_dimension_incompatible("refine_with_constraint(c)", c); 00233 00234 if (!marked_empty()) 00235 refine_no_check(c); 00236 }
| void Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruence | ( | const Congruence & | cg | ) | [inline] |
Uses a copy of congruence cg to refine the system of bounded differences of *this.
| cg | The congruence. If it is not a bounded difference equality, it will be ignored. |
| std::invalid_argument | Thrown if *this and congruence cg are dimension-incompatible. |
Definition at line 253 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Congruence::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
00253 { 00254 const dimension_type cg_space_dim = cg.space_dimension(); 00255 // Dimension-compatibility check. 00256 if (cg_space_dim > space_dimension()) 00257 throw_dimension_incompatible("refine_with_congruence(cg)", cg); 00258 00259 if (!marked_empty()) 00260 refine_no_check(cg); 00261 }
| void Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints | ( | const Constraint_System & | cs | ) | [inline] |
Uses a copy of the constraints in cs to refine the system of bounded differences defining *this.
| cs | The constraint system to be used. Constraints that are not bounded differences are ignored. |
| std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
Definition at line 240 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape().
00240 { 00241 // Dimension-compatibility check. 00242 if (cs.space_dimension() > space_dimension()) 00243 throw_generic("refine_with_constraints(cs)", 00244 "cs and *this are space-dimension incompatible"); 00245 00246 for (Constraint_System::const_iterator i = cs.begin(), 00247 cs_end = cs.end(); !marked_empty() && i != cs_end; ++i) 00248 refine_no_check(*i); 00249 }
| void Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruences | ( | const Congruence_System & | cgs | ) | [inline] |
Uses a copy of the congruences in cgs to refine the system of bounded differences defining *this.
| cgs | The congruence system to be used. Congruences that are not bounded difference equalities are ignored. |
| std::invalid_argument | Thrown if *this and cgs are dimension-incompatible. |
Definition at line 265 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::Congruence_System::begin(), Parma_Polyhedra_Library::Congruence_System::end(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape().
00265 { 00266 // Dimension-compatibility check. 00267 if (cgs.space_dimension() > space_dimension()) 00268 throw_generic("refine_with_congruences(cgs)", 00269 "cgs and *this are space-dimension incompatible"); 00270 00271 for (Congruence_System::const_iterator i = cgs.begin(), 00272 cgs_end = cgs.end(); !marked_empty() && i != cgs_end; ++i) 00273 refine_no_check(*i); 00274 }
| void Parma_Polyhedra_Library::BD_Shape< T >::unconstrain | ( | Variable | var | ) | [inline] |
Computes the cylindrification of *this with respect to space dimension var, assigning the result to *this.
| var | The space dimension that will be unconstrained. |
| std::invalid_argument | Thrown if var is not a space dimension of *this. |
Definition at line 2672 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
02672 { 02673 // Dimension-compatibility check. 02674 const dimension_type dim = var.id(); 02675 if (space_dimension() < dim) 02676 throw_dimension_incompatible("unconstrain(var)", dim); 02677 02678 // Shortest-path closure is necessary to detect emptiness 02679 // and all (possibly implicit) constraints. 02680 shortest_path_closure_assign(); 02681 02682 // If the shape is empty, this is a no-op. 02683 if (marked_empty()) 02684 return; 02685 02686 forget_all_dbm_constraints(dim+1); 02687 // Shortest-path closure is preserved, but not reduction. 02688 reset_shortest_path_reduced(); 02689 assert(OK()); 02690 }
| void Parma_Polyhedra_Library::BD_Shape< T >::unconstrain | ( | const Variables_Set & | to_be_unconstrained | ) | [inline] |
Computes the cylindrification of *this with respect to the set of space dimensions to_be_unconstrained, assigning the result to *this.
| to_be_unconstrained | The set of space dimension that will be unconstrained. |
| std::invalid_argument | Thrown if *this is dimension-incompatible with one of the Variable objects contained in to_be_removed. |
Definition at line 2694 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
02694 { 02695 // The cylindrification wrt no dimensions is a no-op. 02696 // This case captures the only legal cylindrification in a 0-dim space. 02697 if (to_be_unconstrained.empty()) 02698 return; 02699 02700 // Dimension-compatibility check. 02701 const dimension_type min_space_dim = to_be_unconstrained.space_dimension(); 02702 if (space_dimension() < min_space_dim) 02703 throw_dimension_incompatible("unconstrain(vs)", min_space_dim); 02704 02705 // Shortest-path closure is necessary to detect emptiness 02706 // and all (possibly implicit) constraints. 02707 shortest_path_closure_assign(); 02708 02709 // If the shape is empty, this is a no-op. 02710 if (marked_empty()) 02711 return; 02712 02713 for (Variables_Set::const_iterator tbu = to_be_unconstrained.begin(), 02714 tbu_end = to_be_unconstrained.end(); tbu != tbu_end; ++tbu) 02715 forget_all_dbm_constraints(*tbu + 1); 02716 // Shortest-path closure is preserved, but not reduction. 02717 reset_shortest_path_reduced(); 02718 assert(OK()); 02719 }
| void Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the intersection of *this and y.
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 2121 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign().
02121 { 02122 const dimension_type space_dim = space_dimension(); 02123 02124 // Dimension-compatibility check. 02125 if (space_dim != y.space_dimension()) 02126 throw_dimension_incompatible("intersection_assign(y)", y); 02127 02128 // If one of the two bounded difference shapes is empty, 02129 // the intersection is empty. 02130 if (marked_empty()) 02131 return; 02132 if (y.marked_empty()) { 02133 set_empty(); 02134 return; 02135 } 02136 02137 // If both bounded difference shapes are zero-dimensional, 02138 // then at this point they are necessarily non-empty, 02139 // so that their intersection is non-empty too. 02140 if (space_dim == 0) 02141 return; 02142 02143 // To intersect two bounded difference shapes we compare 02144 // the constraints and we choose the less values. 02145 bool changed = false; 02146 for (dimension_type i = space_dim + 1; i-- > 0; ) { 02147 DB_Row<N>& dbm_i = dbm[i]; 02148 const DB_Row<N>& y_dbm_i = y.dbm[i]; 02149 for (dimension_type j = space_dim + 1; j-- > 0; ) { 02150 N& dbm_ij = dbm_i[j]; 02151 const N& y_dbm_ij = y_dbm_i[j]; 02152 if (dbm_ij > y_dbm_ij) { 02153 dbm_ij = y_dbm_ij; 02154 changed = true; 02155 } 02156 } 02157 } 02158 02159 if (changed && marked_shortest_path_closed()) 02160 reset_shortest_path_closed(); 02161 assert(OK()); 02162 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign_and_minimize | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the intersection of *this and y.
false if and only if the result is empty.| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 800 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign().
00800 { 00801 intersection_assign(y); 00802 shortest_path_closure_assign(); 00803 return !marked_empty(); 00804 }
| void Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the smallest BDS containing the union of *this and y.
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1776 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign_and_minimize().
01776 { 01777 const dimension_type space_dim = space_dimension(); 01778 01779 // Dimension-compatibility check. 01780 if (space_dim != y.space_dimension()) 01781 throw_dimension_incompatible("upper_bound_assign(y)", y); 01782 01783 // The poly-hull of a polyhedron `bd' with an empty polyhedron is `bd'. 01784 y.shortest_path_closure_assign(); 01785 if (y.marked_empty()) 01786 return; 01787 shortest_path_closure_assign(); 01788 if (marked_empty()) { 01789 *this = y; 01790 return; 01791 } 01792 01793 // The bds-hull consists in constructing `*this' with the maximum 01794 // elements selected from `*this' and `y'. 01795 assert(space_dim == 0 || marked_shortest_path_closed()); 01796 for (dimension_type i = space_dim + 1; i-- > 0; ) { 01797 DB_Row<N>& dbm_i = dbm[i]; 01798 const DB_Row<N>& y_dbm_i = y.dbm[i]; 01799 for (dimension_type j = space_dim + 1; j-- > 0; ) { 01800 N& dbm_ij = dbm_i[j]; 01801 const N& y_dbm_ij = y_dbm_i[j]; 01802 if (dbm_ij < y_dbm_ij) 01803 dbm_ij = y_dbm_ij; 01804 } 01805 } 01806 // Shortest-path closure is maintained (if it was holding). 01807 // TODO: see whether reduction can be (efficiently!) maintained too. 01808 if (marked_shortest_path_reduced()) 01809 reset_shortest_path_reduced(); 01810 assert(OK()); 01811 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign_and_minimize | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the smallest BDS containing the convex union of *this and y.
false if and only if the result is empty.| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 750 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
00750 { 00751 upper_bound_assign(y); 00752 assert(marked_empty() 00753 || space_dimension() == 0 || marked_shortest_path_closed()); 00754 return !marked_empty(); 00755 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign_if_exact | ( | const BD_Shape< T > & | y | ) | [inline] |
If the upper bound of *this and y is exact, it is assigned to *this and true is returned, otherwise false is returned.
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 759 of file BD_Shape.inlines.hh.
00759 { 00760 // TODO: this must be properly implemented. 00761 used(y); 00762 return false; 00763 }
| void Parma_Polyhedra_Library::BD_Shape< T >::difference_assign | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the smallest BD shape containing the set difference of *this and y.
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1815 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::EMPTY, Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Poly_Con_Relation::implies(), Parma_Polyhedra_Library::BD_Shape< T >::is_empty(), Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::relation_with(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
01815 { 01816 const dimension_type space_dim = space_dimension(); 01817 01818 // Dimension-compatibility check. 01819 if (space_dim != y.space_dimension()) 01820 throw_dimension_incompatible("difference_assign(y)", y); 01821 01822 BD_Shape new_bd_shape(space_dim, EMPTY); 01823 01824 BD_Shape& x = *this; 01825 01826 x.shortest_path_closure_assign(); 01827 // The difference of an empty bounded difference shape 01828 // and of a bounded difference shape `p' is empty. 01829 if (x.marked_empty()) 01830 return; 01831 y.shortest_path_closure_assign(); 01832 // The difference of a bounded difference shape `p' 01833 // and an empty bounded difference shape is `p'. 01834 if (y.marked_empty()) 01835 return; 01836 01837 // If both bounded difference shapes are zero-dimensional, 01838 // then at this point they are necessarily universe system of 01839 // bounded differences, so that their difference is empty. 01840 if (space_dim == 0) { 01841 x.set_empty(); 01842 return; 01843 } 01844 01845 // TODO: This is just an executable specification. 01846 // Have to find a more efficient method. 01847 if (y.contains(x)) { 01848 x.set_empty(); 01849 return; 01850 } 01851 01852 // We take a constraint of the system y at the time and we 01853 // consider its complementary. Then we intersect the union 01854 // of these complementaries with the system x. 01855 const Constraint_System& y_cs = y.constraints(); 01856 for (Constraint_System::const_iterator i = y_cs.begin(), 01857 y_cs_end = y_cs.end(); i != y_cs_end; ++i) { 01858 const Constraint& c = *i; 01859 // If the bounded difference shape `x' is included 01860 // in the bounded difference shape defined by `c', 01861 // then `c' _must_ be skipped, as adding its complement to `x' 01862 // would result in the empty bounded difference shape, 01863 // and as we would obtain a result that is less precise 01864 // than the bds-difference. 01865 if (x.relation_with(c).implies(Poly_Con_Relation::is_included())) 01866 continue; 01867 BD_Shape z = x; 01868 const Linear_Expression e = Linear_Expression(c); 01869 z.add_constraint(e <= 0); 01870 if (!z.is_empty()) 01871 new_bd_shape.upper_bound_assign(z); 01872 if (c.is_equality()) { 01873 z = x; 01874 z.add_constraint(e >= 0); 01875 if (!z.is_empty()) 01876 new_bd_shape.upper_bound_assign(z); 01877 } 01878 } 01879 *this = new_bd_shape; 01880 assert(OK()); 01881 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::simplify_using_context_assign | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this a meet-preserving simplification of *this with respect to y. If false is returned, then the intersection is empty.
| std::invalid_argument | Thrown if *this and y are topology-incompatible or dimension-incompatible. |
Definition at line 1885 of file BD_Shape.templates.hh.
| void Parma_Polyhedra_Library::BD_Shape< T >::affine_image | ( | Variable | var, | |
| const Linear_Expression & | expr, | |||
| Coefficient_traits::const_reference | denominator = Coefficient_one() | |||
| ) | [inline] |
Assigns to *this the affine image of *this under the function mapping variable var into the affine expression specified by expr and denominator.
| var | The variable to which the affine expression is assigned. | |
| expr | The numerator of the affine expression. | |
| denominator | The denominator of the affine expression. |
| std::invalid_argument | Thrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a dimension of *this. |
Definition at line 3108 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::deduce_u_minus_v_bounds(), Parma_Polyhedra_Library::BD_Shape< T >::deduce_v_minus_u_bounds(), Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::forget_binary_dbm_constraints(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::swap(), TEMP_INTEGER, Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), and Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage().
03110 { 03111 // The denominator cannot be zero. 03112 if (denominator == 0) 03113 throw_generic("affine_image(v, e, d)", "d == 0"); 03114 03115 // Dimension-compatibility checks. 03116 // The dimension of `expr' should not be greater than the dimension 03117 // of `*this'. 03118 const dimension_type space_dim = space_dimension(); 03119 const dimension_type expr_space_dim = expr.space_dimension(); 03120 if (space_dim < expr_space_dim) 03121 throw_dimension_incompatible("affine_image(v, e, d)", "e", expr); 03122 03123 // `var' should be one of the dimensions of the shape. 03124 const dimension_type v = var.id() + 1; 03125 if (v > space_dim) 03126 throw_dimension_incompatible("affine_image(v, e, d)", var.id()); 03127 03128 // The image of an empty BDS is empty too. 03129 shortest_path_closure_assign(); 03130 if (marked_empty()) 03131 return; 03132 03133 const Coefficient& b = expr.inhomogeneous_term(); 03134 // Number of non-zero coefficients in `expr': will be set to 03135 // 0, 1, or 2, the latter value meaning any value greater than 1. 03136 dimension_type t = 0; 03137 // Index of the last non-zero coefficient in `expr', if any. 03138 dimension_type w = 0; 03139 // Get information about the number of non-zero coefficients in `expr'. 03140 for (dimension_type i = expr_space_dim; i-- > 0; ) 03141 if (expr.coefficient(Variable(i)) != 0) { 03142 if (t++ == 1) 03143 break; 03144 else 03145 w = i+1; 03146 } 03147 03148 // Now we know the form of `expr': 03149 // - If t == 0, then expr == b, with `b' a constant; 03150 // - If t == 1, then expr == a*w + b, where `w' can be `v' or another 03151 // variable; in this second case we have to check whether `a' is 03152 // equal to `denominator' or `-denominator', since otherwise we have 03153 // to fall back on the general form; 03154 // - If t == 2, the `expr' is of the general form. 03155 TEMP_INTEGER(minus_den); 03156 neg_assign(minus_den, denominator); 03157 03158 if (t == 0) { 03159 // Case 1: expr == b. 03160 // Remove all constraints on `var'. 03161 forget_all_dbm_constraints(v); 03162 // Shortest-path closure is preserved, but not reduction. 03163 if (marked_shortest_path_reduced()) 03164 reset_shortest_path_reduced(); 03165 // Add the constraint `var == b/denominator'. 03166 add_dbm_constraint(0, v, b, denominator); 03167 add_dbm_constraint(v, 0, b, minus_den); 03168 assert(OK()); 03169 return; 03170 } 03171 03172 if (t == 1) { 03173 // Value of the one and only non-zero coefficient in `expr'. 03174 const Coefficient& a = expr.coefficient(Variable(w-1)); 03175 if (a == denominator || a == minus_den) { 03176 // Case 2: expr == a*w + b, with a == +/- denominator. 03177 if (w == v) { 03178 // `expr' is of the form: a*v + b. 03179 if (a == denominator) { 03180 if (b == 0) 03181 // The transformation is the identity function. 03182 return; 03183 else { 03184 // Translate all the constraints on `var', 03185 // adding or subtracting the value `b/denominator'. 03186 DIRTY_TEMP(N, d); 03187 div_round_up(d, b, denominator); 03188 DIRTY_TEMP(N, c); 03189 div_round_up(c, b, minus_den); 03190 DB_Row<N>& dbm_v = dbm[v]; 03191 for (dimension_type i = space_dim + 1; i-- > 0; ) { 03192 N& dbm_vi = dbm_v[i]; 03193 add_assign_r(dbm_vi, dbm_vi, c, ROUND_UP); 03194 N& dbm_iv = dbm[i][v]; 03195 add_assign_r(dbm_iv, dbm_iv, d, ROUND_UP); 03196 } 03197 // Both shortest-path closure and reduction are preserved. 03198 } 03199 } 03200 else { 03201 // Here `a == -denominator'. 03202 // Remove the binary constraints on `var'. 03203 forget_binary_dbm_constraints(v); 03204 // Swap the unary constraints on `var'. 03205 std::swap(dbm[v][0], dbm[0][v]); 03206 // Shortest-path closure is not preserved. 03207 reset_shortest_path_closed(); 03208 if (b != 0) { 03209 // Translate the unary constraints on `var', 03210 // adding or subtracting the value `b/denominator'. 03211 DIRTY_TEMP(N, c); 03212 div_round_up(c, b, minus_den); 03213 N& dbm_v0 = dbm[v][0]; 03214 add_assign_r(dbm_v0, dbm_v0, c, ROUND_UP); 03215 DIRTY_TEMP(N, d); 03216 div_round_up(d, b, denominator); 03217 N& dbm_0v = dbm[0][v]; 03218 add_assign_r(dbm_0v, dbm_0v, d, ROUND_UP); 03219 } 03220 } 03221 } 03222 else { 03223 // Here `w != v', so that `expr' is of the form 03224 // +/-denominator * w + b. 03225 // Remove all constraints on `var'. 03226 forget_all_dbm_constraints(v); 03227 // Shortest-path closure is preserved, but not reduction. 03228 if (marked_shortest_path_reduced()) 03229 reset_shortest_path_reduced(); 03230 if (a == denominator) { 03231 // Add the new constraint `v - w == b/denominator'. 03232 add_dbm_constraint(w, v, b, denominator); 03233 add_dbm_constraint(v, w, b, minus_den); 03234 } 03235 else { 03236 // Here a == -denominator, so that we should be adding 03237 // the constraint `v + w == b/denominator'. 03238 // Approximate it by computing lower and upper bounds for `w'. 03239 const N& dbm_w0 = dbm[w][0]; 03240 if (!is_plus_infinity(dbm_w0)) { 03241 // Add the constraint `v <= b/denominator - lower_w'. 03242 DIRTY_TEMP(N, d); 03243 div_round_up(d, b, denominator); 03244 add_assign_r(dbm[0][v], d, dbm_w0, ROUND_UP); 03245 reset_shortest_path_closed(); 03246 } 03247 const N& dbm_0w = dbm[0][w]; 03248 if (!is_plus_infinity(dbm_0w)) { 03249 // Add the constraint `v >= b/denominator - upper_w'. 03250 DIRTY_TEMP(N, c); 03251 div_round_up(c, b, minus_den); 03252 add_assign_r(dbm[v][0], dbm_0w, c, ROUND_UP); 03253 reset_shortest_path_closed(); 03254 } 03255 } 03256 } 03257 assert(OK()); 03258 return; 03259 } 03260 } 03261 03262 // General case. 03263 // Either t == 2, so that 03264 // expr == a_1*x_1 + a_2*x_2 + ... + a_n*x_n + b, where n >= 2, 03265 // or t == 1, expr == a*w + b, but a <> +/- denominator. 03266 // We will remove all the constraints on `var' and add back 03267 // constraints providing upper and lower bounds for `var'. 03268 03269 // Compute upper approximations for `expr' and `-expr' 03270 // into `pos_sum' and `neg_sum', respectively, taking into account 03271 // the sign of `denominator'. 03272 // Note: approximating `-expr' from above and then negating the 03273 // result is the same as approximating `expr' from below. 03274 const bool is_sc = (denominator > 0); 03275 TEMP_INTEGER(minus_b); 03276 neg_assign(minus_b, b); 03277 const Coefficient& sc_b = is_sc ? b : minus_b; 03278 const Coefficient& minus_sc_b = is_sc ? minus_b : b; 03279 const Coefficient& sc_den = is_sc ? denominator : minus_den; 03280 const Coefficient& minus_sc_den = is_sc ? minus_den : denominator; 03281 // NOTE: here, for optimization purposes, `minus_expr' is only assigned 03282 // when `denominator' is negative. Do not use it unless you are sure 03283 // it has been correctly assigned. 03284 Linear_Expression minus_expr; 03285 if (!is_sc) 03286 minus_expr = -expr; 03287 const Linear_Expression& sc_expr = is_sc ? expr : minus_expr; 03288 03289 DIRTY_TEMP(N, pos_sum); 03290 DIRTY_TEMP(N, neg_sum); 03291 // Indices of the variables that are unbounded in `this->dbm'. 03292 PPL_UNINITIALIZED(dimension_type, pos_pinf_index); 03293 PPL_UNINITIALIZED(dimension_type, neg_pinf_index); 03294 // Number of unbounded variables found. 03295 dimension_type pos_pinf_count = 0; 03296 dimension_type neg_pinf_count = 0; 03297 03298 // Approximate the inhomogeneous term. 03299 assign_r(pos_sum, sc_b, ROUND_UP); 03300 assign_r(neg_sum, minus_sc_b, ROUND_UP); 03301 03302 // Approximate the homogeneous part of `sc_expr'. 03303 const DB_Row<N>& dbm_0 = dbm[0]; 03304 // Speculative allocation of temporaries to be used in the following loop. 03305 DIRTY_TEMP(N, coeff_i); 03306 TEMP_INTEGER(minus_sc_i); 03307 // Note: indices above `w' can be disregarded, as they all have 03308 // a zero coefficient in `sc_expr'. 03309 for (dimension_type i = w; i > 0; --i) { 03310 const Coefficient& sc_i = sc_expr.coefficient(Variable(i-1)); 03311 const int sign_i = sgn(sc_i); 03312 if (sign_i > 0) { 03313 assign_r(coeff_i, sc_i, ROUND_UP); 03314 // Approximating `sc_expr'. 03315 if (pos_pinf_count <= 1) { 03316 const N& up_approx_i = dbm_0[i]; 03317 if (!is_plus_infinity(up_approx_i)) 03318 add_mul_assign_r(pos_sum, coeff_i, up_approx_i, ROUND_UP); 03319 else { 03320 ++pos_pinf_count; 03321 pos_pinf_index = i; 03322 } 03323 } 03324 // Approximating `-sc_expr'. 03325 if (neg_pinf_count <= 1) { 03326 const N& up_approx_minus_i = dbm[i][0]; 03327 if (!is_plus_infinity(up_approx_minus_i)) 03328 add_mul_assign_r(neg_sum, coeff_i, up_approx_minus_i, ROUND_UP); 03329 else { 03330 ++neg_pinf_count; 03331 neg_pinf_index = i; 03332 } 03333 } 03334 } 03335 else if (sign_i < 0) { 03336 neg_assign(minus_sc_i, sc_i); 03337 // Note: using temporary named `coeff_i' to store -coeff_i. 03338 assign_r(coeff_i, minus_sc_i, ROUND_UP); 03339 // Approximating `sc_expr'. 03340 if (pos_pinf_count <= 1) { 03341 const N& up_approx_minus_i = dbm[i][0]; 03342 if (!is_plus_infinity(up_approx_minus_i)) 03343 add_mul_assign_r(pos_sum, coeff_i, up_approx_minus_i, ROUND_UP); 03344 else { 03345 ++pos_pinf_count; 03346 pos_pinf_index = i; 03347 } 03348 } 03349 // Approximating `-sc_expr'. 03350 if (neg_pinf_count <= 1) { 03351 const N& up_approx_i = dbm_0[i]; 03352 if (!is_plus_infinity(up_approx_i)) 03353 add_mul_assign_r(neg_sum, coeff_i, up_approx_i, ROUND_UP); 03354 else { 03355 ++neg_pinf_count; 03356 neg_pinf_index = i; 03357 } 03358 } 03359 } 03360 } 03361 03362 // Remove all constraints on 'v'. 03363 forget_all_dbm_constraints(v); 03364 // Shortest-path closure is maintained, but not reduction. 03365 if (marked_shortest_path_reduced()) 03366 reset_shortest_path_reduced(); 03367 // Return immediately if no approximation could be computed. 03368 if (pos_pinf_count > 1 && neg_pinf_count > 1) { 03369 assert(OK()); 03370 return; 03371 } 03372 03373 // In the following, shortest-path closure will be definitely lost. 03374 reset_shortest_path_closed(); 03375 03376 // Exploit the upper approximation, if possible. 03377 if (pos_pinf_count <= 1) { 03378 // Compute quotient (if needed). 03379 if (sc_den != 1) { 03380 // Before computing quotients, the denominator should be approximated 03381 // towards zero. Since `sc_den' is known to be positive, this amounts to 03382 // rounding downwards, which is achieved as usual by rounding upwards 03383 // `minus_sc_den' and negating again the result. 03384 DIRTY_TEMP(N, down_sc_den); 03385 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 03386 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 03387 div_assign_r(pos_sum, pos_sum, down_sc_den, ROUND_UP); 03388 } 03389 // Add the upper bound constraint, if meaningful. 03390 if (pos_pinf_count == 0) { 03391 // Add the constraint `v <= pos_sum'. 03392 dbm[0][v] = pos_sum; 03393 // Deduce constraints of the form `v - u', where `u != v'. 03394 deduce_v_minus_u_bounds(v, w, sc_expr, sc_den, pos_sum); 03395 } 03396 else 03397 // Here `pos_pinf_count == 1'. 03398 if (pos_pinf_index != v 03399 && sc_expr.coefficient(Variable(pos_pinf_index-1)) == sc_den) 03400 // Add the constraint `v - pos_pinf_index <= pos_sum'. 03401 dbm[pos_pinf_index][v] = pos_sum; 03402 } 03403 03404 // Exploit the lower approximation, if possible. 03405 if (neg_pinf_count <= 1) { 03406 // Compute quotient (if needed). 03407 if (sc_den != 1) { 03408 // Before computing quotients, the denominator should be approximated 03409 // towards zero. Since `sc_den' is known to be positive, this amounts to 03410 // rounding downwards, which is achieved as usual by rounding upwards 03411 // `minus_sc_den' and negating again the result. 03412 DIRTY_TEMP(N, down_sc_den); 03413 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 03414 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 03415 div_assign_r(neg_sum, neg_sum, down_sc_den, ROUND_UP); 03416 } 03417 // Add the lower bound constraint, if meaningful. 03418 if (neg_pinf_count == 0) { 03419 // Add the constraint `v >= -neg_sum', i.e., `-v <= neg_sum'. 03420 DB_Row<N>& dbm_v = dbm[v]; 03421 dbm_v[0] = neg_sum; 03422 // Deduce constraints of the form `u - v', where `u != v'. 03423 deduce_u_minus_v_bounds(v, w, sc_expr, sc_den, neg_sum); 03424 } 03425 else 03426 // Here `neg_pinf_count == 1'. 03427 if (neg_pinf_index != v 03428 && sc_expr.coefficient(Variable(neg_pinf_index-1)) == sc_den) 03429 // Add the constraint `v - neg_pinf_index >= -neg_sum', 03430 // i.e., `neg_pinf_index - v <= neg_sum'. 03431 dbm[v][neg_pinf_index] = neg_sum; 03432 } 03433 03434 assert(OK()); 03435 }
| void Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage | ( | Variable | var, | |
| const Linear_Expression & | expr, | |||
| Coefficient_traits::const_reference | denominator = Coefficient_one() | |||
| ) | [inline] |
Assigns to *this the affine preimage of *this under the function mapping variable var into the affine expression specified by expr and denominator.
| var | The variable to which the affine expression is substituted. | |
| expr | The numerator of the affine expression. | |
| denominator | The denominator of the affine expression. |
| std::invalid_argument | Thrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a dimension of *this. |
Definition at line 3439 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage().
03441 { 03442 // The denominator cannot be zero. 03443 if (denominator == 0) 03444 throw_generic("affine_preimage(v, e, d)", "d == 0"); 03445 03446 // Dimension-compatibility checks. 03447 // The dimension of `expr' should not be greater than the dimension 03448 // of `*this'. 03449 const dimension_type space_dim = space_dimension(); 03450 const dimension_type expr_space_dim = expr.space_dimension(); 03451 if (space_dim < expr_space_dim) 03452 throw_dimension_incompatible("affine_preimage(v, e, d)", "e", expr); 03453 03454 // `var' should be one of the dimensions of 03455 // the bounded difference shapes. 03456 const dimension_type v = var.id() + 1; 03457 if (v > space_dim) 03458 throw_dimension_incompatible("affine_preimage(v, e, d)", var.id()); 03459 03460 // The image of an empty BDS is empty too. 03461 shortest_path_closure_assign(); 03462 if (marked_empty()) 03463 return; 03464 03465 const Coefficient& b = expr.inhomogeneous_term(); 03466 // Number of non-zero coefficients in `expr': will be set to 03467 // 0, 1, or 2, the latter value meaning any value greater than 1. 03468 dimension_type t = 0; 03469 // Index of the last non-zero coefficient in `expr', if any. 03470 dimension_type j = 0; 03471 // Get information about the number of non-zero coefficients in `expr'. 03472 for (dimension_type i = expr_space_dim; i-- > 0; ) 03473 if (expr.coefficient(Variable(i)) != 0) { 03474 if (t++ == 1) 03475 break; 03476 else 03477 j = i; 03478 } 03479 03480 // Now we know the form of `expr': 03481 // - If t == 0, then expr = b, with `b' a constant; 03482 // - If t == 1, then expr = a*w + b, where `w' can be `v' or another 03483 // variable; in this second case we have to check whether `a' is 03484 // equal to `denominator' or `-denominator', since otherwise we have 03485 // to fall back on the general form; 03486 // - If t > 1, the `expr' is of the general form. 03487 if (t == 0) { 03488 // Case 1: expr = n; remove all constraints on `var'. 03489 forget_all_dbm_constraints(v); 03490 // Shortest-path closure is preserved, but not reduction. 03491 if (marked_shortest_path_reduced()) 03492 reset_shortest_path_reduced(); 03493 assert(OK()); 03494 return; 03495 } 03496 03497 if (t == 1) { 03498 // Value of the one and only non-zero coefficient in `expr'. 03499 const Coefficient& a = expr.coefficient(Variable(j)); 03500 if (a == denominator || a == -denominator) { 03501 // Case 2: expr = a*w + b, with a = +/- denominator. 03502 if (j == var.id()) 03503 // Apply affine_image() on the inverse of this transformation. 03504 affine_image(var, denominator*var - b, a); 03505 else { 03506 // `expr == a*w + b', where `w != v'. 03507 // Remove all constraints on `var'. 03508 forget_all_dbm_constraints(v); 03509 // Shortest-path closure is preserved, but not reduction. 03510 if (marked_shortest_path_reduced()) 03511 reset_shortest_path_reduced(); 03512 assert(OK()); 03513 } 03514 return; 03515 } 03516 } 03517 03518 // General case. 03519 // Either t == 2, so that 03520 // expr = a_1*x_1 + a_2*x_2 + ... + a_n*x_n + b, where n >= 2, 03521 // or t = 1, expr = a*w + b, but a <> +/- denominator. 03522 const Coefficient& expr_v = expr.coefficient(var); 03523 if (expr_v != 0) { 03524 // The transformation is invertible. 03525 Linear_Expression inverse((expr_v + denominator)*var); 03526 inverse -= expr; 03527 affine_image(var, inverse, expr_v); 03528 } 03529 else { 03530 // Transformation not invertible: all constraints on `var' are lost. 03531 forget_all_dbm_constraints(v); 03532 // Shortest-path closure is preserved, but not reduction. 03533 if (marked_shortest_path_reduced()) 03534 reset_shortest_path_reduced(); 03535 } 03536 assert(OK()); 03537 }
| void Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image | ( | Variable | var, | |
| Relation_Symbol | relsym, | |||
| const Linear_Expression & | expr, | |||
| Coefficient_traits::const_reference | denominator = Coefficient_one() | |||
| ) | [inline] |
Assigns to *this the image of *this with respect to the affine relation
, where
is the relation symbol encoded by relsym.
| var | The left hand side variable of the generalized affine transfer function. | |
| relsym | The relation symbol. | |
| expr | The numerator of the right hand side affine expression. | |
| denominator | The denominator of the right hand side affine expression. |
| std::invalid_argument | Thrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a dimension of *this or if relsym is a strict relation symbol. |
Definition at line 3852 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::deduce_u_minus_v_bounds(), Parma_Polyhedra_Library::BD_Shape< T >::deduce_v_minus_u_bounds(), Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::forget_binary_dbm_constraints(), Parma_Polyhedra_Library::GREATER_OR_EQUAL, Parma_Polyhedra_Library::GREATER_THAN, Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::LESS_THAN, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::NOT_EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::OK(), PLUS_INFINITY, Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), and Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage().
03856 { 03857 // The denominator cannot be zero. 03858 if (denominator == 0) 03859 throw_generic("generalized_affine_image(v, r, e, d)", "d == 0"); 03860 03861 // Dimension-compatibility checks. 03862 // The dimension of `expr' should not be greater than the dimension 03863 // of `*this'. 03864 const dimension_type space_dim = space_dimension(); 03865 const dimension_type expr_space_dim = expr.space_dimension(); 03866 if (space_dim < expr_space_dim) 03867 throw_dimension_incompatible("generalized_affine_image(v, r, e, d)", 03868 "e", expr); 03869 03870 // `var' should be one of the dimensions of the BDS. 03871 const dimension_type v = var.id() + 1; 03872 if (v > space_dim) 03873 throw_dimension_incompatible("generalized_affine_image(v, r, e, d)", 03874 var.id()); 03875 03876 // The relation symbol cannot be a strict relation symbol. 03877 if (relsym == LESS_THAN || relsym == GREATER_THAN) 03878 throw_generic("generalized_affine_image(v, r, e, d)", 03879 "r is a strict relation symbol and " 03880 "*this is a BD_Shape"); 03881 // The relation symbol cannot be a disequality. 03882 if (relsym == NOT_EQUAL) 03883 throw_generic("generalized_affine_image(v, r, e, d)", 03884 "r is the disequality relation symbol and " 03885 "*this is a BD_Shape"); 03886 03887 if (relsym == EQUAL) { 03888 // The relation symbol is "==": 03889 // this is just an affine image computation. 03890 affine_image(var, expr, denominator); 03891 return; 03892 } 03893 03894 // The image of an empty BDS is empty too. 03895 shortest_path_closure_assign(); 03896 if (marked_empty()) 03897 return; 03898 03899 const Coefficient& b = expr.inhomogeneous_term(); 03900 // Number of non-zero coefficients in `expr': will be set to 03901 // 0, 1, or 2, the latter value meaning any value greater than 1. 03902 dimension_type t = 0; 03903 // Index of the last non-zero coefficient in `expr', if any. 03904 dimension_type w = 0; 03905 // Get information about the number of non-zero coefficients in `expr'. 03906 for (dimension_type i = expr_space_dim; i-- > 0; ) 03907 if (expr.coefficient(Variable(i)) != 0) { 03908 if (t++ == 1) 03909 break; 03910 else 03911 w = i+1; 03912 } 03913 03914 // Now we know the form of `expr': 03915 // - If t == 0, then expr == b, with `b' a constant; 03916 // - If t == 1, then expr == a*w + b, where `w' can be `v' or another 03917 // variable; in this second case we have to check whether `a' is 03918 // equal to `denominator' or `-denominator', since otherwise we have 03919 // to fall back on the general form; 03920 // - If t == 2, the `expr' is of the general form. 03921 DB_Row<N>& dbm_0 = dbm[0]; 03922 DB_Row<N>& dbm_v = dbm[v]; 03923 TEMP_INTEGER(minus_den); 03924 neg_assign(minus_den, denominator); 03925 03926 if (t == 0) { 03927 // Case 1: expr == b. 03928 // Remove all constraints on `var'. 03929 forget_all_dbm_constraints(v); 03930 // Both shortest-path closure and reduction are lost. 03931 reset_shortest_path_closed(); 03932 switch (relsym) { 03933 case LESS_OR_EQUAL: 03934 // Add the constraint `var <= b/denominator'. 03935 add_dbm_constraint(0, v, b, denominator); 03936 break; 03937 case GREATER_OR_EQUAL: 03938 // Add the constraint `var >= b/denominator', 03939 // i.e., `-var <= -b/denominator', 03940 add_dbm_constraint(v, 0, b, minus_den); 03941 break; 03942 default: 03943 // We already dealt with the other cases. 03944 throw std::runtime_error("PPL internal error"); 03945 } 03946 assert(OK()); 03947 return; 03948 } 03949 03950 if (t == 1) { 03951 // Value of the one and only non-zero coefficient in `expr'. 03952 const Coefficient& a = expr.coefficient(Variable(w-1)); 03953 if (a == denominator || a == minus_den) { 03954 // Case 2: expr == a*w + b, with a == +/- denominator. 03955 DIRTY_TEMP(N, d); 03956 switch (relsym) { 03957 case LESS_OR_EQUAL: 03958 div_round_up(d, b, denominator); 03959 if (w == v) { 03960 // `expr' is of the form: a*v + b. 03961 // Shortest-path closure and reduction are not preserved. 03962 reset_shortest_path_closed(); 03963 if (a == denominator) { 03964 // Translate each constraint `v - w <= dbm_wv' 03965 // into the constraint `v - w <= dbm_wv + b/denominator'; 03966 // forget each constraint `w - v <= dbm_vw'. 03967 for (dimension_type i = space_dim + 1; i-- > 0; ) { 03968 N& dbm_iv = dbm[i][v]; 03969 add_assign_r(dbm_iv, dbm_iv, d, ROUND_UP); 03970 assign_r(dbm_v[i], PLUS_INFINITY, ROUND_NOT_NEEDED); 03971 } 03972 } 03973 else { 03974 // Here `a == -denominator'. 03975 // Translate the constraint `0 - v <= dbm_v0' 03976 // into the constraint `0 - v <= dbm_v0 + b/denominator'. 03977 N& dbm_v0 = dbm_v[0]; 03978 add_assign_r(dbm_0[v], dbm_v0, d, ROUND_UP); 03979 // Forget all the other constraints on `v'. 03980 assign_r(dbm_v0, PLUS_INFINITY, ROUND_NOT_NEEDED); 03981 forget_binary_dbm_constraints(v); 03982 } 03983 } 03984 else { 03985 // Here `w != v', so that `expr' is of the form 03986 // +/-denominator * w + b, with `w != v'. 03987 // Remove all constraints on `v'. 03988 forget_all_dbm_constraints(v); 03989 // Shortest-path closure is preserved, but not reduction. 03990 if (marked_shortest_path_reduced()) 03991 reset_shortest_path_reduced(); 03992 if (a == denominator) 03993 // Add the new constraint `v - w <= b/denominator'. 03994 add_dbm_constraint(w, v, d); 03995 else { 03996 // Here a == -denominator, so that we should be adding 03997 // the constraint `v <= b/denominator - w'. 03998 // Approximate it by computing a lower bound for `w'. 03999 const N& dbm_w0 = dbm[w][0]; 04000 if (!is_plus_infinity(dbm_w0)) { 04001 // Add the constraint `v <= b/denominator - lb_w'. 04002 add_assign_r(dbm_0[v], d, dbm_w0, ROUND_UP); 04003 // Shortest-path closure is not preserved. 04004 reset_shortest_path_closed(); 04005 } 04006 } 04007 } 04008 break; 04009 04010 case GREATER_OR_EQUAL: 04011 div_round_up(d, b, minus_den); 04012 if (w == v) { 04013 // `expr' is of the form: a*w + b. 04014 // Shortest-path closure and reduction are not preserved. 04015 reset_shortest_path_closed(); 04016 if (a == denominator) { 04017 // Translate each constraint `w - v <= dbm_vw' 04018 // into the constraint `w - v <= dbm_vw - b/denominator'; 04019 // forget each constraint `v - w <= dbm_wv'. 04020 for (dimension_type i = space_dim + 1; i-- > 0; ) { 04021 N& dbm_vi = dbm_v[i]; 04022 add_assign_r(dbm_vi, dbm_vi, d, ROUND_UP); 04023 assign_r(dbm[i][v], PLUS_INFINITY, ROUND_NOT_NEEDED); 04024 } 04025 } 04026 else { 04027 // Here `a == -denominator'. 04028 // Translate the constraint `0 - v <= dbm_v0' 04029 // into the constraint `0 - v <= dbm_0v - b/denominator'. 04030 N& dbm_0v = dbm_0[v]; 04031 add_assign_r(dbm_v[0], dbm_0v, d, ROUND_UP); 04032 // Forget all the other constraints on `v'. 04033 assign_r(dbm_0v, PLUS_INFINITY, ROUND_NOT_NEEDED); 04034 forget_binary_dbm_constraints(v); 04035 } 04036 } 04037 else { 04038 // Here `w != v', so that `expr' is of the form 04039 // +/-denominator * w + b, with `w != v'. 04040 // Remove all constraints on `v'. 04041 forget_all_dbm_constraints(v); 04042 // Shortest-path closure is preserved, but not reduction. 04043 if (marked_shortest_path_reduced()) 04044 reset_shortest_path_reduced(); 04045 if (a == denominator) 04046 // Add the new constraint `v - w >= b/denominator', 04047 // i.e., `w - v <= -b/denominator'. 04048 add_dbm_constraint(v, w, d); 04049 else { 04050 // Here a == -denominator, so that we should be adding 04051 // the constraint `v >= -w + b/denominator', 04052 // i.e., `-v <= w - b/denominator'. 04053 // Approximate it by computing an upper bound for `w'. 04054 const N& dbm_0w = dbm_0[w]; 04055 if (!is_plus_infinity(dbm_0w)) { 04056 // Add the constraint `-v <= ub_w - b/denominator'. 04057 add_assign_r(dbm_v[0], dbm_0w, d, ROUND_UP); 04058 // Shortest-path closure is not preserved. 04059 reset_shortest_path_closed(); 04060 } 04061 } 04062 } 04063 break; 04064 04065 default: 04066 // We already dealt with the other cases. 04067 throw std::runtime_error("PPL internal error"); 04068 } 04069 assert(OK()); 04070 return; 04071 } 04072 } 04073 04074 // General case. 04075 // Either t == 2, so that 04076 // expr == a_1*x_1 + a_2*x_2 + ... + a_n*x_n + b, where n >= 2, 04077 // or t == 1, expr == a*w + b, but a <> +/- denominator. 04078 // We will remove all the constraints on `v' and add back 04079 // a constraint providing an upper or a lower bound for `v' 04080 // (depending on `relsym'). 04081 const bool is_sc = (denominator > 0); 04082 TEMP_INTEGER(minus_b); 04083 neg_assign(minus_b, b); 04084 const Coefficient& sc_b = is_sc ? b : minus_b; 04085 const Coefficient& minus_sc_b = is_sc ? minus_b : b; 04086 const Coefficient& sc_den = is_sc ? denominator : minus_den; 04087 const Coefficient& minus_sc_den = is_sc ? minus_den : denominator; 04088 // NOTE: here, for optimization purposes, `minus_expr' is only assigned 04089 // when `denominator' is negative. Do not use it unless you are sure 04090 // it has been correctly assigned. 04091 Linear_Expression minus_expr; 04092 if (!is_sc) 04093 minus_expr = -expr; 04094 const Linear_Expression& sc_expr = is_sc ? expr : minus_expr; 04095 04096 DIRTY_TEMP(N, sum); 04097 // Index of variable that is unbounded in `this->dbm'. 04098 PPL_UNINITIALIZED(dimension_type, pinf_index); 04099 // Number of unbounded variables found. 04100 dimension_type pinf_count = 0; 04101 04102 // Speculative allocation of temporaries to be used in the following loops. 04103 DIRTY_TEMP(N, coeff_i); 04104 TEMP_INTEGER(minus_sc_i); 04105 04106 switch (relsym) { 04107 case LESS_OR_EQUAL: 04108 // Compute an upper approximation for `sc_expr' into `sum'. 04109 04110 // Approximate the inhomogeneous term. 04111 assign_r(sum, sc_b, ROUND_UP); 04112 // Approximate the homogeneous part of `sc_expr'. 04113 // Note: indices above `w' can be disregarded, as they all have 04114 // a zero coefficient in `sc_expr'. 04115 for (dimension_type i = w; i > 0; --i) { 04116 const Coefficient& sc_i = sc_expr.coefficient(Variable(i-1)); 04117 const int sign_i = sgn(sc_i); 04118 if (sign_i == 0) 04119 continue; 04120 // Choose carefully: we are approximating `sc_expr'. 04121 const N& approx_i = (sign_i > 0) ? dbm_0[i] : dbm[i][0]; 04122 if (is_plus_infinity(approx_i)) { 04123 if (++pinf_count > 1) 04124 break; 04125 pinf_index = i; 04126 continue; 04127 } 04128 if (sign_i > 0) 04129 assign_r(coeff_i, sc_i, ROUND_UP); 04130 else { 04131 neg_assign(minus_sc_i, sc_i); 04132 assign_r(coeff_i, minus_sc_i, ROUND_UP); 04133 } 04134 add_mul_assign_r(sum, coeff_i, approx_i, ROUND_UP); 04135 } 04136 04137 // Remove all constraints on `v'. 04138 forget_all_dbm_constraints(v); 04139 // Shortest-path closure is preserved, but not reduction. 04140 if (marked_shortest_path_reduced()) 04141 reset_shortest_path_reduced(); 04142 // Return immediately if no approximation could be computed. 04143 if (pinf_count > 1) { 04144 assert(OK()); 04145 return; 04146 } 04147 04148 // Divide by the (sign corrected) denominator (if needed). 04149 if (sc_den != 1) { 04150 // Before computing the quotient, the denominator should be approximated 04151 // towards zero. Since `sc_den' is known to be positive, this amounts to 04152 // rounding downwards, which is achieved as usual by rounding upwards 04153 // `minus_sc_den' and negating again the result. 04154 DIRTY_TEMP(N, down_sc_den); 04155 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 04156 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 04157 div_assign_r(sum, sum, down_sc_den, ROUND_UP); 04158 } 04159 04160 if (pinf_count == 0) { 04161 // Add the constraint `v <= sum'. 04162 add_dbm_constraint(0, v, sum); 04163 // Deduce constraints of the form `v - u', where `u != v'. 04164 deduce_v_minus_u_bounds(v, w, sc_expr, sc_den, sum); 04165 } 04166 else if (pinf_count == 1) 04167 if (pinf_index != v 04168 && expr.coefficient(Variable(pinf_index-1)) == denominator) 04169 // Add the constraint `v - pinf_index <= sum'. 04170 add_dbm_constraint(pinf_index, v, sum); 04171 break; 04172 04173 case GREATER_OR_EQUAL: 04174 // Compute an upper approximation for `-sc_expr' into `sum'. 04175 // Note: approximating `-sc_expr' from above and then negating the 04176 // result is the same as approximating `sc_expr' from below. 04177 04178 // Approximate the inhomogeneous term. 04179 assign_r(sum, minus_sc_b, ROUND_UP); 04180 // Approximate the homogeneous part of `-sc_expr'. 04181 for (dimension_type i = expr_space_dim + 1; i > 0; --i) { 04182 const Coefficient& sc_i = sc_expr.coefficient(Variable(i-1)); 04183 const int sign_i = sgn(sc_i); 04184 if (sign_i == 0) 04185 continue; 04186 // Choose carefully: we are approximating `-sc_expr'. 04187 const N& approx_i = (sign_i > 0) ? dbm[i][0] : dbm_0[i]; 04188 if (is_plus_infinity(approx_i)) { 04189 if (++pinf_count > 1) 04190 break; 04191 pinf_index = i; 04192 continue; 04193 } 04194 if (sign_i > 0) 04195 assign_r(coeff_i, sc_i, ROUND_UP); 04196 else { 04197 neg_assign(minus_sc_i, sc_i); 04198 assign_r(coeff_i, minus_sc_i, ROUND_UP); 04199 } 04200 add_mul_assign_r(sum, coeff_i, approx_i, ROUND_UP); 04201 } 04202 04203 // Remove all constraints on `var'. 04204 forget_all_dbm_constraints(v); 04205 // Shortest-path closure is preserved, but not reduction. 04206 if (marked_shortest_path_reduced()) 04207 reset_shortest_path_reduced(); 04208 // Return immediately if no approximation could be computed. 04209 if (pinf_count > 1) { 04210 assert(OK()); 04211 return; 04212 } 04213 04214 // Divide by the (sign corrected) denominator (if needed). 04215 if (sc_den != 1) { 04216 // Before computing the quotient, the denominator should be approximated 04217 // towards zero. Since `sc_den' is known to be positive, this amounts to 04218 // rounding downwards, which is achieved as usual by rounding upwards 04219 // `minus_sc_den' and negating again the result. 04220 DIRTY_TEMP(N, down_sc_den); 04221 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 04222 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 04223 div_assign_r(sum, sum, down_sc_den, ROUND_UP); 04224 } 04225 04226 if (pinf_count == 0) { 04227 // Add the constraint `v >= -sum', i.e., `-v <= sum'. 04228 add_dbm_constraint(v, 0, sum); 04229 // Deduce constraints of the form `u - v', where `u != v'. 04230 deduce_u_minus_v_bounds(v, w, sc_expr, sc_den, sum); 04231 } 04232 else if (pinf_count == 1) 04233 if (pinf_index != v 04234 && expr.coefficient(Variable(pinf_index-1)) == denominator) 04235 // Add the constraint `v - pinf_index >= -sum', 04236 // i.e., `pinf_index - v <= sum'. 04237 add_dbm_constraint(v, pinf_index, sum); 04238 break; 04239 04240 default: 04241 // We already dealt with the other cases. 04242 throw std::runtime_error("PPL internal error"); 04243 } 04244 assert(OK()); 04245 }
| void Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image | ( | const Linear_Expression & | lhs, | |
| Relation_Symbol | relsym, | |||
| const Linear_Expression & | rhs | |||
| ) | [inline] |
Assigns to *this the image of *this with respect to the affine relation
, where
is the relation symbol encoded by relsym.
| lhs | The left hand side affine expression. | |
| relsym | The relation symbol. | |
| rhs | The right hand side affine expression. |
| std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs or if relsym is a strict relation symbol. |
Definition at line 4249 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::GREATER_OR_EQUAL, Parma_Polyhedra_Library::GREATER_THAN, Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::LESS_THAN, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::NOT_EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
04251 { 04252 // Dimension-compatibility checks. 04253 // The dimension of `lhs' should not be greater than the dimension 04254 // of `*this'. 04255 const dimension_type space_dim = space_dimension(); 04256 const dimension_type lhs_space_dim = lhs.space_dimension(); 04257 if (space_dim < lhs_space_dim) 04258 throw_dimension_incompatible("generalized_affine_image(e1, r, e2)", 04259 "e1", lhs); 04260 04261 // The dimension of `rhs' should not be greater than the dimension 04262 // of `*this'. 04263 const dimension_type rhs_space_dim = rhs.space_dimension(); 04264 if (space_dim < rhs_space_dim) 04265 throw_dimension_incompatible("generalized_affine_image(e1, r, e2)", 04266 "e2", rhs); 04267 04268 // Strict relation symbols are not admitted for BDSs. 04269 if (relsym == LESS_THAN || relsym == GREATER_THAN) 04270 throw_generic("generalized_affine_image(e1, r, e2)", 04271 "r is a strict relation symbol and " 04272 "*this is a BD_Shape"); 04273 // The relation symbol cannot be a disequality. 04274 if (relsym == NOT_EQUAL) 04275 throw_generic("generalized_affine_image(e1, r, e2)", 04276 "r is the disequality relation symbol and " 04277 "*this is a BD_Shape"); 04278 04279 // The image of an empty BDS is empty. 04280 shortest_path_closure_assign(); 04281 if (marked_empty()) 04282 return; 04283 04284 // Number of non-zero coefficients in `lhs': will be set to 04285 // 0, 1, or 2, the latter value meaning any value greater than 1. 04286 dimension_type t_lhs = 0; 04287 // Index of the last non-zero coefficient in `lhs', if any. 04288 dimension_type j_lhs = 0; 04289 // Compute the number of the non-zero components of `lhs'. 04290 for (dimension_type i = lhs_space_dim; i-- > 0; ) 04291 if (lhs.coefficient(Variable(i)) != 0) { 04292 if (t_lhs++ == 1) 04293 break; 04294 else 04295 j_lhs = i; 04296 } 04297 04298 const Coefficient& b_lhs = lhs.inhomogeneous_term(); 04299 04300 if (t_lhs == 0) { 04301 // `lhs' is a constant. 04302 // In principle, it is sufficient to add the constraint `lhs relsym rhs'. 04303 // Note that this constraint is a bounded difference if `t_rhs <= 1' 04304 // or `t_rhs > 1' and `rhs == a*v - a*w + b_rhs'. If `rhs' is of a 04305 // more general form, it will be simply ignored. 04306 // TODO: if it is not a bounded difference, should we compute 04307 // approximations for this constraint? 04308 switch (relsym) { 04309 case LESS_OR_EQUAL: 04310 refine_no_check(lhs <= rhs); 04311 break; 04312 case EQUAL: 04313 refine_no_check(lhs == rhs); 04314 break; 04315 case GREATER_OR_EQUAL: 04316 refine_no_check(lhs >= rhs); 04317 break; 04318 default: 04319 // We already dealt with the other cases. 04320 throw std::runtime_error("PPL internal error"); 04321 } 04322 } 04323 else if (t_lhs == 1) { 04324 // Here `lhs == a_lhs * v + b_lhs'. 04325 // Independently from the form of `rhs', we can exploit the 04326 // method computing generalized affine images for a single variable. 04327 Variable v(j_lhs); 04328 // Compute a sign-corrected relation symbol. 04329 const Coefficient& den = lhs.coefficient(v); 04330 Relation_Symbol new_relsym = relsym; 04331 if (den < 0) { 04332 if (relsym == LESS_OR_EQUAL) 04333 new_relsym = GREATER_OR_EQUAL; 04334 else if (relsym == GREATER_OR_EQUAL) 04335 new_relsym = LESS_OR_EQUAL; 04336 } 04337 Linear_Expression expr = rhs - b_lhs; 04338 generalized_affine_image(v, new_relsym, expr, den); 04339 } 04340 else { 04341 // Here `lhs' is of the general form, having at least two variables. 04342 // Compute the set of variables occurring in `lhs'. 04343 bool lhs_vars_intersects_rhs_vars = false; 04344 std::vector<Variable> lhs_vars; 04345 for (dimension_type i = lhs_space_dim; i-- > 0; ) 04346 if (lhs.coefficient(Variable(i)) != 0) { 04347 lhs_vars.push_back(Variable(i)); 04348 if (rhs.coefficient(Variable(i)) != 0) 04349 lhs_vars_intersects_rhs_vars = true; 04350 } 04351 04352 if (!lhs_vars_intersects_rhs_vars) { 04353 // `lhs' and `rhs' variables are disjoint. 04354 // Existentially quantify all variables in the lhs. 04355 for (dimension_type i = lhs_vars.size(); i-- > 0; ) 04356 forget_all_dbm_constraints(lhs_vars[i].id() + 1); 04357 // Constrain the left hand side expression so that it is related to 04358 // the right hand side expression as dictated by `relsym'. 04359 // TODO: if the following constraint is NOT a bounded difference, 04360 // it will be simply ignored. Should we compute approximations for it? 04361 switch (relsym) { 04362 case LESS_OR_EQUAL: 04363 refine_no_check(lhs <= rhs); 04364 break; 04365 case EQUAL: 04366 refine_no_check(lhs == rhs); 04367 break; 04368 case GREATER_OR_EQUAL: 04369 refine_no_check(lhs >= rhs); 04370 break; 04371 default: 04372 // We already dealt with the other cases. 04373 throw std::runtime_error("PPL internal error"); 04374 } 04375 } 04376 else { 04377 // Some variables in `lhs' also occur in `rhs'. 04378 04379 #if 1 // Simplified computation (see the TODO note below). 04380 04381 for (dimension_type i = lhs_vars.size(); i-- > 0; ) 04382 forget_all_dbm_constraints(lhs_vars[i].id() + 1); 04383 04384 #else // Currently unnecessarily complex computation. 04385 04386 // More accurate computation that is worth doing only if 04387 // the following TODO note is accurately dealt with. 04388 04389 // To ease the computation, we add an additional dimension. 04390 const Variable new_var = Variable(space_dim); 04391 add_space_dimensions_and_embed(1); 04392 // Constrain the new dimension to be equal to `rhs'. 04393 // NOTE: calling affine_image() instead of refine_no_check() 04394 // ensures some approximation is tried even when the constraint 04395 // is not a bounded difference. 04396 affine_image(new_var, rhs); 04397 // Existentially quantify all variables in the lhs. 04398 // NOTE: enforce shortest-path closure for precision. 04399 shortest_path_closure_assign(); 04400 assert(!marked_empty()); 04401 for (dimension_type i = lhs_vars.size(); i-- > 0; ) 04402 forget_all_dbm_constraints(lhs_vars[i].id() + 1); 04403 // Constrain the new dimension so that it is related to 04404 // the left hand side as dictated by `relsym'. 04405 // TODO: each one of the following constraints is definitely NOT 04406 // a bounded differences (since it has 3 variables at least). 04407 // Thus, the method refine_no_check() will simply ignore it. 04408 // Should we compute approximations for this constraint? 04409 switch (relsym) { 04410 case LESS_OR_EQUAL: 04411 refine_no_check(lhs <= new_var); 04412 break; 04413 case EQUAL: 04414 refine_no_check(lhs == new_var); 04415 break; 04416 case GREATER_OR_EQUAL: 04417 refine_no_check(lhs >= new_var); 04418 break; 04419 default: 04420 // We already dealt with the other cases. 04421 throw std::runtime_error("PPL internal error"); 04422 } 04423 // Remove the temporarily added dimension. 04424 remove_higher_space_dimensions(space_dim-1); 04425 #endif // Currently unnecessarily complex computation. 04426 } 04427 } 04428 04429 assert(OK()); 04430 }
| void Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage | ( | Variable | var, | |
| Relation_Symbol | relsym, | |||
| const Linear_Expression & | expr, | |||
| Coefficient_traits::const_reference | denominator = Coefficient_one() | |||
| ) | [inline] |
Assigns to *this the preimage of *this with respect to the affine relation
, where
is the relation symbol encoded by relsym.
| var | The left hand side variable of the generalized affine transfer function. | |
| relsym | The relation symbol. | |
| expr | The numerator of the right hand side affine expression. | |
| denominator | The denominator of the right hand side affine expression. |
| std::invalid_argument | Thrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a dimension of *this or if relsym is a strict relation symbol. |
Definition at line 4434 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::GREATER_OR_EQUAL, Parma_Polyhedra_Library::GREATER_THAN, Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::BD_Shape< T >::is_empty(), Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::LESS_THAN, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::NOT_EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::refine(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), and Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage().
04438 { 04439 // The denominator cannot be zero. 04440 if (denominator == 0) 04441 throw_generic("generalized_affine_preimage(v, r, e, d)", "d == 0"); 04442 04443 // Dimension-compatibility checks. 04444 // The dimension of `expr' should not be greater than the dimension 04445 // of `*this'. 04446 const dimension_type space_dim = space_dimension(); 04447 const dimension_type expr_space_dim = expr.space_dimension(); 04448 if (space_dim < expr_space_dim) 04449 throw_dimension_incompatible("generalized_affine_preimage(v, r, e, d)", 04450 "e", expr); 04451 04452 // `var' should be one of the dimensions of the BDS. 04453 const dimension_type v = var.id() + 1; 04454 if (v > space_dim) 04455 throw_dimension_incompatible("generalized_affine_preimage(v, r, e, d)", 04456 var.id()); 04457 04458 // The relation symbol cannot be a strict relation symbol. 04459 if (relsym == LESS_THAN || relsym == GREATER_THAN) 04460 throw_generic("generalized_affine_preimage(v, r, e, d)", 04461 "r is a strict relation symbol and " 04462 "*this is a BD_Shape"); 04463 // The relation symbol cannot be a disequality. 04464 if (relsym == NOT_EQUAL) 04465 throw_generic("generalized_affine_preimage(v, r, e, d)", 04466 "r is the disequality relation symbol and " 04467 "*this is a BD_Shape"); 04468 04469 if (relsym == EQUAL) { 04470 // The relation symbol is "==": 04471 // this is just an affine preimage computation. 04472 affine_preimage(var, expr, denominator); 04473 return; 04474 } 04475 04476 // The preimage of an empty BDS is empty too. 04477 shortest_path_closure_assign(); 04478 if (marked_empty()) 04479 return; 04480 04481 // Check whether the preimage of this affine relation can be easily 04482 // computed as the image of its inverse relation. 04483 const Coefficient& expr_v = expr.coefficient(var); 04484 if (expr_v != 0) { 04485 const Relation_Symbol reversed_relsym = (relsym == LESS_OR_EQUAL) 04486 ? GREATER_OR_EQUAL : LESS_OR_EQUAL; 04487 const Linear_Expression inverse 04488 = expr - (expr_v + denominator)*var; 04489 TEMP_INTEGER(inverse_den); 04490 neg_assign(inverse_den, expr_v); 04491 const Relation_Symbol inverse_relsym 04492 = (sgn(denominator) == sgn(inverse_den)) ? relsym : reversed_relsym; 04493 generalized_affine_image(var, inverse_relsym, inverse, inverse_den); 04494 return; 04495 } 04496 04497 refine(var, relsym, expr, denominator); 04498 // If the shrunk BD_Shape is empty, its preimage is empty too; ... 04499 if (is_empty()) 04500 return; 04501 // ... otherwise, since the relation was not invertible, 04502 // we just forget all constraints on `v'. 04503 forget_all_dbm_constraints(v); 04504 // Shortest-path closure is preserved, but not reduction. 04505 if (marked_shortest_path_reduced()) 04506 reset_shortest_path_reduced(); 04507 assert(OK()); 04508 }
| void Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage | ( | const Linear_Expression & | lhs, | |
| Relation_Symbol | relsym, | |||
| const Linear_Expression & | rhs | |||
| ) | [inline] |
Assigns to *this the preimage of *this with respect to the affine relation
, where
is the relation symbol encoded by relsym.
| lhs | The left hand side affine expression. | |
| relsym | The relation symbol. | |
| rhs | The right hand side affine expression. |
| std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs or if relsym is a strict relation symbol. |
Definition at line 4512 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::GREATER_OR_EQUAL, Parma_Polyhedra_Library::GREATER_THAN, Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::BD_Shape< T >::is_empty(), Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::LESS_THAN, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::NOT_EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
04514 { 04515 // Dimension-compatibility checks. 04516 // The dimension of `lhs' should not be greater than the dimension 04517 // of `*this'. 04518 const dimension_type bds_space_dim = space_dimension(); 04519 const dimension_type lhs_space_dim = lhs.space_dimension(); 04520 if (bds_space_dim < lhs_space_dim) 04521 throw_dimension_incompatible("generalized_affine_preimage(e1, r, e2)", 04522 "e1", lhs); 04523 04524 // The dimension of `rhs' should not be greater than the dimension 04525 // of `*this'. 04526 const dimension_type rhs_space_dim = rhs.space_dimension(); 04527 if (bds_space_dim < rhs_space_dim) 04528 throw_dimension_incompatible("generalized_affine_preimage(e1, r, e2)", 04529 "e2", rhs); 04530 04531 // Strict relation symbols are not admitted for BDSs. 04532 if (relsym == LESS_THAN || relsym == GREATER_THAN) 04533 throw_generic("generalized_affine_preimage(e1, r, e2)", 04534 "r is a strict relation symbol and " 04535 "*this is a BD_Shape"); 04536 // The relation symbol cannot be a disequality. 04537 if (relsym == NOT_EQUAL) 04538 throw_generic("generalized_affine_preimage(e1, r, e2)", 04539 "r is the disequality relation symbol and " 04540 "*this is a BD_Shape"); 04541 04542 // The preimage of an empty BDS is empty. 04543 shortest_path_closure_assign(); 04544 if (marked_empty()) 04545 return; 04546 04547 // Number of non-zero coefficients in `lhs': will be set to 04548 // 0, 1, or 2, the latter value meaning any value greater than 1. 04549 dimension_type t_lhs = 0; 04550 // Index of the last non-zero coefficient in `lhs', if any. 04551 dimension_type j_lhs = 0; 04552 // Compute the number of the non-zero components of `lhs'. 04553 for (dimension_type i = lhs_space_dim; i-- > 0; ) 04554 if (lhs.coefficient(Variable(i)) != 0) { 04555 if (t_lhs++ == 1) 04556 break; 04557 else 04558 j_lhs = i; 04559 } 04560 04561 const Coefficient& b_lhs = lhs.inhomogeneous_term(); 04562 04563 if (t_lhs == 0) { 04564 // `lhs' is a constant. 04565 // In this case, preimage and image happen to be the same. 04566 generalized_affine_image(lhs, relsym, rhs); 04567 return; 04568 } 04569 else if (t_lhs == 1) { 04570 // Here `lhs == a_lhs * v + b_lhs'. 04571 // Independently from the form of `rhs', we can exploit the 04572 // method computing generalized affine preimages for a single variable. 04573 Variable v(j_lhs); 04574 // Compute a sign-corrected relation symbol. 04575 const Coefficient& den = lhs.coefficient(v); 04576 Relation_Symbol new_relsym = relsym; 04577 if (den < 0) { 04578 if (relsym == LESS_OR_EQUAL) 04579 new_relsym = GREATER_OR_EQUAL; 04580 else if (relsym == GREATER_OR_EQUAL) 04581 new_relsym = LESS_OR_EQUAL; 04582 } 04583 Linear_Expression expr = rhs - b_lhs; 04584 generalized_affine_preimage(v, new_relsym, expr, den); 04585 } 04586 else { 04587 // Here `lhs' is of the general form, having at least two variables. 04588 // Compute the set of variables occurring in `lhs'. 04589 bool lhs_vars_intersects_rhs_vars = false; 04590 std::vector<Variable> lhs_vars; 04591 for (dimension_type i = lhs_space_dim; i-- > 0; ) 04592 if (lhs.coefficient(Variable(i)) != 0) { 04593 lhs_vars.push_back(Variable(i)); 04594 if (rhs.coefficient(Variable(i)) != 0) 04595 lhs_vars_intersects_rhs_vars = true; 04596 } 04597 04598 if (!lhs_vars_intersects_rhs_vars) { 04599 // `lhs' and `rhs' variables are disjoint. 04600 04601 // Constrain the left hand side expression so that it is related to 04602 // the right hand side expression as dictated by `relsym'. 04603 // TODO: if the following constraint is NOT a bounded difference, 04604 // it will be simply ignored. Should we compute approximations for it? 04605 switch (relsym) { 04606 case LESS_OR_EQUAL: 04607 refine_no_check(lhs <= rhs); 04608 break; 04609 case EQUAL: 04610 refine_no_check(lhs == rhs); 04611 break; 04612 case GREATER_OR_EQUAL: 04613 refine_no_check(lhs >= rhs); 04614 break; 04615 default: 04616 // We already dealt with the other cases. 04617 throw std::runtime_error("PPL internal error"); 04618 } 04619 04620 // If the shrunk BD_Shape is empty, its preimage is empty too; ... 04621 if (is_empty()) 04622 return; 04623 // Existentially quantify all variables in the lhs. 04624 for (dimension_type i = lhs_vars.size(); i-- > 0; ) 04625 forget_all_dbm_constraints(lhs_vars[i].id() + 1); 04626 } 04627 else { 04628 04629 // Some variables in `lhs' also occur in `rhs'. 04630 // To ease the computation, we add an additional dimension. 04631 const Variable new_var = Variable(bds_space_dim); 04632 add_space_dimensions_and_embed(1); 04633 // Constrain the new dimension to be equal to `lhs'. 04634 // NOTE: calling affine_image() instead of refine_no_check() 04635 // ensures some approximation is tried even when the constraint 04636 // is not a bounded difference. 04637 affine_image(new_var, lhs); 04638 // Existentiallly quantify all variables in the lhs. 04639 // NOTE: enforce shortest-path closure for precision. 04640 shortest_path_closure_assign(); 04641 assert(!marked_empty()); 04642 for (dimension_type i = lhs_vars.size(); i-- > 0; ) 04643 forget_all_dbm_constraints(lhs_vars[i].id() + 1); 04644 // Constrain the new dimension so that it is related to 04645 // the left hand side as dictated by `relsym'. 04646 // Note: if `rhs == a_rhs*v + b_rhs' where `a_rhs' is in {0, 1}, 04647 // then one of the following constraints will be added, 04648 // since it is a bounded difference. Else the method 04649 // refine_no_check() will ignore it, because the 04650 // constraint is NOT a bounded difference. 04651 switch (relsym) { 04652 case LESS_OR_EQUAL: 04653 refine_no_check(new_var <= rhs); 04654 break; 04655 case EQUAL: 04656 refine_no_check(new_var == rhs); 04657 break; 04658 case GREATER_OR_EQUAL: 04659 refine_no_check(new_var >= rhs); 04660 break; 04661 default: 04662 // We already dealt with the other cases. 04663 throw std::runtime_error("PPL internal error"); 04664 } 04665 // Remove the temporarily added dimension. 04666 remove_higher_space_dimensions(bds_space_dim); 04667 } 04668 } 04669 04670 assert(OK()); 04671 }
| void Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image | ( | Variable | var, | |
| const Linear_Expression & | lb_expr, | |||
| const Linear_Expression & | ub_expr, | |||
| Coefficient_traits::const_reference | denominator = Coefficient_one() | |||
| ) | [inline] |
Assigns to *this the image of *this with respect to the bounded affine relation
.
| var | The variable updated by the affine relation; | |
| lb_expr | The numerator of the lower bounding affine expression; | |
| ub_expr | The numerator of the upper bounding affine expression; | |
| denominator | The (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1). |
| std::invalid_argument | Thrown if denominator is zero or if lb_expr (resp., ub_expr) and *this are dimension-incompatible or if var is not a space dimension of *this. |
Definition at line 3542 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::deduce_v_minus_u_bounds(), Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::GREATER_OR_EQUAL, Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
03545 { 03546 // The denominator cannot be zero. 03547 if (denominator == 0) 03548 throw_generic("bounded_affine_image(v, lb, ub, d)", "d == 0"); 03549 03550 // Dimension-compatibility checks. 03551 // `var' should be one of the dimensions of the BD_Shape. 03552 const dimension_type bds_space_dim = space_dimension(); 03553 const dimension_type v = var.id() + 1; 03554 if (v > bds_space_dim) 03555 throw_dimension_incompatible("bounded_affine_image(v, lb, ub, d)", 03556 "v", var); 03557 // The dimension of `lb_expr' and `ub_expr' should not be 03558 // greater than the dimension of `*this'. 03559 const dimension_type lb_space_dim = lb_expr.space_dimension(); 03560 if (bds_space_dim < lb_space_dim) 03561 throw_dimension_incompatible("bounded_affine_image(v, lb, ub)", 03562 "lb", lb_expr); 03563 const dimension_type ub_space_dim = ub_expr.space_dimension(); 03564 if (bds_space_dim < ub_space_dim) 03565 throw_dimension_incompatible("bounded_affine_image(v, lb, ub)", 03566 "ub", ub_expr); 03567 03568 // Any image of an empty BDS is empty. 03569 shortest_path_closure_assign(); 03570 if (marked_empty()) 03571 return; 03572 03573 const Coefficient& b = ub_expr.inhomogeneous_term(); 03574 // Number of non-zero coefficients in `ub_expr': will be set to 03575 // 0, 1, or 2, the latter value meaning any value greater than 1. 03576 dimension_type t = 0; 03577 // Index of the last non-zero coefficient in `ub_expr', if any. 03578 dimension_type w = 0; 03579 // Get information about the number of non-zero coefficients in `expr'. 03580 for (dimension_type i = ub_space_dim; i-- > 0; ) 03581 if (ub_expr.coefficient(Variable(i)) != 0) { 03582 if (t++ == 1) 03583 break; 03584 else 03585 w = i+1; 03586 } 03587 03588 // Now we know the form of `ub_expr': 03589 // - If t == 0, then ub_expr == b, with `b' a constant; 03590 // - If t == 1, then ub_expr == a*w + b, where `w' can be `v' or another 03591 // variable; in this second case we have to check whether `a' is 03592 // equal to `denominator' or `-denominator', since otherwise we have 03593 // to fall back on the general form; 03594 // - If t == 2, the `ub_expr' is of the general form. 03595 TEMP_INTEGER(minus_den); 03596 neg_assign(minus_den, denominator); 03597 03598 if (t == 0) { 03599 // Case 1: ub_expr == b. 03600 generalized_affine_image(var, 03601 GREATER_OR_EQUAL, 03602 lb_expr, 03603 denominator); 03604 // Add the constraint `var <= b/denominator'. 03605 add_dbm_constraint(0, v, b, denominator); 03606 assert(OK()); 03607 return; 03608 } 03609 03610 if (t == 1) { 03611 // Value of the one and only non-zero coefficient in `ub_expr'. 03612 const Coefficient& a = ub_expr.coefficient(Variable(w-1)); 03613 if (a == denominator || a == minus_den) { 03614 // Case 2: expr == a*w + b, with a == +/- denominator. 03615 if (w == v) { 03616 // Here `var' occurs in `ub_expr'. 03617 // To ease the computation, we add an additional dimension. 03618 const Variable new_var = Variable(bds_space_dim); 03619 add_space_dimensions_and_embed(1); 03620 // Constrain the new dimension to be equal to `ub_expr'. 03621 affine_image(new_var, ub_expr, denominator); 03622 // NOTE: enforce shortest-path closure for precision. 03623 shortest_path_closure_assign(); 03624 assert(!marked_empty()); 03625 // Apply the affine lower bound. 03626 generalized_affine_image(var, 03627 GREATER_OR_EQUAL, 03628 lb_expr, 03629 denominator); 03630 // Now apply the affine upper bound, as recorded in `new_var'. 03631 add_constraint(var <= new_var); 03632 // Remove the temporarily added dimension. 03633 remove_higher_space_dimensions(bds_space_dim); 03634 return; 03635 } 03636 else { 03637 // Here `w != v', so that `expr' is of the form 03638 // +/-denominator * w + b. 03639 // Apply the affine lower bound. 03640 generalized_affine_image(var, 03641 GREATER_OR_EQUAL, 03642 lb_expr, 03643 denominator); 03644 if (a == denominator) { 03645 // Add the new constraint `v - w == b/denominator'. 03646 add_dbm_constraint(w, v, b, denominator); 03647 } 03648 else { 03649 // Here a == -denominator, so that we should be adding 03650 // the constraint `v + w == b/denominator'. 03651 // Approximate it by computing lower and upper bounds for `w'. 03652 const N& dbm_w0 = dbm[w][0]; 03653 if (!is_plus_infinity(dbm_w0)) { 03654 // Add the constraint `v <= b/denominator - lower_w'. 03655 DIRTY_TEMP(N, d); 03656 div_round_up(d, b, denominator); 03657 add_assign_r(dbm[0][v], d, dbm_w0, ROUND_UP); 03658 reset_shortest_path_closed(); 03659 } 03660 } 03661 assert(OK()); 03662 return; 03663 } 03664 } 03665 } 03666 03667 // General case. 03668 // Either t == 2, so that 03669 // ub_expr == a_1*x_1 + a_2*x_2 + ... + a_n*x_n + b, where n >= 2, 03670 // or t == 1, ub_expr == a*w + b, but a <> +/- denominator. 03671 // We will remove all the constraints on `var' and add back 03672 // constraints providing upper and lower bounds for `var'. 03673 03674 // Compute upper approximations for `ub_expr' into `pos_sum' 03675 // taking into account the sign of `denominator'. 03676 const bool is_sc = (denominator > 0); 03677 TEMP_INTEGER(minus_b); 03678 neg_assign(minus_b, b); 03679 const Coefficient& sc_b = is_sc ? b : minus_b; 03680 const Coefficient& sc_den = is_sc ? denominator : minus_den; 03681 const Coefficient& minus_sc_den = is_sc ? minus_den : denominator; 03682 // NOTE: here, for optimization purposes, `minus_expr' is only assigned 03683 // when `denominator' is negative. Do not use it unless you are sure 03684 // it has been correctly assigned. 03685 Linear_Expression minus_expr; 03686 if (!is_sc) 03687 minus_expr = -ub_expr; 03688 const Linear_Expression& sc_expr = is_sc ? ub_expr : minus_expr; 03689 03690 DIRTY_TEMP(N, pos_sum); 03691 // Index of the variable that are unbounded in `this->dbm'. 03692 PPL_UNINITIALIZED(dimension_type, pos_pinf_index); 03693 // Number of unbounded variables found. 03694 dimension_type pos_pinf_count = 0; 03695 03696 // Approximate the inhomogeneous term. 03697 assign_r(pos_sum, sc_b, ROUND_UP); 03698 03699 // Approximate the homogeneous part of `sc_expr'. 03700 const DB_Row<N>& dbm_0 = dbm[0]; 03701 // Speculative allocation of temporaries to be used in the following loop. 03702 DIRTY_TEMP(N, coeff_i); 03703 TEMP_INTEGER(minus_sc_i); 03704 // Note: indices above `w' can be disregarded, as they all have 03705 // a zero coefficient in `sc_expr'. 03706 for (dimension_type i = w; i > 0; --i) { 03707 const Coefficient& sc_i = sc_expr.coefficient(Variable(i-1)); 03708 const int sign_i = sgn(sc_i); 03709 if (sign_i > 0) { 03710 assign_r(coeff_i, sc_i, ROUND_UP); 03711 // Approximating `sc_expr'. 03712 if (pos_pinf_count <= 1) { 03713 const N& up_approx_i = dbm_0[i]; 03714 if (!is_plus_infinity(up_approx_i)) 03715 add_mul_assign_r(pos_sum, coeff_i, up_approx_i, ROUND_UP); 03716 else { 03717 ++pos_pinf_count; 03718 pos_pinf_index = i; 03719 } 03720 } 03721 } 03722 else if (sign_i < 0) { 03723 neg_assign(minus_sc_i, sc_i); 03724 // Note: using temporary named `coeff_i' to store -coeff_i. 03725 assign_r(coeff_i, minus_sc_i, ROUND_UP); 03726 // Approximating `sc_expr'. 03727 if (pos_pinf_count <= 1) { 03728 const N& up_approx_minus_i = dbm[i][0]; 03729 if (!is_plus_infinity(up_approx_minus_i)) 03730 add_mul_assign_r(pos_sum, coeff_i, up_approx_minus_i, ROUND_UP); 03731 else { 03732 ++pos_pinf_count; 03733 pos_pinf_index = i; 03734 } 03735 } 03736 } 03737 } 03738 // Apply the affine lower bound. 03739 generalized_affine_image(var, 03740 GREATER_OR_EQUAL, 03741 lb_expr, 03742 denominator); 03743 // Return immediately if no approximation could be computed. 03744 if (pos_pinf_count > 1) { 03745 return; 03746 } 03747 03748 // In the following, shortest-path closure will be definitely lost. 03749 reset_shortest_path_closed(); 03750 03751 // Exploit the upper approximation, if possible. 03752 if (pos_pinf_count <= 1) { 03753 // Compute quotient (if needed). 03754 if (sc_den != 1) { 03755 // Before computing quotients, the denominator should be approximated 03756 // towards zero. Since `sc_den' is known to be positive, this amounts to 03757 // rounding downwards, which is achieved as usual by rounding upwards 03758 // `minus_sc_den' and negating again the result. 03759 DIRTY_TEMP(N, down_sc_den); 03760 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 03761 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 03762 div_assign_r(pos_sum, pos_sum, down_sc_den, ROUND_UP); 03763 } 03764 // Add the upper bound constraint, if meaningful. 03765 if (pos_pinf_count == 0) { 03766 // Add the constraint `v <= pos_sum'. 03767 dbm[0][v] = pos_sum; 03768 // Deduce constraints of the form `v - u', where `u != v'. 03769 deduce_v_minus_u_bounds(v, w, sc_expr, sc_den, pos_sum); 03770 } 03771 else 03772 // Here `pos_pinf_count == 1'. 03773 if (pos_pinf_index != v 03774 && sc_expr.coefficient(Variable(pos_pinf_index-1)) == sc_den) 03775 // Add the constraint `v - pos_pinf_index <= pos_sum'. 03776 dbm[pos_pinf_index][v] = pos_sum; 03777 } 03778 assert(OK()); 03779 }
| void Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage | ( | Variable | var, | |
| const Linear_Expression & | lb_expr, | |||
| const Linear_Expression & | ub_expr, | |||
| Coefficient_traits::const_reference | denominator = Coefficient_one() | |||
| ) | [inline] |
Assigns to *this the preimage of *this with respect to the bounded affine relation
.
| var | The variable updated by the affine relation; | |
| lb_expr | The numerator of the lower bounding affine expression; | |
| ub_expr | The numerator of the upper bounding affine expression; | |
| denominator | The (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1). |
| std::invalid_argument | Thrown if denominator is zero or if lb_expr (resp., ub_expr) and *this are dimension-incompatible or if var is not a space dimension of *this. |
Definition at line 3784 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::GREATER_OR_EQUAL, Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::refine(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
03787 { 03788 // The denominator cannot be zero. 03789 if (denominator == 0) 03790 throw_generic("bounded_affine_preimage(v, lb, ub, d)", "d == 0"); 03791 03792 // Dimension-compatibility checks. 03793 // `var' should be one of the dimensions of the BD_Shape. 03794 const dimension_type space_dim = space_dimension(); 03795 const dimension_type v = var.id() + 1; 03796 if (v > space_dim) 03797 throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub, d)", 03798 "v", var); 03799 // The dimension of `lb_expr' and `ub_expr' should not be 03800 // greater than the dimension of `*this'. 03801 const dimension_type lb_space_dim = lb_expr.space_dimension(); 03802 if (space_dim < lb_space_dim) 03803 throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub)", 03804 "lb", lb_expr); 03805 const dimension_type ub_space_dim = ub_expr.space_dimension(); 03806 if (space_dim < ub_space_dim) 03807 throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub)", 03808 "ub", ub_expr); 03809 03810 // Any preimage of an empty BDS is empty. 03811 shortest_path_closure_assign(); 03812 if (marked_empty()) 03813 return; 03814 03815 if (ub_expr.coefficient(var) == 0) { 03816 refine(var, LESS_OR_EQUAL, ub_expr, denominator); 03817 generalized_affine_preimage(var, GREATER_OR_EQUAL, 03818 lb_expr, denominator); 03819 return; 03820 } 03821 if (lb_expr.coefficient(var) == 0) { 03822 refine(var, GREATER_OR_EQUAL, lb_expr, denominator); 03823 generalized_affine_preimage(var, LESS_OR_EQUAL, 03824 ub_expr, denominator); 03825 return; 03826 } 03827 03828 const Coefficient& lb_expr_v = lb_expr.coefficient(var); 03829 // Here `var' occurs in `lb_expr' and `ub_expr'. 03830 // To ease the computation, we add an additional dimension. 03831 const Variable new_var = Variable(space_dim); 03832 add_space_dimensions_and_embed(1); 03833 const Linear_Expression lb_inverse 03834 = lb_expr - (lb_expr_v + denominator)*var; 03835 TEMP_INTEGER(lb_inverse_den); 03836 neg_assign(lb_inverse_den, lb_expr_v); 03837 affine_image(new_var, lb_inverse, lb_inverse_den); 03838 shortest_path_closure_assign(); 03839 assert(!marked_empty()); 03840 generalized_affine_preimage(var, LESS_OR_EQUAL, 03841 ub_expr, denominator); 03842 if (sgn(denominator) == sgn(lb_inverse_den)) 03843 add_constraint(var >= new_var); 03844 else 03845 add_constraint(var <= new_var); 03846 // Remove the temporarily added dimension. 03847 remove_higher_space_dimensions(space_dim); 03848 }
| void Parma_Polyhedra_Library::BD_Shape< T >::time_elapse_assign | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the result of computing the time-elapse between *this and y.
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 728 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::swap(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::Polyhedron::time_elapse_assign().
00728 { 00729 // Dimension-compatibility check. 00730 if (space_dimension() != y.space_dimension()) 00731 throw_dimension_incompatible("time_elapse_assign(y)", y); 00732 // See the polyhedra documentation. 00733 C_Polyhedron px(constraints()); 00734 C_Polyhedron py(y.constraints()); 00735 px.time_elapse_assign(py); 00736 BD_Shape<T> x(px); 00737 swap(x); 00738 assert(OK()); 00739 }
| void Parma_Polyhedra_Library::BD_Shape< T >::topological_closure_assign | ( | ) | [inline] |
| void Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign | ( | const BD_Shape< T > & | y, | |
| unsigned * | tp = 0 | |||
| ) | [inline] |
Assigns to *this the result of computing the CC76-extrapolation between *this and y.
| y | A BDS that must be contained in *this. | |
| tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 808 of file BD_Shape.inlines.hh.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign().
00808 { 00809 static N stop_points[] = { 00810 N(-2, ROUND_UP), 00811 N(-1, ROUND_UP), 00812 N( 0, ROUND_UP), 00813 N( 1, ROUND_UP), 00814 N( 2, ROUND_UP) 00815 }; 00816 CC76_extrapolation_assign(y, 00817 stop_points, 00818 stop_points 00819 + sizeof(stop_points)/sizeof(stop_points[0]), 00820 tp); 00821 }
| void Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign | ( | const BD_Shape< T > & | y, | |
| Iterator | first, | |||
| Iterator | last, | |||
| unsigned * | tp = 0 | |||
| ) | [inline] |
Assigns to *this the result of computing the CC76-extrapolation between *this and y.
| y | A BDS that must be contained in *this. | |
| first | An iterator referencing the first stop-point. | |
| last | An iterator referencing one past the last stop-point. | |
| tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 2167 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), PLUS_INFINITY, Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
02169 { 02170 const dimension_type space_dim = space_dimension(); 02171 02172 // Dimension-compatibility check. 02173 if (space_dim != y.space_dimension()) 02174 throw_dimension_incompatible("CC76_extrapolation_assign(y)", y); 02175 02176 #ifndef NDEBUG 02177 { 02178 // We assume that `y' is contained in or equal to `*this'. 02179 const BD_Shape x_copy = *this; 02180 const BD_Shape y_copy = y; 02181 assert(x_copy.contains(y_copy)); 02182 } 02183 #endif 02184 02185 // If both bounded difference shapes are zero-dimensional, 02186 // since `*this' contains `y', we simply return `*this'. 02187 if (space_dim == 0) 02188 return; 02189 02190 shortest_path_closure_assign(); 02191 // If `*this' is empty, since `*this' contains `y', `y' is empty too. 02192 if (marked_empty()) 02193 return; 02194 y.shortest_path_closure_assign(); 02195 // If `y' is empty, we return. 02196 if (y.marked_empty()) 02197 return; 02198 02199 // If there are tokens available, work on a temporary copy. 02200 if (tp != 0 && *tp > 0) { 02201 BD_Shape<T> x_tmp(*this); 02202 x_tmp.CC76_extrapolation_assign(y, first, last, 0); 02203 // If the widening was not precise, use one of the available tokens. 02204 if (!contains(x_tmp)) 02205 --(*tp); 02206 return; 02207 } 02208 02209 // Compare each constraint in `y' to the corresponding one in `*this'. 02210 // The constraint in `*this' is kept as is if it is stronger than or 02211 // equal to the constraint in `y'; otherwise, the inhomogeneous term 02212 // of the constraint in `*this' is further compared with elements taken 02213 // from a sorted container (the stop-points, provided by the user), and 02214 // is replaced by the first entry, if any, which is greater than or equal 02215 // to the inhomogeneous term. If no such entry exists, the constraint 02216 // is removed altogether. 02217 for (dimension_type i = space_dim + 1; i-- > 0; ) { 02218 DB_Row<N>& dbm_i = dbm[i]; 02219 const DB_Row<N>& y_dbm_i = y.dbm[i]; 02220 for (dimension_type j = space_dim + 1; j-- > 0; ) { 02221 N& dbm_ij = dbm_i[j]; 02222 const N& y_dbm_ij = y_dbm_i[j]; 02223 if (y_dbm_ij < dbm_ij) { 02224 Iterator k = std::lower_bound(first, last, dbm_ij); 02225 if (k != last) { 02226 if (dbm_ij < *k) 02227 assign_r(dbm_ij, *k, ROUND_UP); 02228 } 02229 else 02230 assign_r(dbm_ij, PLUS_INFINITY, ROUND_NOT_NEEDED); 02231 } 02232 } 02233 } 02234 reset_shortest_path_closed(); 02235 assert(OK()); 02236 }
| void Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign | ( | const BD_Shape< T > & | y, | |
| unsigned * | tp = 0 | |||
| ) | [inline] |
Assigns to *this the result of computing the BHMZ05-widening of *this and y.
| y | A BDS that must be contained in *this. | |
| tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 2353 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::affine_dimension(), Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), PLUS_INFINITY, Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign().
02353 { 02354 const dimension_type space_dim = space_dimension(); 02355 02356 // Dimension-compatibility check. 02357 if (space_dim != y.space_dimension()) 02358 throw_dimension_incompatible("BHMZ05_widening_assign(y)", y); 02359 02360 #ifndef NDEBUG 02361 { 02362 // We assume that `y' is contained in or equal to `*this'. 02363 const BD_Shape x_copy = *this; 02364 const BD_Shape y_copy = y; 02365 assert(x_copy.contains(y_copy)); 02366 } 02367 #endif 02368 02369 // Compute the affine dimension of `y'. 02370 const dimension_type y_affine_dim = y.affine_dimension(); 02371 // If the affine dimension of `y' is zero, then either `y' is 02372 // zero-dimensional, or it is empty, or it is a singleton. 02373 // In all cases, due to the inclusion hypothesis, the result is `*this'. 02374 if (y_affine_dim == 0) 02375 return; 02376 02377 // If the affine dimension has changed, due to the inclusion hypothesis, 02378 // the result is `*this'. 02379 const dimension_type x_affine_dim = affine_dimension(); 02380 assert(x_affine_dim >= y_affine_dim); 02381 if (x_affine_dim != y_affine_dim) 02382 return; 02383 02384 // If there are tokens available, work on a temporary copy. 02385 if (tp != 0 && *tp > 0) { 02386 BD_Shape<T> x_tmp(*this); 02387 x_tmp.BHMZ05_widening_assign(y, 0); 02388 // If the widening was not precise, use one of the available tokens. 02389 if (!contains(x_tmp)) 02390 --(*tp); 02391 return; 02392 } 02393 02394 // Here no token is available. 02395 assert(marked_shortest_path_closed() && y.marked_shortest_path_closed()); 02396 // Minimize `y'. 02397 y.shortest_path_reduction_assign(); 02398 02399 // Extrapolate unstable bounds, taking into account redundancy in `y'. 02400 for (dimension_type i = space_dim + 1; i-- > 0; ) { 02401 DB_Row<N>& dbm_i = dbm[i]; 02402 const DB_Row<N>& y_dbm_i = y.dbm[i]; 02403 const Bit_Row& y_redundancy_i = y.redundancy_dbm[i]; 02404 for (dimension_type j = space_dim + 1; j-- > 0; ) { 02405 N& dbm_ij = dbm_i[j]; 02406 // Note: in the following line the use of `!=' (as opposed to 02407 // the use of `<' that would seem -but is not- equivalent) is 02408 // intentional. 02409 if (y_redundancy_i[j] || y_dbm_i[j] != dbm_ij) 02410 assign_r(dbm_ij, PLUS_INFINITY, ROUND_NOT_NEEDED); 02411 } 02412 } 02413 // NOTE: this will also reset the shortest-path reduction flag, 02414 // even though the dbm is still in reduced form. However, the 02415 // current implementation invariant requires that any reduced dbm 02416 // is closed too. 02417 reset_shortest_path_closed(); 02418 assert(OK()); 02419 }
| void Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign | ( | const BD_Shape< T > & | y, | |
| const Constraint_System & | cs, | |||
| unsigned * | tp = 0 | |||
| ) | [inline] |
Improves the result of the BHMZ05-widening computation by also enforcing those constraints in cs that are satisfied by all the points of *this.
| y | A BDS that must be contained in *this. | |
| cs | The system of constraints used to improve the widened BDS. | |
| tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
| std::invalid_argument | Thrown if *this, y and cs are dimension-incompatible or if cs contains a strict inequality. |
Definition at line 2423 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::Constraint_System::has_strict_inequalities(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), Parma_Polyhedra_Library::BD_Shape< T >::throw_generic(), and Parma_Polyhedra_Library::UNIVERSE.
02425 { 02426 // Dimension-compatibility check. 02427 const dimension_type space_dim = space_dimension(); 02428 if (space_dim != y.space_dimension()) 02429 throw_dimension_incompatible("limited_BHMZ05_extrapolation_assign(y, cs)", 02430 y); 02431 // `cs' must be dimension-compatible with the two systems 02432 // of bounded differences. 02433 const dimension_type cs_space_dim = cs.space_dimension(); 02434 if (space_dim < cs_space_dim) 02435 throw_generic("limited_BHMZ05_extrapolation_assign(y, cs)", 02436 "cs is space-dimension incompatible"); 02437 02438 // Strict inequalities are not allowed. 02439 if (cs.has_strict_inequalities()) 02440 throw_generic("limited_BHMZ05_extrapolation_assign(y, cs)", 02441 "cs has strict inequalities"); 02442 02443 // The limited BHMZ05-extrapolation between two systems of bounded 02444 // differences in a zero-dimensional space is a system of bounded 02445 // differences in a zero-dimensional space, too. 02446 if (space_dim == 0) 02447 return; 02448 02449 #ifndef NDEBUG 02450 { 02451 // We assume that `y' is contained in or equal to `*this'. 02452 const BD_Shape x_copy = *this; 02453 const BD_Shape y_copy = y; 02454 assert(x_copy.contains(y_copy)); 02455 } 02456 #endif 02457 02458 // If `*this' is empty, since `*this' contains `y', `y' is empty too. 02459 if (marked_empty()) 02460 return; 02461 // If `y' is empty, we return. 02462 if (y.marked_empty()) 02463 return; 02464 02465 BD_Shape<T> limiting_shape(space_dim, UNIVERSE); 02466 get_limiting_shape(cs, limiting_shape); 02467 BHMZ05_widening_assign(y, tp); 02468 intersection_assign(limiting_shape); 02469 }
| void Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the result of restoring in y the constraints of *this that were lost by CC76-extrapolation applications.
| y | A BDS that must contain *this. |
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
y is meant to denote the value computed in the previous iteration step, whereas *this denotes the value computed in the current iteration step (in the decreasing iteration sequence). Hence, the call x.CC76_narrowing_assign(y) will assign to x the result of the computation
. Definition at line 2473 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
02473 { 02474 const dimension_type space_dim = space_dimension(); 02475 02476 // Dimension-compatibility check. 02477 if (space_dim != y.space_dimension()) 02478 throw_dimension_incompatible("CC76_narrowing_assign(y)", y); 02479 02480 #ifndef NDEBUG 02481 { 02482 // We assume that `*this' is contained in or equal to `y'. 02483 const BD_Shape x_copy = *this; 02484 const BD_Shape y_copy = y; 02485 assert(y_copy.contains(x_copy)); 02486 } 02487 #endif 02488 02489 // If both bounded difference shapes are zero-dimensional, 02490 // since `y' contains `*this', we simply return `*this'. 02491 if (space_dim == 0) 02492 return; 02493 02494 y.shortest_path_closure_assign(); 02495 // If `y' is empty, since `y' contains `this', `*this' is empty too. 02496 if (y.marked_empty()) 02497 return; 02498 shortest_path_closure_assign(); 02499 // If `*this' is empty, we return. 02500 if (marked_empty()) 02501 return; 02502 02503 // Replace each constraint in `*this' by the corresponding constraint 02504 // in `y' if the corresponding inhomogeneous terms are both finite. 02505 bool changed = false; 02506 for (dimension_type i = space_dim + 1; i-- > 0; ) { 02507 DB_Row<N>& dbm_i = dbm[i]; 02508 const DB_Row<N>& y_dbm_i = y.dbm[i]; 02509 for (dimension_type j = space_dim + 1; j-- > 0; ) { 02510 N& dbm_ij = dbm_i[j]; 02511 const N& y_dbm_ij = y_dbm_i[j]; 02512 if (!is_plus_infinity(dbm_ij) 02513 && !is_plus_infinity(y_dbm_ij) 02514 && dbm_ij != y_dbm_ij) { 02515 dbm_ij = y_dbm_ij; 02516 changed = true; 02517 } 02518 } 02519 } 02520 if (changed && marked_shortest_path_closed()) 02521 reset_shortest_path_closed(); 02522 assert(OK()); 02523 }
| void Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign | ( | const BD_Shape< T > & | y, | |
| const Constraint_System & | cs, | |||
| unsigned * | tp = 0 | |||
| ) | [inline] |
Improves the result of the CC76-extrapolation computation by also enforcing those constraints in cs that are satisfied by all the points of *this.
| y | A BDS that must be contained in *this. | |
| cs | The system of constraints used to improve the widened BDS. | |
| tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
| std::invalid_argument | Thrown if *this, y and cs are dimension-incompatible or if cs contains a strict inequality. |
Definition at line 2302 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::Constraint_System::has_strict_inequalities(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), Parma_Polyhedra_Library::BD_Shape< T >::throw_generic(), and Parma_Polyhedra_Library::UNIVERSE.
02304 { 02305 // Dimension-compatibility check. 02306 const dimension_type space_dim = space_dimension(); 02307 if (space_dim != y.space_dimension()) 02308 throw_dimension_incompatible("limited_CC76_extrapolation_assign(y, cs)", 02309 y); 02310 02311 // `cs' must be dimension-compatible with the two systems 02312 // of bounded differences. 02313 const dimension_type cs_space_dim = cs.space_dimension(); 02314 if (space_dim < cs_space_dim) 02315 throw_generic("limited_CC76_extrapolation_assign(y, cs)", 02316 "cs is space_dimension incompatible"); 02317 02318 // Strict inequalities not allowed. 02319 if (cs.has_strict_inequalities()) 02320 throw_generic("limited_CC76_extrapolation_assign(y, cs)", 02321 "cs has strict inequalities"); 02322 02323 // The limited CC76-extrapolation between two systems of bounded 02324 // differences in a zero-dimensional space is a system of bounded 02325 // differences in a zero-dimensional space, too. 02326 if (space_dim == 0) 02327 return; 02328 02329 #ifndef NDEBUG 02330 { 02331 // We assume that `y' is contained in or equal to `*this'. 02332 const BD_Shape x_copy = *this; 02333 const BD_Shape y_copy = y; 02334 assert(x_copy.contains(y_copy)); 02335 } 02336 #endif 02337 02338 // If `*this' is empty, since `*this' contains `y', `y' is empty too. 02339 if (marked_empty()) 02340 return; 02341 // If `y' is empty, we return. 02342 if (y.marked_empty()) 02343 return; 02344 02345 BD_Shape<T> limiting_shape(space_dim, UNIVERSE); 02346 get_limiting_shape(cs, limiting_shape); 02347 CC76_extrapolation_assign(y, tp); 02348 intersection_assign(limiting_shape); 02349 }
| void Parma_Polyhedra_Library::BD_Shape< T >::H79_widening_assign | ( | const BD_Shape< T > & | y, | |
| unsigned * | tp = 0 | |||
| ) | [inline] |
Assigns to *this the result of computing the H79-widening between *this and y.
| y | A BDS that must be contained in *this. | |
| tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
| std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 825 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::Polyhedron::H79_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), and Parma_Polyhedra_Library::BD_Shape< T >::swap().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::widening_assign().
00825 { 00826 // See the documentation for polyhedra. 00827 C_Polyhedron px(constraints()); 00828 C_Polyhedron py(y.constraints()); 00829 px.H79_widening_assign(py, tp); 00830 BD_Shape x(px); 00831 swap(x); 00832 assert(OK()); 00833 }
| void Parma_Polyhedra_Library::BD_Shape< T >::widening_assign | ( | const BD_Shape< T > & | y, | |
| unsigned * | tp = 0 | |||
| ) | [inline] |
Same as H79_widening_assign(y, tp).
Definition at line 837 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::H79_widening_assign().
00837 { 00838 H79_widening_assign(y, tp); 00839 }
| void Parma_Polyhedra_Library::BD_Shape< T >::limited_H79_extrapolation_assign | ( | const BD_Shape< T > & | y, | |
| const Constraint_System & | cs, | |||
| unsigned * | tp = 0 | |||
| ) | [inline] |
Improves the result of the H79-widening computation by also enforcing those constraints in cs that are satisfied by all the points of *this.
| y | A BDS that must be contained in *this. | |
| cs | The system of constraints used to improve the widened BDS. | |
| tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
| std::invalid_argument | Thrown if *this, y and cs are dimension-incompatible. |
Definition at line 843 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::Polyhedron::limited_H79_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), and Parma_Polyhedra_Library::BD_Shape< T >::swap().
00845 { 00846 // See the documentation for polyhedra. 00847 C_Polyhedron px(constraints()); 00848 C_Polyhedron py(y.constraints()); 00849 px.limited_H79_extrapolation_assign(py, cs, tp); 00850 BD_Shape x(px); 00851 swap(x); 00852 assert(OK()); 00853 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed | ( | dimension_type | m | ) | [inline] |
Adds m new dimensions and embeds the old BDS into the new space.
| m | The number of dimensions to add. |
and adding a third dimension, the result will be the BDS
Definition at line 1893 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), and Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage().
01893 { 01894 // Adding no dimensions is a no-op. 01895 if (m == 0) 01896 return; 01897 01898 const dimension_type space_dim = space_dimension(); 01899 const dimension_type new_space_dim = space_dim + m; 01900 const bool was_zero_dim_univ = (!marked_empty() && space_dim == 0); 01901 01902 // To embed an n-dimension space BDS in a (n+m)-dimension space, 01903 // we just add `m' rows and columns in the bounded difference shape, 01904 // initialized to PLUS_INFINITY. 01905 dbm.grow(new_space_dim + 1); 01906 01907 // Shortest-path closure is maintained (if it was holding). 01908 // TODO: see whether reduction can be (efficiently!) maintained too. 01909 if (marked_shortest_path_reduced()) 01910 reset_shortest_path_reduced(); 01911 01912 // If `*this' was the zero-dim space universe BDS, 01913 // the we can set the shortest-path closure flag. 01914 if (was_zero_dim_univ) 01915 set_shortest_path_closed(); 01916 01917 assert(OK()); 01918 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project | ( | dimension_type | m | ) | [inline] |
Adds m new dimensions to the BDS and does not embed it in the new vector space.
| m | The number of dimensions to add. |
and adding a third dimension, the result will be the BDS
Definition at line 1922 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
01922 { 01923 // Adding no dimensions is a no-op. 01924 if (m == 0) 01925 return; 01926 01927 const dimension_type space_dim = space_dimension(); 01928 01929 // If `*this' was zero-dimensional, then we add `m' rows and columns. 01930 // If it also was non-empty, then we zero all the added elements 01931 // and set the flag for shortest-path closure. 01932 if (space_dim == 0) { 01933 dbm.grow(m + 1); 01934 if (!marked_empty()) { 01935 for (dimension_type i = m + 1; i-- > 0; ) { 01936 DB_Row<N>& dbm_i = dbm[i]; 01937 for (dimension_type j = m + 1; j-- > 0; ) 01938 if (i != j) 01939 assign_r(dbm_i[j], 0, ROUND_NOT_NEEDED); 01940 } 01941 set_shortest_path_closed(); 01942 } 01943 assert(OK()); 01944 return; 01945 } 01946 01947 // To project an n-dimension space bounded difference shape 01948 // in a (n+m)-dimension space, we add `m' rows and columns. 01949 // In the first row and column of the matrix we add `zero' from 01950 // the (n+1)-th position to the end. 01951 const dimension_type new_space_dim = space_dim + m; 01952 dbm.grow(new_space_dim + 1); 01953 01954 // Bottom of the matrix and first row. 01955 DB_Row<N>& dbm_0 = dbm[0]; 01956 for (dimension_type i = space_dim + 1; i <= new_space_dim; ++i) { 01957 assign_r(dbm[i][0], 0, ROUND_NOT_NEEDED); 01958 assign_r(dbm_0[i], 0, ROUND_NOT_NEEDED); 01959 } 01960 01961 if (marked_shortest_path_closed()) 01962 reset_shortest_path_closed(); 01963 assert(OK()); 01964 }
| void Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign | ( | const BD_Shape< T > & | y | ) | [inline] |
Assigns to *this the concatenation of *this and y, taken in this order.
| std::length_error | Thrown if the concatenation would cause the vector space to exceed dimension max_space_dimension(). |
Definition at line 533 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00533 { 00534 BD_Shape& x = *this; 00535 00536 const dimension_type x_space_dim = x.space_dimension(); 00537 const dimension_type y_space_dim = y.space_dimension(); 00538 00539 // If `y' is an empty 0-dim space bounded difference shape, 00540 // let `*this' become empty. 00541 if (y_space_dim == 0 && y.marked_empty()) { 00542 set_empty(); 00543 return; 00544 } 00545 00546 // If `x' is an empty 0-dim space BDS, then it is sufficient to adjust 00547 // the dimension of the vector space. 00548 if (x_space_dim == 0 && marked_empty()) { 00549 dbm.grow(y_space_dim + 1); 00550 assert(OK()); 00551 return; 00552 } 00553 // First we increase the space dimension of `x' by adding 00554 // `y.space_dimension()' new dimensions. 00555 // The matrix for the new system of constraints is obtained 00556 // by leaving the old system of constraints in the upper left-hand side 00557 // and placing the constraints of `y' in the lower right-hand side, 00558 // except the constraints as `y(i) >= cost' or `y(i) <= cost', that are 00559 // placed in the right position on the new matrix. 00560 add_space_dimensions_and_embed(y_space_dim); 00561 const dimension_type new_space_dim = x_space_dim + y_space_dim; 00562 for (dimension_type i = x_space_dim + 1; i <= new_space_dim; ++i) { 00563 DB_Row<N>& dbm_i = dbm[i]; 00564 dbm_i[0] = y.dbm[i - x_space_dim][0]; 00565 dbm[0][i] = y.dbm[0][i - x_space_dim]; 00566 for (dimension_type j = x_space_dim + 1; j <= new_space_dim; ++j) 00567 dbm_i[j] = y.dbm[i - x_space_dim][j - x_space_dim]; 00568 } 00569 00570 if (marked_shortest_path_closed()) 00571 reset_shortest_path_closed(); 00572 assert(OK()); 00573 }
| void Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions | ( | const Variables_Set & | to_be_removed | ) | [inline] |
Removes all the specified dimensions.
| to_be_removed | The set of Variable objects corresponding to the dimensions to be removed. |
| std::invalid_argument | Thrown if *this is dimension-incompatible with one of the Variable objects contained in to_be_removed. |
Definition at line 1968 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::set_zero_dim_univ(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::swap(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions().
01968 { 01969 // The removal of no dimensions from any BDS is a no-op. 01970 // Note that this case also captures the only legal removal of 01971 // space dimensions from a BDS in a 0-dim space. 01972 if (to_be_removed.empty()) { 01973 assert(OK()); 01974 return; 01975 } 01976 01977 const dimension_type old_space_dim = space_dimension(); 01978 01979 // Dimension-compatibility check. 01980 const dimension_type min_space_dim = to_be_removed.space_dimension(); 01981 if (old_space_dim < min_space_dim) 01982 throw_dimension_incompatible("remove_space_dimensions(vs)", min_space_dim); 01983 01984 // Shortest-path closure is necessary to keep precision. 01985 shortest_path_closure_assign(); 01986 01987 // When removing _all_ dimensions from a BDS, we obtain the 01988 // zero-dimensional BDS. 01989 const dimension_type new_space_dim = old_space_dim - to_be_removed.size(); 01990 if (new_space_dim == 0) { 01991 dbm.resize_no_copy(1); 01992 if (!marked_empty()) 01993 // We set the zero_dim_univ flag. 01994 set_zero_dim_univ(); 01995 assert(OK()); 01996 return; 01997 } 01998 01999 // Handle the case of an empty BD_Shape. 02000 if (marked_empty()) { 02001 dbm.resize_no_copy(new_space_dim + 1); 02002 assert(OK()); 02003 return; 02004 } 02005 02006 // Shortest-path closure is maintained. 02007 // TODO: see whether reduction can be (efficiently!) maintained too. 02008 if (marked_shortest_path_reduced()) 02009 reset_shortest_path_reduced(); 02010 02011 // For each variable to remove, we fill the corresponding column and 02012 // row by shifting respectively left and above those 02013 // columns and rows, that will not be removed. 02014 Variables_Set::const_iterator tbr = to_be_removed.begin(); 02015 Variables_Set::const_iterator tbr_end = to_be_removed.end(); 02016 dimension_type dst = *tbr + 1; 02017 dimension_type src = dst + 1; 02018 for (++tbr; tbr != tbr_end; ++tbr) { 02019 const dimension_type tbr_next = *tbr + 1; 02020 // All other columns and rows are moved respectively to the left 02021 // and above. 02022 while (src < tbr_next) { 02023 std::swap(dbm[dst], dbm[src]); 02024 for (dimension_type i = old_space_dim + 1; i-- > 0; ) { 02025 DB_Row<N>& dbm_i = dbm[i]; 02026 assign_or_swap(dbm_i[dst], dbm_i[src]); 02027 } 02028 ++dst; 02029 ++src; 02030 } 02031 ++src; 02032 } 02033 02034 // Moving the remaining rows and columns. 02035 while (src <= old_space_dim) { 02036 std::swap(dbm[dst], dbm[src]); 02037 for (dimension_type i = old_space_dim + 1; i-- > 0; ) { 02038 DB_Row<N>& dbm_i = dbm[i]; 02039 assign_or_swap(dbm_i[dst], dbm_i[src]); 02040 } 02041 ++src; 02042 ++dst; 02043 } 02044 02045 // Update the space dimension. 02046 dbm.resize_no_copy(new_space_dim + 1); 02047 assert(OK()); 02048 }
| void Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions | ( | dimension_type | new_dimension | ) | [inline] |
Removes the higher dimensions so that the resulting space will have dimension new_dimension.
| std::invalid_argument | Thrown if new_dimension is greater than the space dimension of *this. |
Definition at line 767 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::set_zero_dim_univ(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), and Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions().
00767 { 00768 // Dimension-compatibility check: the variable having 00769 // maximum index is the one occurring last in the set. 00770 if (new_dim > space_dimension()) 00771 throw_dimension_incompatible("remove_higher_space_dimensions(nd)", 00772 new_dim); 00773 00774 // The removal of no dimensions from any BDS is a no-op. 00775 // Note that this case also captures the only legal removal of 00776 // dimensions from a zero-dim space BDS. 00777 if (new_dim == space_dimension()) { 00778 assert(OK()); 00779 return; 00780 } 00781 00782 // Shortest-path closure is necessary as in remove_space_dimensions(). 00783 shortest_path_closure_assign(); 00784 dbm.resize_no_copy(new_dim + 1); 00785 00786 // Shortest-path closure is maintained. 00787 // TODO: see whether or not reduction can be (efficiently!) maintained too. 00788 if (marked_shortest_path_reduced()) 00789 reset_shortest_path_reduced(); 00790 00791 // If we removed _all_ dimensions from a non-empty BDS, 00792 // the zero-dim universe BDS has been obtained. 00793 if (new_dim == 0 && !marked_empty()) 00794 set_zero_dim_univ(); 00795 assert(OK()); 00796 }
| void Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions | ( | const Partial_Function & | pfunc | ) | [inline] |
Remaps the dimensions of the vector space according to a partial function.
| pfunc | The partial function specifying the destiny of each dimension. |
bool has_empty_codomain() const
true if and only if the represented partial function has an empty co-domain (i.e., it is always undefined). The has_empty_codomain() method will always be called before the methods below. However, if has_empty_codomain() returns true, none of the functions below will be called. dimension_type max_in_codomain() const
bool maps(dimension_type i, dimension_type& j) const
be the represented function and
be the value of i. If
is defined in
, then
is assigned to j and true is returned. If
is undefined in
, then false is returned.
The result is undefined if pfunc does not encode a partial function with the properties described in the specification of the mapping operator.
Definition at line 2053 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::swap().
02053 { 02054 const dimension_type space_dim = space_dimension(); 02055 // TODO: this implementation is just an executable specification. 02056 if (space_dim == 0) 02057 return; 02058 02059 if (pfunc.has_empty_codomain()) { 02060 // All dimensions vanish: the BDS becomes zero_dimensional. 02061 remove_higher_space_dimensions(0); 02062 return; 02063 } 02064 02065 const dimension_type new_space_dim = pfunc.max_in_codomain() + 1; 02066 // If we are going to actually reduce the space dimension, 02067 // then shortest-path closure is required to keep precision. 02068 if (new_space_dim < space_dim) 02069 shortest_path_closure_assign(); 02070 02071 // If the BDS is empty, then it is sufficient to adjust the 02072 // space dimension of the bounded difference shape. 02073 if (marked_empty()) { 02074 remove_higher_space_dimensions(new_space_dim); 02075 return; 02076 } 02077 02078 // Shortest-path closure is maintained (if it was holding). 02079 // TODO: see whether reduction can be (efficiently!) maintained too. 02080 if (marked_shortest_path_reduced()) 02081 reset_shortest_path_reduced(); 02082 02083 // We create a new matrix with the new space dimension. 02084 DB_Matrix<N> x(new_space_dim+1); 02085 // First of all we must map the unary constraints, because 02086 // there is the fictitious variable `zero', that can't be mapped 02087 // at all. 02088 DB_Row<N>& dbm_0 = dbm[0]; 02089 DB_Row<N>& x_0 = x[0]; 02090 for (dimension_type j = 1; j <= space_dim; ++j) { 02091 dimension_type new_j; 02092 if (pfunc.maps(j - 1, new_j)) { 02093 assign_or_swap(x_0[new_j + 1], dbm_0[j]); 02094 assign_or_swap(x[new_j + 1][0], dbm[j][0]); 02095 } 02096 } 02097 // Now we map the binary constraints, exchanging the indexes. 02098 for (dimension_type i = 1; i <= space_dim; ++i) { 02099 dimension_type new_i; 02100 if (pfunc.maps(i - 1, new_i)) { 02101 DB_Row<N>& dbm_i = dbm[i]; 02102 ++new_i; 02103 DB_Row<N>& x_new_i = x[new_i]; 02104 for (dimension_type j = i+1; j <= space_dim; ++j) { 02105 dimension_type new_j; 02106 if (pfunc.maps(j - 1, new_j)) { 02107 ++new_j; 02108 assign_or_swap(x_new_i[new_j], dbm_i[j]); 02109 assign_or_swap(x[new_j][new_i], dbm[j][i]); 02110 } 02111 } 02112 } 02113 } 02114 02115 std::swap(dbm, x); 02116 assert(OK()); 02117 }
| void Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension | ( | Variable | var, | |
| dimension_type | m | |||
| ) | [inline] |
Creates m copies of the space dimension corresponding to var.
| var | The variable corresponding to the space dimension to be replicated; | |
| m | The number of replicas to be created. |
| std::invalid_argument | Thrown if var does not correspond to a dimension of the vector space. | |
| std::length_error | Thrown if adding m new space dimensions would cause the vector space to exceed dimension max_space_dimension(). |
*this has space dimension
, with
, and var has space dimension
, then the
-th space dimension is expanded to m new space dimensions
,
,
,
.
Definition at line 4833 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::max_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::Variable::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
04833 { 04834 dimension_type old_dim = space_dimension(); 04835 // `var' should be one of the dimensions of the vector space. 04836 if (var.space_dimension() > old_dim) 04837 throw_dimension_incompatible("expand_space_dimension(v, m)", "v", var); 04838 04839 // The space dimension of the resulting BDS should not 04840 // overflow the maximum allowed space dimension. 04841 if (m > max_space_dimension() - space_dimension()) 04842 throw_generic("expand_dimension(v, m)", 04843 "adding m new space dimensions exceeds " 04844 "the maximum allowed space dimension"); 04845 04846 // Nothing to do, if no dimensions must be added. 04847 if (m == 0) 04848 return; 04849 04850 // Add the required new dimensions. 04851 add_space_dimensions_and_embed(m); 04852 04853 // For each constraints involving variable `var', we add a 04854 // similar constraint with the new variable substituted for 04855 // variable `var'. 04856 const dimension_type v_id = var.id() + 1; 04857 const DB_Row<N>& dbm_v = dbm[v_id]; 04858 for (dimension_type i = old_dim + 1; i-- > 0; ) { 04859 DB_Row<N>& dbm_i = dbm[i]; 04860 const N& dbm_i_v = dbm[i][v_id]; 04861 const N& dbm_v_i = dbm_v[i]; 04862 for (dimension_type j = old_dim+1; j < old_dim+m+1; ++j) { 04863 dbm_i[j] = dbm_i_v; 04864 dbm[j][i] = dbm_v_i; 04865 } 04866 } 04867 // In general, adding a constraint does not preserve the shortest-path 04868 // closure or reduction of the bounded difference shape. 04869 if (marked_shortest_path_closed()) 04870 reset_shortest_path_closed(); 04871 assert(OK()); 04872 }
| void Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions | ( | const Variables_Set & | to_be_folded, | |
| Variable | var | |||
| ) | [inline] |
Folds the space dimensions in to_be_folded into var.
| to_be_folded | The set of Variable objects corresponding to the space dimensions to be folded; | |
| var | The variable corresponding to the space dimension that is the destination of the folding operation. |
| std::invalid_argument | Thrown if *this is dimension-incompatible with var or with one of the Variable objects contained in to_be_folded. Also thrown if var is contained in to_be_folded. |
*this has space dimension
, with
, var has space dimension
, to_be_folded is a set of variables whose maximum space dimension is also less than or equal to
, and var is not a member of to_be_folded, then the space dimensions corresponding to variables in to_be_folded are folded into the
-th space dimension.
Definition at line 4876 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::max_assign(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::Variable::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_generic().
04877 { 04878 const dimension_type space_dim = space_dimension(); 04879 // `var' should be one of the dimensions of the BDS. 04880 if (var.space_dimension() > space_dim) 04881 throw_dimension_incompatible("fold_space_dimensions(tbf, v)", 04882 "v", var); 04883 04884 // The folding of no dimensions is a no-op. 04885 if (to_be_folded.empty()) 04886 return; 04887 04888 // All variables in `to_be_folded' should be dimensions of the BDS. 04889 if (to_be_folded.space_dimension() > space_dim) 04890 throw_dimension_incompatible("fold_space_dimensions(tbf, ...)", 04891 to_be_folded.space_dimension()); 04892 04893 // Moreover, `var.id()' should not occur in `to_be_folded'. 04894 if (to_be_folded.find(var.id()) != to_be_folded.end()) 04895 throw_generic("fold_space_dimensions(tbf, v)", 04896 "v should not occur in tbf"); 04897 04898 shortest_path_closure_assign(); 04899 if (!marked_empty()) { 04900 // Recompute the elements of the row and the column corresponding 04901 // to variable `var' by taking the join of their value with the 04902 // value of the corresponding elements in the row and column of the 04903 // variable `to_be_folded'. 04904 const dimension_type v_id = var.id() + 1; 04905 DB_Row<N>& dbm_v = dbm[v_id]; 04906 for (Variables_Set::const_iterator i = to_be_folded.begin(), 04907 tbf_end = to_be_folded.end(); i != tbf_end; ++i) { 04908 const dimension_type tbf_id = *i + 1; 04909 const DB_Row<N>& dbm_tbf = dbm[tbf_id]; 04910 for (dimension_type j = space_dim + 1; j-- > 0; ) { 04911 max_assign(dbm[j][v_id], dbm[j][tbf_id]); 04912 max_assign(dbm_v[j], dbm_tbf[j]); 04913 } 04914 } 04915 } 04916 remove_space_dimensions(to_be_folded); 04917 }
| void Parma_Polyhedra_Library::BD_Shape< T >::ascii_dump | ( | ) | const |
Writes to std::cerr an ASCII representation of *this.
| void Parma_Polyhedra_Library::BD_Shape< T >::ascii_dump | ( | std::ostream & | s | ) | const [inline] |
Writes to s an ASCII representation of *this.
Definition at line 5031 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Bit_Matrix::ascii_dump(), Parma_Polyhedra_Library::BD_Shape< T >::Status::ascii_dump(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, and Parma_Polyhedra_Library::BD_Shape< T >::status.
05031 { 05032 status.ascii_dump(s); 05033 s << "\n"; 05034 dbm.ascii_dump(s); 05035 s << "\n"; 05036 redundancy_dbm.ascii_dump(s); 05037 }
| void Parma_Polyhedra_Library::BD_Shape< T >::print | ( | ) | const |
Prints *this to std::cerr using operator<<.
| bool Parma_Polyhedra_Library::BD_Shape< T >::ascii_load | ( | std::istream & | s | ) | [inline] |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise.
Definition at line 5043 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Bit_Matrix::ascii_load(), Parma_Polyhedra_Library::BD_Shape< T >::Status::ascii_load(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, and Parma_Polyhedra_Library::BD_Shape< T >::status.
05043 { 05044 if (!status.ascii_load(s)) 05045 return false; 05046 if (!dbm.ascii_load(s)) 05047 return false; 05048 if (!redundancy_dbm.ascii_load(s)) 05049 return false; 05050 return true; 05051 }
| memory_size_type Parma_Polyhedra_Library::BD_Shape< T >::total_memory_in_bytes | ( | ) | const [inline] |
Returns the total size in bytes of the memory occupied by *this.
Definition at line 857 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::external_memory_in_bytes().
00857 { 00858 return sizeof(*this) + external_memory_in_bytes(); 00859 }
| memory_size_type Parma_Polyhedra_Library::BD_Shape< T >::external_memory_in_bytes | ( | ) | const [inline] |
Returns the size in bytes of the memory managed by *this.
Definition at line 5055 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::Bit_Matrix::external_memory_in_bytes(), and Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::total_memory_in_bytes().
05055 { 05056 return dbm.external_memory_in_bytes() 05057 + redundancy_dbm.external_memory_in_bytes(); 05058 }
| int32_t Parma_Polyhedra_Library::BD_Shape< T >::hash_code | ( | ) | const [inline] |
Returns a 32-bit hash code for *this.
If x and y are such that x == y, then x.hash_code() == y.hash_code().
Definition at line 863 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00863 { 00864 return space_dimension() & 0x7fffffff; 00865 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::marked_zero_dim_univ | ( | ) | const [inline, private] |
Returns true if the BDS is the zero-dimensional universe.
Definition at line 52 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::status, and Parma_Polyhedra_Library::BD_Shape< T >::Status::test_zero_dim_univ().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape().
00052 { 00053 return status.test_zero_dim_univ(); 00054 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::marked_empty | ( | ) | const [inline, private] |
Returns true if the BDS is known to be empty.
The return value false does not necessarily implies that *this is non-empty.
Definition at line 58 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::status, and Parma_Polyhedra_Library::BD_Shape< T >::Status::test_empty().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraint_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraints_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project(), Parma_Polyhedra_Library::BD_Shape< T >::affine_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::bounds(), Parma_Polyhedra_Library::Box< ITV >::Box(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::compute_leaders(), Parma_Polyhedra_Library::BD_Shape< T >::compute_predecessors(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::constrains(), Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::euclidean_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::is_bounded(), Parma_Polyhedra_Library::BD_Shape< T >::is_disjoint_from(), Parma_Polyhedra_Library::BD_Shape< T >::is_empty(), Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::is_universe(), Parma_Polyhedra_Library::BD_Shape< T >::l_infinity_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::max_min(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::rectilinear_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::relation_with(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), Parma_Polyhedra_Library::BD_Shape< T >::unconstrain(), Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign_and_minimize().
00058 { 00059 return status.test_empty(); 00060 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed | ( | ) | const [inline, private] |
Returns true if the system of bounded differences is known to be shortest-path closed.
The return value false does not necessarily implies that this->dbm is not shortest-path closed.
Definition at line 64 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::status, and Parma_Polyhedra_Library::BD_Shape< T >::Status::test_shortest_path_closed().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::compute_leaders(), Parma_Polyhedra_Library::BD_Shape< T >::compute_predecessors(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign_and_minimize().
00064 { 00065 return status.test_shortest_path_closed(); 00066 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced | ( | ) | const [inline, private] |
Returns true if the system of bounded differences is known to be shortest-path reduced.
The return value false does not necessarily implies that this->dbm is not shortest-path reduced.
Definition at line 70 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::status, and Parma_Polyhedra_Library::BD_Shape< T >::Status::test_shortest_path_reduced().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::operator=(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
00070 { 00071 return status.test_shortest_path_reduced(); 00072 }
| void Parma_Polyhedra_Library::BD_Shape< T >::set_empty | ( | ) | [inline, private] |
Turns *this into an empty BDS.
Definition at line 82 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::Status::set_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::status.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign().
| void Parma_Polyhedra_Library::BD_Shape< T >::set_zero_dim_univ | ( | ) | [inline, private] |
Turns *this into an zero-dimensional universe BDS.
Definition at line 76 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::Status::set_zero_dim_univ(), and Parma_Polyhedra_Library::BD_Shape< T >::status.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), and Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions().
00076 { 00077 status.set_zero_dim_univ(); 00078 }
| void Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed | ( | ) | [inline, private] |
Marks *this as shortest-path closed.
Definition at line 88 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::Status::set_shortest_path_closed(), and Parma_Polyhedra_Library::BD_Shape< T >::status.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign().
00088 { 00089 status.set_shortest_path_closed(); 00090 }
| void Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_reduced | ( | ) | [inline, private] |
Marks *this as shortest-path closed.
Definition at line 94 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::Status::set_shortest_path_reduced(), and Parma_Polyhedra_Library::BD_Shape< T >::status.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign().
00094 { 00095 status.set_shortest_path_reduced(); 00096 }
| void Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed | ( | ) | [inline, private] |
Marks *this as possibly not shortest-path closed.
Definition at line 100 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::Status::reset_shortest_path_closed(), and Parma_Polyhedra_Library::BD_Shape< T >::status.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::contains_integer_point(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::refine(), and Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check().
00100 { 00101 status.reset_shortest_path_closed(); 00102 }
| void Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced | ( | ) | [inline, private] |
Marks *this as possibly not shortest-path reduced.
Definition at line 106 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::Status::reset_shortest_path_reduced(), and Parma_Polyhedra_Library::BD_Shape< T >::status.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::unconstrain(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
00106 { 00107 status.reset_shortest_path_reduced(); 00108 }
| void Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign | ( | ) | const [inline, private] |
Assigns to this->dbm its shortest-path closure.
Definition at line 1620 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::min_assign(), PLUS_INFINITY, Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraint_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraints_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::affine_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::bounds(), Parma_Polyhedra_Library::Box< ITV >::Box(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::euclidean_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign_and_minimize(), Parma_Polyhedra_Library::BD_Shape< T >::is_bounded(), Parma_Polyhedra_Library::BD_Shape< T >::is_disjoint_from(), Parma_Polyhedra_Library::BD_Shape< T >::is_empty(), Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::l_infinity_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::max_min(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::rectilinear_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::relation_with(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), Parma_Polyhedra_Library::BD_Shape< T >::unconstrain(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
01620 { 01621 // Do something only if necessary. 01622 if (marked_empty() || marked_shortest_path_closed()) 01623 return; 01624 const dimension_type num_dimensions = space_dimension(); 01625 // Zero-dimensional BDSs are necessarily shortest-path closed. 01626 if (num_dimensions == 0) 01627 return; 01628 01629 // Even though the BDS will not change, its internal representation 01630 // is going to be modified by the Floyd-Warshall algorithm. 01631 BD_Shape& x = const_cast<BD_Shape<T>&>(*this); 01632 01633 // Fill the main diagonal with zeros. 01634 for (dimension_type h = num_dimensions + 1; h-- > 0; ) { 01635 assert(is_plus_infinity(x.dbm[h][h])); 01636 assign_r(x.dbm[h][h], 0, ROUND_NOT_NEEDED); 01637 } 01638 01639 DIRTY_TEMP(N, sum); 01640 for (dimension_type k = num_dimensions + 1; k-- > 0; ) { 01641 const DB_Row<N>& x_dbm_k = x.dbm[k]; 01642 for (dimension_type i = num_dimensions + 1; i-- > 0; ) { 01643 DB_Row<N>& x_dbm_i = x.dbm[i]; 01644 const N& x_dbm_i_k = x_dbm_i[k]; 01645 if (!is_plus_infinity(x_dbm_i_k)) 01646 for (dimension_type j = num_dimensions + 1; j-- > 0; ) { 01647 const N& x_dbm_k_j = x_dbm_k[j]; 01648 if (!is_plus_infinity(x_dbm_k_j)) { 01649 // Rounding upward for correctness. 01650 add_assign_r(sum, x_dbm_i_k, x_dbm_k_j, ROUND_UP); 01651 min_assign(x_dbm_i[j], sum); 01652 } 01653 } 01654 } 01655 } 01656 01657 // Check for emptiness: the BDS is empty if and only if there is a 01658 // negative value on the main diagonal of `dbm'. 01659 for (dimension_type h = num_dimensions + 1; h-- > 0; ) { 01660 N& x_dbm_hh = x.dbm[h][h]; 01661 if (sgn(x_dbm_hh) < 0) { 01662 x.set_empty(); 01663 return; 01664 } 01665 else { 01666 assert(sgn(x_dbm_hh) == 0); 01667 // Restore PLUS_INFINITY on the main diagonal. 01668 assign_r(x_dbm_hh, PLUS_INFINITY, ROUND_NOT_NEEDED); 01669 } 01670 } 01671 01672 // The BDS is not empty and it is now shortest-path closed. 01673 x.set_shortest_path_closed(); 01674 }
| void Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign | ( | ) | const [inline, private] |
Assigns to this->dbm its shortest-path closure and records into this->redundancy_dbm which of the entries in this->dbm are redundant.
Definition at line 1678 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Bit_Matrix::clear(), Parma_Polyhedra_Library::Bit_Row::clear(), Parma_Polyhedra_Library::BD_Shape< T >::compute_leader_indices(), Parma_Polyhedra_Library::BD_Shape< T >::compute_predecessors(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, Parma_Polyhedra_Library::Bit_Row::set(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::swap().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints(), and Parma_Polyhedra_Library::BD_Shape< T >::OK().
01678 { 01679 // Do something only if necessary. 01680 if (marked_shortest_path_reduced()) 01681 return; 01682 01683 const dimension_type space_dim = space_dimension(); 01684 // Zero-dimensional BDSs are necessarily reduced. 01685 if (space_dim == 0) 01686 return; 01687 01688 // First find the tightest constraints for this BDS. 01689 shortest_path_closure_assign(); 01690 01691 // If `*this' is empty, then there is nothing to reduce. 01692 if (marked_empty()) 01693 return; 01694 01695 // Step 1: compute zero-equivalence classes. 01696 // Variables corresponding to indices `i' and `j' are zero-equivalent 01697 // if they lie on a zero-weight loop; since the matrix is shortest-path 01698 // closed, this happens if and only if dbm[i][j] == -dbm[j][i]. 01699 std::vector<dimension_type> predecessor; 01700 compute_predecessors(predecessor); 01701 std::vector<dimension_type> leaders; 01702 compute_leader_indices(predecessor, leaders); 01703 const dimension_type num_leaders = leaders.size(); 01704 01705 Bit_Matrix redundancy(space_dim + 1, space_dim + 1); 01706 // Init all constraints to be redundant. 01707 // TODO: provide an appropriate method to set multiple bits. 01708 Bit_Row& red_0 = redundancy[0]; 01709 for (dimension_type j = space_dim + 1; j-- > 0; ) 01710 red_0.set(j); 01711 for (dimension_type i = space_dim + 1; i-- > 0; ) 01712 redundancy[i] = red_0; 01713 01714 // Step 2: flag non-redundant constraints in the (zero-cycle-free) 01715 // subsystem of bounded differences having only leaders as variables. 01716 DIRTY_TEMP(N, c); 01717 for (dimension_type l_i = 0; l_i < num_leaders; ++l_i) { 01718 const dimension_type i = leaders[l_i]; 01719 const DB_Row<N>& dbm_i = dbm[i]; 01720 Bit_Row& redundancy_i = redundancy[i]; 01721 for (dimension_type l_j = 0; l_j < num_leaders; ++l_j) { 01722 const dimension_type j = leaders[l_j]; 01723 if (redundancy_i[j]) { 01724 const N& dbm_i_j = dbm_i[j]; 01725 redundancy_i.clear(j); 01726 for (dimension_type l_k = 0; l_k < num_leaders; ++l_k) { 01727 const dimension_type k = leaders[l_k]; 01728 add_assign_r(c, dbm_i[k], dbm[k][j], ROUND_UP); 01729 if (dbm_i_j >= c) { 01730 redundancy_i.set(j); 01731 break; 01732 } 01733 } 01734 } 01735 } 01736 } 01737 01738 // Step 3: flag non-redundant constraints in zero-equivalence classes. 01739 // Each equivalence class must have a single 0-cycle connecting 01740 // all the equivalent variables in increasing order. 01741 std::deque<bool> dealt_with(space_dim + 1, false); 01742 for (dimension_type i = space_dim + 1; i-- > 0; ) 01743 // We only need to deal with non-singleton zero-equivalence classes 01744 // that haven't already been dealt with. 01745 if (i != predecessor[i] && !dealt_with[i]) { 01746 dimension_type j = i; 01747 while (true) { 01748 const dimension_type pred_j = predecessor[j]; 01749 if (j == pred_j) { 01750 // We finally found the leader of `i'. 01751 assert(redundancy[i][j]); 01752 redundancy[i].clear(j); 01753 // Here we dealt with `j' (i.e., `pred_j'), but it is useless 01754 // to update `dealt_with' because `j' is a leader. 01755 break; 01756 } 01757 // We haven't found the leader of `i' yet. 01758 assert(redundancy[pred_j][j]); 01759 redundancy[pred_j].clear(j); 01760 dealt_with[pred_j] = true; 01761 j = pred_j; 01762 } 01763 } 01764 01765 // Even though shortest-path reduction is not going to change the BDS, 01766 // it might change its internal representation. 01767 BD_Shape<T>& x = const_cast<BD_Shape<T>&>(*this); 01768 std::swap(x.redundancy_dbm, redundancy); 01769 x.set_shortest_path_reduced(); 01770 01771 assert(is_shortest_path_reduced()); 01772 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced | ( | ) | const [inline, private] |
Returns true if and only if this->dbm is shortest-path closed and this->redundancy_dbm correctly flags the redundant entries in this->dbm.
Definition at line 844 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::is_additive_inverse(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm, Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign().
00844 { 00845 // If the BDS is empty, it is also reduced. 00846 if (marked_empty()) 00847 return true; 00848 00849 const dimension_type space_dim = space_dimension(); 00850 // Zero-dimensional BDSs are necessarily reduced. 00851 if (space_dim == 0) 00852 return true; 00853 00854 // A shortest-path reduced dbm is just a dbm with an indication of 00855 // those constraints that are redundant. If there is no indication 00856 // of the redundant constraints, then it cannot be reduced. 00857 if (!marked_shortest_path_reduced()) 00858 return false; 00859 00860 const BD_Shape x_copy = *this; 00861 x_copy.shortest_path_closure_assign(); 00862 // If we just discovered emptiness, it cannot be reduced. 00863 if (x_copy.marked_empty()) 00864 return false; 00865 00866 // The vector `leader' is used to indicate which variables are equivalent. 00867 std::vector<dimension_type> leader(space_dim + 1); 00868 00869 // We store the leader. 00870 for (dimension_type i = space_dim + 1; i-- > 0; ) 00871 leader[i] = i; 00872 00873 // Step 1: we store really the leader with the corrected value. 00874 // We search for the equivalent or zero-equivalent variables. 00875 // The variable(i-1) and variable(j-1) are equivalent if and only if 00876 // m_i_j == -(m_j_i). 00877 for (dimension_type i = 0; i < space_dim; ++i) { 00878 const DB_Row<N>& x_copy_dbm_i = x_copy.dbm[i]; 00879 for (dimension_type j = i + 1; j <= space_dim; ++j) 00880 if (is_additive_inverse(x_copy.dbm[j][i], x_copy_dbm_i[j])) 00881 // Two equivalent variables have got the same leader 00882 // (the smaller variable). 00883 leader[j] = leader[i]; 00884 } 00885 00886 // Step 2: we check if there are redundant constraints in the zero_cycle 00887 // free bounded difference shape, considering only the leaders. 00888 // A constraint `c' is redundant, when there are two constraints such that 00889 // their sum is the same constraint with the inhomogeneous term 00890 // less than or equal to the `c' one. 00891 DIRTY_TEMP(N, c); 00892 for (dimension_type k = 0; k <= space_dim; ++k) 00893 if (leader[k] == k) { 00894 const DB_Row<N>& x_k = x_copy.dbm[k]; 00895 for (dimension_type i = 0; i <= space_dim; ++i) 00896 if (leader[i] == i) { 00897 const DB_Row<N>& x_i = x_copy.dbm[i]; 00898 const Bit_Row& redundancy_i = redundancy_dbm[i]; 00899 const N& x_i_k = x_i[k]; 00900 for (dimension_type j = 0; j <= space_dim; ++j) 00901 if (leader[j] == j) { 00902 const N& x_i_j = x_i[j]; 00903 if (!is_plus_infinity(x_i_j)) { 00904 add_assign_r(c, x_i_k, x_k[j], ROUND_UP); 00905 if (x_i_j >= c && !redundancy_i[j]) 00906 return false; 00907 } 00908 } 00909 } 00910 } 00911 00912 // The vector `var_conn' is used to check if there is a single cycle 00913 // that connected all zero-equivalent variables between them. 00914 // The value `space_dim + 1' is used to indicate that the equivalence 00915 // class contains a single variable. 00916 std::vector<dimension_type> var_conn(space_dim + 1); 00917 for (dimension_type i = space_dim + 1; i-- > 0; ) 00918 var_conn[i] = space_dim + 1; 00919 00920 // Step 3: we store really the `var_conn' with the right value, putting 00921 // the variable with the selected variable is connected: 00922 // we check the row of each variable: 00923 // a- each leader could be connected with only zero-equivalent one, 00924 // b- each no-leader with only another zero-equivalent one. 00925 for (dimension_type i = 0; i <= space_dim; ++i) { 00926 // It count with how many variables the selected variable is 00927 // connected. 00928 dimension_type t = 0; 00929 dimension_type ld_i = leader[i]; 00930 // Case a: leader. 00931 if (ld_i == i) { 00932 for (dimension_type j = 0; j <= space_dim; ++j) { 00933 dimension_type ld_j = leader[j]; 00934 // Only the connectedness with equivalent variables 00935 // is considered. 00936 if (j != ld_j) 00937 if (!redundancy_dbm[i][j]) { 00938 if (t == 1) 00939 // Two no-leaders couldn't connected with the same leader. 00940 return false; 00941 else 00942 if (ld_j != i) 00943 // The variables isn't in the same equivalence class. 00944 return false; 00945 else { 00946 ++t; 00947 var_conn[i] = j; 00948 } 00949 } 00950 } 00951 } 00952 // Case b: no-leader. 00953 else { 00954 for (dimension_type j = 0; j <= space_dim; ++j) { 00955 if (!redundancy_dbm[i][j]) { 00956 dimension_type ld_j = leader[j]; 00957 if (ld_i != ld_j) 00958 // The variables isn't in the same equivalence class. 00959 return false; 00960 else { 00961 if (t == 1) 00962 // Two variables couldn't connected with the same leader. 00963 return false; 00964 else { 00965 ++t; 00966 var_conn[i] = j; 00967 } 00968 } 00969 // A no-leader must be connected with 00970 // another variable. 00971 if (t == 0) 00972 return false; 00973 } 00974 } 00975 } 00976 } 00977 00978 // The vector `just_checked' is used to check if 00979 // a variable is already checked. 00980 std::vector<bool> just_checked(space_dim + 1); 00981 for (dimension_type i = space_dim + 1; i-- > 0; ) 00982 just_checked[i] = false; 00983 00984 // Step 4: we check if there are single cycles that 00985 // connected all the zero-equivalent variables between them. 00986 for (dimension_type i = 0; i <= space_dim; ++i) { 00987 bool jc_i = just_checked[i]; 00988 // We do not re-check the already considered single cycles. 00989 if (!jc_i) { 00990 dimension_type v_con = var_conn[i]; 00991 // We consider only the equivalence classes with 00992 // 2 or plus variables. 00993 if (v_con != space_dim + 1) { 00994 // There is a single cycle if taken a variable, 00995 // we return to this same variable. 00996 while (v_con != i) { 00997 just_checked[v_con] = true; 00998 v_con = var_conn[v_con]; 00999 // If we re-pass to an already considered variable, 01000 // then we haven't a single cycle. 01001 if (just_checked[v_con]) 01002 return false; 01003 } 01004 } 01005 } 01006 just_checked[i] = true; 01007 } 01008 01009 // The system bounded differences is just reduced. 01010 return true; 01011 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::bounds | ( | const Linear_Expression & | expr, | |
| bool | from_above | |||
| ) | const [inline, private] |
Checks if and how expr is bounded in *this.
Returns true if and only if from_above is true and expr is bounded from above in *this, or from_above is false and expr is bounded from below in *this.
| expr | The linear expression to test; | |
| from_above | true if and only if the boundedness of interest is "from above". |
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
Definition at line 1015 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::extract_bounded_difference(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::MAXIMIZATION, Parma_Polyhedra_Library::MINIMIZATION, Parma_Polyhedra_Library::OPTIMIZED_MIP_PROBLEM, Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::MIP_Problem::solve(), Parma_Polyhedra_Library::Constraint::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), TEMP_INTEGER, and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::bounds_from_above(), and Parma_Polyhedra_Library::BD_Shape< T >::bounds_from_below().
01016 { 01017 // The dimension of `expr' should not be greater than the dimension 01018 // of `*this'. 01019 const dimension_type expr_space_dim = expr.space_dimension(); 01020 const dimension_type space_dim = space_dimension(); 01021 if (space_dim < expr_space_dim) 01022 throw_dimension_incompatible((from_above 01023 ? "bounds_from_above(e)" 01024 : "bounds_from_below(e)"), "e", expr); 01025 01026 shortest_path_closure_assign(); 01027 // A zero-dimensional or empty BDS bounds everything. 01028 if (space_dim == 0 || marked_empty()) 01029 return true; 01030 01031 // The constraint `c' is used to check if `expr' is a difference 01032 // bounded and, in this case, to select the cell. 01033 const Constraint& c = from_above ? expr <= 0 : expr >= 0; 01034 const dimension_type c_space_dim = c.space_dimension(); 01035 dimension_type num_vars = 0; 01036 dimension_type i = 0; 01037 dimension_type j = 0; 01038 TEMP_INTEGER(coeff); 01039 // Check if `c' is a BD constraint. 01040 if (extract_bounded_difference(c, c_space_dim, num_vars, i, j, coeff)) { 01041 if (num_vars == 0) 01042 // Dealing with a trivial constraint. 01043 return true; 01044 // Select the cell to be checked. 01045 const N& x = (coeff < 0) ? dbm[i][j] : dbm[j][i]; 01046 return !is_plus_infinity(x); 01047 } 01048 else { 01049 // Not a DB constraint: use the MIP solver. 01050 Optimization_Mode mode_bounds 01051 = from_above ? MAXIMIZATION : MINIMIZATION; 01052 MIP_Problem mip(space_dim, constraints(), expr, mode_bounds); 01053 // Problem is known to be feasible. 01054 return (mip.solve() == OPTIMIZED_MIP_PROBLEM); 01055 } 01056 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::max_min | ( | const Linear_Expression & | expr, | |
| bool | maximize, | |||
| Coefficient & | ext_n, | |||
| Coefficient & | ext_d, | |||
| bool & | included, | |||
| Generator & | g | |||
| ) | const [inline, private] |
Maximizes or minimizes expr subject to *this.
| expr | The linear expression to be maximized or minimized subject to this; | |
| maximize | true if maximization is what is wanted; | |
| ext_n | The numerator of the extremum value; | |
| ext_d | The denominator of the extremum value; | |
| included | true if and only if the extremum of expr can actually be reached in * this; | |
| g | When maximization or minimization succeeds, will be assigned a point or closure point where expr reaches the corresponding extremum value. |
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this is empty or expr is not bounded in the appropriate direction, false is returned and ext_n, ext_d, included and g are left untouched.
Definition at line 1159 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::MIP_Problem::evaluate_objective_function(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::MAXIMIZATION, Parma_Polyhedra_Library::MINIMIZATION, Parma_Polyhedra_Library::OPTIMIZED_MIP_PROBLEM, Parma_Polyhedra_Library::MIP_Problem::optimizing_point(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::MIP_Problem::solve(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::maximize(), and Parma_Polyhedra_Library::BD_Shape< T >::minimize().
01163 { 01164 // The dimension of `expr' should not be greater than the dimension 01165 // of `*this'. 01166 const dimension_type space_dim = space_dimension(); 01167 const dimension_type expr_space_dim = expr.space_dimension(); 01168 if (space_dim < expr_space_dim) 01169 throw_dimension_incompatible((maximize 01170 ? "maximize(e, ...)" 01171 : "minimize(e, ...)"), "e", expr); 01172 // Deal with zero-dim BDS first. 01173 if (space_dim == 0) { 01174 if (marked_empty()) 01175 return false; 01176 else { 01177 ext_n = expr.inhomogeneous_term(); 01178 ext_d = 1; 01179 included = true; 01180 g = point(); 01181 return true; 01182 } 01183 } 01184 01185 shortest_path_closure_assign(); 01186 // For an empty BDS we simply return false. 01187 if (marked_empty()) 01188 return false; 01189 01190 Optimization_Mode mode_max_min 01191 = maximize ? MAXIMIZATION : MINIMIZATION; 01192 MIP_Problem mip(space_dim, constraints(), expr, mode_max_min); 01193 if (mip.solve() == OPTIMIZED_MIP_PROBLEM) { 01194 g = mip.optimizing_point(); 01195 mip.evaluate_objective_function(g, ext_n, ext_d); 01196 included = true; 01197 return true; 01198 } 01199 // Here `expr' is unbounded in `*this'. 01200 return false; 01201 }
| bool Parma_Polyhedra_Library::BD_Shape< T >::max_min | ( | const Linear_Expression & | expr, | |
| bool | maximize, | |||
| Coefficient & | ext_n, | |||
| Coefficient & | ext_d, | |||
| bool & | included | |||
| ) | const [inline, private] |
Maximizes or minimizes expr subject to *this.
| expr | The linear expression to be maximized or minimized subject to this; | |
| maximize | true if maximization is what is wanted; | |
| ext_n | The numerator of the extremum value; | |
| ext_d | The denominator of the extremum value; | |
| included | true if and only if the extremum of expr can actually be reached in * this; |
| std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this is empty or expr is not bounded in the appropriate direction, false is returned and ext_n, ext_d, included and point are left untouched.
Definition at line 1060 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::extract_bounded_difference(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::MAXIMIZATION, Parma_Polyhedra_Library::MINIMIZATION, Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::numer_denom(), Parma_Polyhedra_Library::MIP_Problem::optimal_value(), Parma_Polyhedra_Library::OPTIMIZED_MIP_PROBLEM, Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::MIP_Problem::solve(), Parma_Polyhedra_Library::Constraint::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), TEMP_INTEGER, and Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible().
01063 { 01064 // The dimension of `expr' should not be greater than the dimension 01065 // of `*this'. 01066 const dimension_type space_dim = space_dimension(); 01067 const dimension_type expr_space_dim = expr.space_dimension(); 01068 if (space_dim < expr_space_dim) 01069 throw_dimension_incompatible((maximize 01070 ? "maximize(e, ...)" 01071 : "minimize(e, ...)"), "e", expr); 01072 // Deal with zero-dim BDS first. 01073 if (space_dim == 0) { 01074 if (marked_empty()) 01075 return false; 01076 else { 01077 ext_n = expr.inhomogeneous_term(); 01078 ext_d = 1; 01079 included = true; 01080 return true; 01081 } 01082 } 01083 01084 shortest_path_closure_assign(); 01085 // For an empty BDS we simply return false. 01086 if (marked_empty()) 01087 return false; 01088 01089 // The constraint `c' is used to check if `expr' is a difference 01090 // bounded and, in this case, to select the cell. 01091 const Constraint& c = maximize ? expr <= 0 : expr >= 0; 01092 const dimension_type c_space_dim = c.space_dimension(); 01093 dimension_type num_vars = 0; 01094 dimension_type i = 0; 01095 dimension_type j = 0; 01096 TEMP_INTEGER(coeff); 01097 // Check if `c' is a BD constraint. 01098 if (!extract_bounded_difference(c, c_space_dim, num_vars, i, j, coeff)) { 01099 Optimization_Mode mode_max_min 01100 = maximize ? MAXIMIZATION : MINIMIZATION; 01101 MIP_Problem mip(space_dim, constraints(), expr, mode_max_min); 01102 if (mip.solve() == OPTIMIZED_MIP_PROBLEM) { 01103 mip.optimal_value(ext_n, ext_d); 01104 included = true; 01105 return true; 01106 } 01107 else 01108 // Here`expr' is unbounded in `*this'. 01109 return false; 01110 } 01111 else { 01112 // Here `expr' is a bounded difference. 01113 if (num_vars == 0) { 01114 // Dealing with a trivial expression. 01115 ext_n = expr.inhomogeneous_term(); 01116 ext_d = 1; 01117 included = true; 01118 return true; 01119 } 01120 01121 // Select the cell to be checked. 01122 const N& x = (coeff < 0) ? dbm[i][j] : dbm[j][i]; 01123 if (!is_plus_infinity(x)) { 01124 // Compute the maximize/minimize of `expr'. 01125 DIRTY_TEMP(N, d); 01126 const Coefficient& b = expr.inhomogeneous_term(); 01127 TEMP_INTEGER(minus_b); 01128 neg_assign(minus_b, b); 01129 const Coefficient& sc_b = maximize ? b : minus_b; 01130 assign_r(d, sc_b, ROUND_UP); 01131 // Set `coeff_expr' to the absolute value of coefficient of 01132 // a variable in `expr'. 01133 DIRTY_TEMP(N, coeff_expr); 01134 const Coefficient& coeff_i = expr.coefficient(Variable(i-1)); 01135 const int sign_i = sgn(coeff_i); 01136 if (sign_i > 0) 01137 assign_r(coeff_expr, coeff_i, ROUND_UP); 01138 else { 01139 TEMP_INTEGER(minus_coeff_i); 01140 neg_assign(minus_coeff_i, coeff_i); 01141 assign_r(coeff_expr, minus_coeff_i, ROUND_UP); 01142 } 01143 // Approximating the maximum/minimum of `expr'. 01144 add_mul_assign_r(d, coeff_expr, x, ROUND_UP); 01145 numer_denom(d, ext_n, ext_d); 01146 if (!maximize) 01147 neg_assign(ext_n); 01148 included = true; 01149 return true; 01150 } 01151 01152 // `expr' is unbounded. 01153 return false; 01154 } 01155 }
| void Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check | ( | const Constraint & | c | ) | [inline, private] |
Uses the constraint c to refine *this.
| c | The constraint to be added. Non BD constraints are ignored. |
c and *this are dimension-incompatible, the behavior is undefined. Definition at line 473 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::BD_Shape< T >::extract_bounded_difference(), Parma_Polyhedra_Library::Constraint::inhomogeneous_term(), Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Constraint::is_strict_inequality(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Constraint::space_dimension(), and TEMP_INTEGER.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraint(), and Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints().
00473 { 00474 assert(!marked_empty()); 00475 const dimension_type c_space_dim = c.space_dimension(); 00476 assert(c_space_dim <= space_dimension()); 00477 00478 dimension_type num_vars = 0; 00479 dimension_type i = 0; 00480 dimension_type j = 0; 00481 TEMP_INTEGER(coeff); 00482 // Constraints that are not bounded differences are ignored. 00483 if (!extract_bounded_difference(c, c_space_dim, num_vars, i, j, coeff)) 00484 return; 00485 00486 const Coefficient& inhomo = c.inhomogeneous_term(); 00487 if (num_vars == 0) { 00488 // Dealing with a trivial constraint (might be a strict inequality). 00489 if (inhomo < 0 00490 || (c.is_equality() && inhomo != 0) 00491 || (c.is_strict_inequality() && inhomo == 0)) 00492 set_empty(); 00493 return; 00494 } 00495 00496 // Select the cell to be modified for the "<=" part of the constraint, 00497 // and set `coeff' to the absolute value of itself. 00498 const bool negative = (coeff < 0); 00499 N& x = negative ? dbm[i][j] : dbm[j][i]; 00500 N& y = negative ? dbm[j][i] : dbm[i][j]; 00501 if (negative) 00502 neg_assign(coeff); 00503 00504 bool changed = false; 00505 // Compute the bound for `x', rounding towards plus infinity. 00506 DIRTY_TEMP(N, d); 00507 div_round_up(d, inhomo, coeff); 00508 if (x > d) { 00509 x = d; 00510 changed = true; 00511 } 00512 00513 if (c.is_equality()) { 00514 // Also compute the bound for `y', rounding towards plus infinity. 00515 TEMP_INTEGER(minus_c_term); 00516 neg_assign(minus_c_term, inhomo); 00517 div_round_up(d, minus_c_term, coeff); 00518 if (y > d) { 00519 y = d; 00520 changed = true; 00521 } 00522 } 00523 00524 // In general, adding a constraint does not preserve the shortest-path 00525 // closure or reduction of the bounded difference shape. 00526 if (changed && marked_shortest_path_closed()) 00527 reset_shortest_path_closed(); 00528 assert(OK()); 00529 }
| void Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check | ( | const Congruence & | cg | ) | [inline, private] |
Uses the congruence cg to refine *this.
| cg | The congruence to be added. Nontrivial proper congruences are ignored. Non BD equalities are ignored. |
cg and *this are dimension-incompatible, the behavior is undefined. Definition at line 278 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::Congruence::is_equality(), Parma_Polyhedra_Library::Congruence::is_inconsistent(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), and Parma_Polyhedra_Library::Congruence::space_dimension().
00278 { 00279 assert(!marked_empty()); 00280 assert(cg.space_dimension() <= space_dimension()); 00281 00282 if (cg.is_proper_congruence()) { 00283 if (cg.is_inconsistent()) 00284 set_empty(); 00285 // Other proper congruences are just ignored. 00286 return; 00287 } 00288 00289 assert(cg.is_equality()); 00290 Constraint c(cg); 00291 refine_no_check(c); 00292 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint | ( | dimension_type | i, | |
| dimension_type | j, | |||
| const N & | k | |||
| ) | [inline, private] |
Adds the constraint dbm[i][j] <= k.
Definition at line 699 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), and Parma_Polyhedra_Library::BD_Shape< T >::refine().
00701 { 00702 // Private method: the caller has to ensure the following. 00703 assert(i <= space_dimension() && j <= space_dimension() && i != j); 00704 N& dbm_ij = dbm[i][j]; 00705 if (dbm_ij > k) { 00706 dbm_ij = k; 00707 if (marked_shortest_path_closed()) 00708 reset_shortest_path_closed(); 00709 } 00710 }
| void Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint | ( | dimension_type | i, | |
| dimension_type | j, | |||
| Coefficient_traits::const_reference | num, | |||
| Coefficient_traits::const_reference | den | |||
| ) | [inline, private] |
Adds the constraint dbm[i][j] <= num/den.
Definition at line 714 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::div_round_up(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00717 { 00718 // Private method: the caller has to ensure the following. 00719 assert(i <= space_dimension() && j <= space_dimension() && i != j); 00720 assert(den != 0); 00721 DIRTY_TEMP(N, k); 00722 div_round_up(k, num, den); 00723 add_dbm_constraint(i, j, k); 00724 }
| void Parma_Polyhedra_Library::BD_Shape< T >::refine | ( | Variable | var, | |
| Relation_Symbol | relsym, | |||
| const Linear_Expression & | expr, | |||
| Coefficient_traits::const_reference | denominator = Coefficient_one() | |||
| ) | [inline, private] |
Adds to the BDS the constraint
.
Note that the coefficient of var in expr is null.
Definition at line 2723 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::deduce_u_minus_v_bounds(), Parma_Polyhedra_Library::BD_Shape< T >::deduce_v_minus_u_bounds(), Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::GREATER_OR_EQUAL, Parma_Polyhedra_Library::GREATER_THAN, Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::is_plus_infinity(), Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::LESS_THAN, Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), and TEMP_INTEGER.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), and Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage().
02726 { 02727 assert(denominator != 0); 02728 const dimension_type expr_space_dim = expr.space_dimension(); 02729 assert(space_dimension() >= expr_space_dim); 02730 const dimension_type v = var.id() + 1; 02731 assert(v <= space_dimension()); 02732 assert(expr.coefficient(var) == 0); 02733 assert(relsym != LESS_THAN && relsym != GREATER_THAN); 02734 02735 const Coefficient& b = expr.inhomogeneous_term(); 02736 // Number of non-zero coefficients in `expr': will be set to 02737 // 0, 1, or 2, the latter value meaning any value greater than 1. 02738 dimension_type t = 0; 02739 // Index of the last non-zero coefficient in `expr', if any. 02740 dimension_type w = 0; 02741 // Get information about the number of non-zero coefficients in `expr'. 02742 for (dimension_type i = expr_space_dim; i-- > 0; ) 02743 if (expr.coefficient(Variable(i)) != 0) { 02744 if (t++ == 1) 02745 break; 02746 else 02747 w = i+1; 02748 } 02749 02750 // Since we are only able to record bounded differences, we can 02751 // precisely deal with the case of a single variable only if its 02752 // coefficient (taking into account the denominator) is 1. 02753 // If this is not the case, we fall back to the general case 02754 // so as to over-approximate the constraint. 02755 if (t == 1 && expr.coefficient(Variable(w-1)) != denominator) 02756 t = 2; 02757 02758 // Now we know the form of `expr': 02759 // - If t == 0, then expr == b, with `b' a constant; 02760 // - If t == 1, then expr == a*w + b, where `w != v' and `a == denominator'; 02761 // - If t == 2, the `expr' is of the general form. 02762 const DB_Row<N>& dbm_0 = dbm[0]; 02763 TEMP_INTEGER(minus_den); 02764 neg_assign(minus_den, denominator); 02765 02766 if (t == 0) { 02767 // Case 1: expr == b. 02768 switch (relsym) { 02769 case EQUAL: 02770 // Add the constraint `var == b/denominator'. 02771 add_dbm_constraint(0, v, b, denominator); 02772 add_dbm_constraint(v, 0, b, minus_den); 02773 break; 02774 case LESS_OR_EQUAL: 02775 // Add the constraint `var <= b/denominator'. 02776 add_dbm_constraint(0, v, b, denominator); 02777 break; 02778 case GREATER_OR_EQUAL: 02779 // Add the constraint `var >= b/denominator', 02780 // i.e., `-var <= -b/denominator', 02781 add_dbm_constraint(v, 0, b, minus_den); 02782 break; 02783 default: 02784 // We already dealt with the other cases. 02785 throw std::runtime_error("PPL internal error"); 02786 } 02787 return; 02788 } 02789 02790 if (t == 1) { 02791 // Case 2: expr == a*w + b, w != v, a == denominator. 02792 assert(expr.coefficient(Variable(w-1)) == denominator); 02793 DIRTY_TEMP(N, d); 02794 switch (relsym) { 02795 case EQUAL: 02796 // Add the new constraint `v - w <= b/denominator'. 02797 div_round_up(d, b, denominator); 02798 add_dbm_constraint(w, v, d); 02799 // Add the new constraint `v - w >= b/denominator', 02800 // i.e., `w - v <= -b/denominator'. 02801 div_round_up(d, b, minus_den); 02802 add_dbm_constraint(v, w, d); 02803 break; 02804 case LESS_OR_EQUAL: 02805 // Add the new constraint `v - w <= b/denominator'. 02806 div_round_up(d, b, denominator); 02807 add_dbm_constraint(w, v, d); 02808 break; 02809 case GREATER_OR_EQUAL: 02810 // Add the new constraint `v - w >= b/denominator', 02811 // i.e., `w - v <= -b/denominator'. 02812 div_round_up(d, b, minus_den); 02813 add_dbm_constraint(v, w, d); 02814 break; 02815 default: 02816 // We already dealt with the other cases. 02817 throw std::runtime_error("PPL internal error"); 02818 } 02819 return; 02820 } 02821 02822 // Here t == 2, so that either 02823 // expr == a_1*x_1 + a_2*x_2 + ... + a_n*x_n + b, where n >= 2, or 02824 // expr == a*w + b, w != v and a != denominator. 02825 const bool is_sc = (denominator > 0); 02826 TEMP_INTEGER(minus_b); 02827 neg_assign(minus_b, b); 02828 const Coefficient& sc_b = is_sc ? b : minus_b; 02829 const Coefficient& minus_sc_b = is_sc ? minus_b : b; 02830 const Coefficient& sc_den = is_sc ? denominator : minus_den; 02831 const Coefficient& minus_sc_den = is_sc ? minus_den : denominator; 02832 // NOTE: here, for optimization purposes, `minus_expr' is only assigned 02833 // when `denominator' is negative. Do not use it unless you are sure 02834 // it has been correctly assigned. 02835 Linear_Expression minus_expr; 02836 if (!is_sc) 02837 minus_expr = -expr; 02838 const Linear_Expression& sc_expr = is_sc ? expr : minus_expr; 02839 02840 DIRTY_TEMP(N, sum); 02841 // Indices of the variables that are unbounded in `this->dbm'. 02842 PPL_UNINITIALIZED(dimension_type, pinf_index); 02843 // Number of unbounded variables found. 02844 dimension_type pinf_count = 0; 02845 02846 // Speculative allocation of temporaries that are used in most 02847 // of the computational traces starting from this point (also loops). 02848 TEMP_INTEGER(minus_sc_i); 02849 DIRTY_TEMP(N, coeff_i); 02850 02851 switch (relsym) { 02852 case EQUAL: 02853 { 02854 DIRTY_TEMP(N, neg_sum); 02855 // Indices of the variables that are unbounded in `this->dbm'. 02856 PPL_UNINITIALIZED(dimension_type, neg_pinf_index); 02857 // Number of unbounded variables found. 02858 dimension_type neg_pinf_count = 0; 02859 02860 // Compute an upper approximation for `expr' into `sum', 02861 // taking into account the sign of `denominator'. 02862 02863 // Approximate the inhomogeneous term. 02864 assign_r(sum, sc_b, ROUND_UP); 02865 assign_r(neg_sum, minus_sc_b, ROUND_UP); 02866 02867 // Approximate the homogeneous part of `sc_expr'. 02868 // Note: indices above `w' can be disregarded, as they all have 02869 // a zero coefficient in `expr'. 02870 for (dimension_type i = w; i > 0; --i) { 02871 const Coefficient& sc_i = sc_expr.coefficient(Variable(i-1)); 02872 const int sign_i = sgn(sc_i); 02873 if (sign_i == 0) 02874 continue; 02875 if (sign_i > 0) { 02876 assign_r(coeff_i, sc_i, ROUND_UP); 02877 // Approximating `sc_expr'. 02878 if (pinf_count <= 1) { 02879 const N& approx_i = dbm_0[i]; 02880 if (!is_plus_infinity(approx_i)) 02881 add_mul_assign_r(sum, coeff_i, approx_i, ROUND_UP); 02882 else { 02883 ++pinf_count; 02884 pinf_index = i; 02885 } 02886 } 02887 // Approximating `-sc_expr'. 02888 if (neg_pinf_count <= 1) { 02889 const N& approx_minus_i = dbm[i][0]; 02890 if (!is_plus_infinity(approx_minus_i)) 02891 add_mul_assign_r(neg_sum, coeff_i, approx_minus_i, ROUND_UP); 02892 else { 02893 ++neg_pinf_count; 02894 neg_pinf_index = i; 02895 } 02896 } 02897 } 02898 else if (sign_i < 0) { 02899 neg_assign(minus_sc_i, sc_i); 02900 // Note: using temporary named `coeff_i' to store -coeff_i. 02901 assign_r(coeff_i, minus_sc_i, ROUND_UP); 02902 // Approximating `sc_expr'. 02903 if (pinf_count <= 1) { 02904 const N& approx_minus_i = dbm[i][0]; 02905 if (!is_plus_infinity(approx_minus_i)) 02906 add_mul_assign_r(sum, coeff_i, approx_minus_i, ROUND_UP); 02907 else { 02908 ++pinf_count; 02909 pinf_index = i; 02910 } 02911 } 02912 // Approximating `-sc_expr'. 02913 if (neg_pinf_count <= 1) { 02914 const N& approx_i = dbm_0[i]; 02915 if (!is_plus_infinity(approx_i)) 02916 add_mul_assign_r(neg_sum, coeff_i, approx_i, ROUND_UP); 02917 else { 02918 ++neg_pinf_count; 02919 neg_pinf_index = i; 02920 } 02921 } 02922 } 02923 } 02924 // Return immediately if no approximation could be computed. 02925 if (pinf_count > 1 && neg_pinf_count > 1) { 02926 assert(OK()); 02927 return; 02928 } 02929 02930 // In the following, shortest-path closure will be definitely lost. 02931 reset_shortest_path_closed(); 02932 02933 // Before computing quotients, the denominator should be approximated 02934 // towards zero. Since `sc_den' is known to be positive, this amounts to 02935 // rounding downwards, which is achieved as usual by rounding upwards 02936 // `minus_sc_den' and negating again the result. 02937 DIRTY_TEMP(N, down_sc_den); 02938 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 02939 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 02940 02941 // Exploit the upper approximation, if possible. 02942 if (pinf_count <= 1) { 02943 // Compute quotient (if needed). 02944 if (down_sc_den != 1) 02945 div_assign_r(sum, sum, down_sc_den, ROUND_UP); 02946 // Add the upper bound constraint, if meaningful. 02947 if (pinf_count == 0) { 02948 // Add the constraint `v <= sum'. 02949 dbm[0][v] = sum; 02950 // Deduce constraints of the form `v - u', where `u != v'. 02951 deduce_v_minus_u_bounds(v, w, sc_expr, sc_den, sum); 02952 } 02953 else 02954 // Here `pinf_count == 1'. 02955 if (pinf_index != v 02956 && sc_expr.coefficient(Variable(pinf_index-1)) == sc_den) 02957 // Add the constraint `v - pinf_index <= sum'. 02958 dbm[pinf_index][v] = sum; 02959 } 02960 02961 // Exploit the lower approximation, if possible. 02962 if (neg_pinf_count <= 1) { 02963 // Compute quotient (if needed). 02964 if (down_sc_den != 1) 02965 div_assign_r(neg_sum, neg_sum, down_sc_den, ROUND_UP); 02966 // Add the lower bound constraint, if meaningful. 02967 if (neg_pinf_count == 0) { 02968 // Add the constraint `v >= -neg_sum', i.e., `-v <= neg_sum'. 02969 DB_Row<N>& dbm_v = dbm[v]; 02970 dbm_v[0] = neg_sum; 02971 // Deduce constraints of the form `u - v', where `u != v'. 02972 deduce_u_minus_v_bounds(v, w, sc_expr, sc_den, neg_sum); 02973 } 02974 else 02975 // Here `neg_pinf_count == 1'. 02976 if (neg_pinf_index != v 02977 && sc_expr.coefficient(Variable(neg_pinf_index-1)) == sc_den) 02978 // Add the constraint `v - neg_pinf_index >= -neg_sum', 02979 // i.e., `neg_pinf_index - v <= neg_sum'. 02980 dbm[v][neg_pinf_index] = neg_sum; 02981 } 02982 } 02983 break; 02984 02985 case LESS_OR_EQUAL: 02986 // Compute an upper approximation for `expr' into `sum', 02987 // taking into account the sign of `denominator'. 02988 02989 // Approximate the inhomogeneous term. 02990 assign_r(sum, sc_b, ROUND_UP); 02991 02992 // Approximate the homogeneous part of `sc_expr'. 02993 // Note: indices above `w' can be disregarded, as they all have 02994 // a zero coefficient in `expr'. 02995 for (dimension_type i = w; i > 0; --i) { 02996 const Coefficient& sc_i = sc_expr.coefficient(Variable(i-1)); 02997 const int sign_i = sgn(sc_i); 02998 if (sign_i == 0) 02999 continue; 03000 // Choose carefully: we are approximating `sc_expr'. 03001 const N& approx_i = (sign_i > 0) ? dbm_0[i] : dbm[i][0]; 03002 if (is_plus_infinity(approx_i)) { 03003 if (++pinf_count > 1) 03004 break; 03005 pinf_index = i; 03006 continue; 03007 } 03008 if (sign_i > 0) 03009 assign_r(coeff_i, sc_i, ROUND_UP); 03010 else { 03011 neg_assign(minus_sc_i, sc_i); 03012 assign_r(coeff_i, minus_sc_i, ROUND_UP); 03013 } 03014 add_mul_assign_r(sum, coeff_i, approx_i, ROUND_UP); 03015 } 03016 03017 // Divide by the (sign corrected) denominator (if needed). 03018 if (sc_den != 1) { 03019 // Before computing the quotient, the denominator should be 03020 // approximated towards zero. Since `sc_den' is known to be 03021 // positive, this amounts to rounding downwards, which is achieved 03022 // by rounding upwards `minus_sc-den' and negating again the result. 03023 DIRTY_TEMP(N, down_sc_den); 03024 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 03025 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 03026 div_assign_r(sum, sum, down_sc_den, ROUND_UP); 03027 } 03028 03029 if (pinf_count == 0) { 03030 // Add the constraint `v <= sum'. 03031 add_dbm_constraint(0, v, sum); 03032 // Deduce constraints of the form `v - u', where `u != v'. 03033 deduce_v_minus_u_bounds(v, w, sc_expr, sc_den, sum); 03034 } 03035 else if (pinf_count == 1) 03036 if (expr.coefficient(Variable(pinf_index-1)) == denominator) 03037 // Add the constraint `v - pinf_index <= sum'. 03038 add_dbm_constraint(pinf_index, v, sum); 03039 break; 03040 03041 case GREATER_OR_EQUAL: 03042 // Compute an upper approximation for `-sc_expr' into `sum'. 03043 // Note: approximating `-sc_expr' from above and then negating the 03044 // result is the same as approximating `sc_expr' from below. 03045 03046 // Approximate the inhomogeneous term. 03047 assign_r(sum, minus_sc_b, ROUND_UP); 03048 03049 // Approximate the homogeneous part of `-sc_expr'. 03050 for (dimension_type i = w; i > 0; --i) { 03051 const Coefficient& sc_i = sc_expr.coefficient(Variable(i-1)); 03052 const int sign_i = sgn(sc_i); 03053 if (sign_i == 0) 03054 continue; 03055 // Choose carefully: we are approximating `-sc_expr'. 03056 const N& approx_i = (sign_i > 0) ? dbm[i][0] : dbm_0[i]; 03057 if (is_plus_infinity(approx_i)) { 03058 if (++pinf_count > 1) 03059 break; 03060 pinf_index = i; 03061 continue; 03062 } 03063 if (sign_i > 0) 03064 assign_r(coeff_i, sc_i, ROUND_UP); 03065 else { 03066 neg_assign(minus_sc_i, sc_i); 03067 assign_r(coeff_i, minus_sc_i, ROUND_UP); 03068 } 03069 add_mul_assign_r(sum, coeff_i, approx_i, ROUND_UP); 03070 } 03071 03072 // Divide by the (sign corrected) denominator (if needed). 03073 if (sc_den != 1) { 03074 // Before computing the quotient, the denominator should be 03075 // approximated towards zero. Since `sc_den' is known to be positive, 03076 // this amounts to rounding downwards, which is achieved by rounding 03077 // upwards `minus_sc_den' and negating again the result. 03078 DIRTY_TEMP(N, down_sc_den); 03079 assign_r(down_sc_den, minus_sc_den, ROUND_UP); 03080 neg_assign_r(down_sc_den, down_sc_den, ROUND_UP); 03081 div_assign_r(sum, sum, down_sc_den, ROUND_UP); 03082 } 03083 03084 if (pinf_count == 0) { 03085 // Add the constraint `v >= -sum', i.e., `-v <= sum'. 03086 add_dbm_constraint(v, 0, sum); 03087 // Deduce constraints of the form `u - v', where `u != v'. 03088 deduce_u_minus_v_bounds(v, w, sc_expr, sc_den, sum); 03089 } 03090 else if (pinf_count == 1) 03091 if (pinf_index != v 03092 && expr.coefficient(Variable(pinf_index-1)) == denominator) 03093 // Add the constraint `v - pinf_index >= -sum', 03094 // i.e., `pinf_index - v <= sum'. 03095 add_dbm_constraint(v, pinf_index, sum); 03096 break; 03097 03098 default: 03099 // We already dealt with the other cases. 03100 throw std::runtime_error("PPL internal error"); 03101 } 03102 03103 assert(OK()); 03104 }
| void Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints | ( | dimension_type | v | ) | [inline, private] |
Removes all the constraints on row/column v.
Definition at line 2650 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, and PLUS_INFINITY.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), and Parma_Polyhedra_Library::BD_Shape< T >::unconstrain().
02650 { 02651 assert(0 < v && v <= dbm.num_rows()); 02652 DB_Row<N>& dbm_v = dbm[v]; 02653 for (dimension_type i = dbm.num_rows(); i-- > 0; ) { 02654 assign_r(dbm_v[i], PLUS_INFINITY, ROUND_NOT_NEEDED); 02655 assign_r(dbm[i][v], PLUS_INFINITY, ROUND_NOT_NEEDED); 02656 } 02657 }
| void Parma_Polyhedra_Library::BD_Shape< T >::forget_binary_dbm_constraints | ( | dimension_type | v | ) | [inline, private] |
Removes all binary constraints on row/column v.
Definition at line 2661 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, and PLUS_INFINITY.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), and Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image().
02661 { 02662 assert(0 < v && v <= dbm.num_rows()); 02663 DB_Row<N>& dbm_v = dbm[v]; 02664 for (dimension_type i = dbm.num_rows()-1; i > 0; --i) { 02665 assign_r(dbm_v[i], PLUS_INFINITY, ROUND_NOT_NEEDED); 02666 assign_r(dbm[i][v], PLUS_INFINITY, ROUND_NOT_NEEDED); 02667 } 02668 }
| void Parma_Polyhedra_Library::BD_Shape< T >::deduce_v_minus_u_bounds | ( | dimension_type | v, | |
| dimension_type | last_v, | |||
| const Linear_Expression & | sc_expr, | |||
| Coefficient_traits::const_reference | sc_den, | |||
| const N & | ub_v | |||
| ) | [inline, private] |
An helper function for the computation of affine relations.
For each dbm index u (less than or equal to last_v and different from v), deduce constraints of the form v - u <= c, starting from ub_v which is an upper bound for v.
The shortest-path closure is able to deduce the constraint v - u <= ub_v - lb_u. We can be more precise if variable u played an active role in the computation of the upper bound for v, i.e., if the corresponding coefficient q == sc_expr[u]/sc_den is greater than zero. In particular:
q >= 1, then v - u <= ub_v - ub_u;0 < q < 1, then v - u <= ub_v - (q*ub_u + (1-q)*lb_u). Definition at line 2528 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, and Parma_Polyhedra_Library::is_plus_infinity().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), and Parma_Polyhedra_Library::BD_Shape< T >::refine().
02532 { 02533 assert(sc_den > 0); 02534 assert(!is_plus_infinity(ub_v)); 02535 // Deduce constraints of the form `v - u', where `u != v'. 02536 // Note: the shortest-path closure is able to deduce the constraint 02537 // `v - u <= ub_v - lb_u'. We can be more precise if variable `u' 02538 // played an active role in the computation of the upper bound for `v', 02539 // i.e., if the corresponding coefficient `q == expr_u/den' is 02540 // greater than zero. In particular: 02541 // if `q >= 1', then `v - u <= ub_v - ub_u'; 02542 // if `0 < q < 1', then `v - u <= ub_v - (q*ub_u + (1-q)*lb_u)'. 02543 DIRTY_TEMP0(mpq_class, mpq_sc_den); 02544 assign_r(mpq_sc_den, sc_den, ROUND_NOT_NEEDED); 02545 const DB_Row<N>& dbm_0 = dbm[0]; 02546 // Speculative allocation of temporaries to be used in the following loop. 02547 DIRTY_TEMP0(mpq_class, minus_lb_u); 02548 DIRTY_TEMP0(mpq_class, q); 02549 DIRTY_TEMP0(mpq_class, ub_u); 02550 DIRTY_TEMP(N, up_approx); 02551 // No need to consider indices greater than `last_v'. 02552 for (dimension_type u = last_v; u > 0; --u) 02553 if (u != v) { 02554 const Coefficient& expr_u = sc_expr.coefficient(Variable(u-1)); 02555 if (expr_u > 0) { 02556 if (expr_u >= sc_den) 02557 // Deducing `v - u <= ub_v - ub_u'. 02558 sub_assign_r(dbm[u][v], ub_v, dbm_0[u], ROUND_UP); 02559 else { 02560 DB_Row<N>& dbm_u = dbm[u]; 02561 const N& dbm_u0 = dbm_u[0]; 02562 if (!is_plus_infinity(dbm_u0)) { 02563 // Let `ub_u' and `lb_u' be the known upper and lower bound 02564 // for `u', respectively. Letting `q = expr_u/sc_den' be the 02565 // rational coefficient of `u' in `sc_expr/sc_den', 02566 // the upper bound for `v - u' is computed as 02567 // `ub_v - (q * ub_u + (1-q) * lb_u)', i.e., 02568 // `ub_v + (-lb_u) - q * (ub_u + (-lb_u))'. 02569 assign_r(minus_lb_u, dbm_u0, ROUND_NOT_NEEDED); 02570 assign_r(q, expr_u, ROUND_NOT_NEEDED); 02571 div_assign_r(q, q, mpq_sc_den, ROUND_NOT_NEEDED); 02572 assign_r(ub_u, dbm_0[u], ROUND_NOT_NEEDED); 02573 // Compute `ub_u - lb_u'. 02574 add_assign_r(ub_u, ub_u, minus_lb_u, ROUND_NOT_NEEDED); 02575 // Compute `(-lb_u) - q * (ub_u - lb_u)'. 02576 sub_mul_assign_r(minus_lb_u, q, ub_u, ROUND_NOT_NEEDED); 02577 assign_r(up_approx, minus_lb_u, ROUND_UP); 02578 // Deducing `v - u <= ub_v - (q * ub_u + (1-q) * lb_u)'. 02579 add_assign_r(dbm_u[v], ub_v, up_approx, ROUND_UP); 02580 } 02581 } 02582 } 02583 } 02584 }
| void Parma_Polyhedra_Library::BD_Shape< T >::deduce_u_minus_v_bounds | ( | dimension_type | v, | |
| dimension_type | last_v, | |||
| const Linear_Expression & | sc_expr, | |||
| Coefficient_traits::const_reference | sc_den, | |||
| const N & | minus_lb_v | |||
| ) | [inline, private] |
An helper function for the computation of affine relations.
For each dbm index u (less than or equal to last_v and different from v), deduce constraints of the form u - v <= c, starting from minus_lb_v which is a lower bound for v.
The shortest-path closure is able to deduce the constraint u - v <= ub_u - lb_v. We can be more precise if variable u played an active role in the computation of the lower bound for v, i.e., if the corresponding coefficient q == sc_expr[u]/sc_den is greater than zero. In particular:
q >= 1, then u - v <= lb_u - lb_v;0 < q < 1, then u - v <= (q*lb_u + (1-q)*ub_u) - lb_v. Definition at line 2589 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, and Parma_Polyhedra_Library::is_plus_infinity().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), and Parma_Polyhedra_Library::BD_Shape< T >::refine().
02593 { 02594 assert(sc_den > 0); 02595 assert(!is_plus_infinity(minus_lb_v)); 02596 // Deduce constraints of the form `u - v', where `u != v'. 02597 // Note: the shortest-path closure is able to deduce the constraint 02598 // `u - v <= ub_u - lb_v'. We can be more precise if variable `u' 02599 // played an active role in the computation of the lower bound for `v', 02600 // i.e., if the corresponding coefficient `q == expr_u/den' is 02601 // greater than zero. In particular: 02602 // if `q >= 1', then `u - v <= lb_u - lb_v'; 02603 // if `0 < q < 1', then `u - v <= (q*lb_u + (1-q)*ub_u) - lb_v'. 02604 DIRTY_TEMP0(mpq_class, mpq_sc_den); 02605 assign_r(mpq_sc_den, sc_den, ROUND_NOT_NEEDED); 02606 DB_Row<N>& dbm_0 = dbm[0]; 02607 DB_Row<N>& dbm_v = dbm[v]; 02608 // Speculative allocation of temporaries to be used in the following loop. 02609 DIRTY_TEMP0(mpq_class, ub_u); 02610 DIRTY_TEMP0(mpq_class, q); 02611 DIRTY_TEMP0(mpq_class, minus_lb_u); 02612 DIRTY_TEMP(N, up_approx); 02613 // No need to consider indices greater than `last_v'. 02614 for (dimension_type u = last_v; u > 0; --u) 02615 if (u != v) { 02616 const Coefficient& expr_u = sc_expr.coefficient(Variable(u-1)); 02617 if (expr_u > 0) { 02618 if (expr_u >= sc_den) 02619 // Deducing `u - v <= lb_u - lb_v', 02620 // i.e., `u - v <= (-lb_v) - (-lb_u)'. 02621 sub_assign_r(dbm_v[u], minus_lb_v, dbm[u][0], ROUND_UP); 02622 else { 02623 const N& dbm_0u = dbm_0[u]; 02624 if (!is_plus_infinity(dbm_0u)) { 02625 // Let `ub_u' and `lb_u' be the known upper and lower bound 02626 // for `u', respectively. Letting `q = expr_u/sc_den' be the 02627 // rational coefficient of `u' in `sc_expr/sc_den', 02628 // the upper bound for `u - v' is computed as 02629 // `(q * lb_u + (1-q) * ub_u) - lb_v', i.e., 02630 // `ub_u - q * (ub_u + (-lb_u)) + minus_lb_v'. 02631 assign_r(ub_u, dbm_0u, ROUND_NOT_NEEDED); 02632 assign_r(q, expr_u, ROUND_NOT_NEEDED); 02633 div_assign_r(q, q, mpq_sc_den, ROUND_NOT_NEEDED); 02634 assign_r(minus_lb_u, dbm[u][0], ROUND_NOT_NEEDED); 02635 // Compute `ub_u - lb_u'. 02636 add_assign_r(minus_lb_u, minus_lb_u, ub_u, ROUND_NOT_NEEDED); 02637 // Compute `ub_u - q * (ub_u - lb_u)'. 02638 sub_mul_assign_r(ub_u, q, minus_lb_u, ROUND_NOT_NEEDED); 02639 assign_r(up_approx, ub_u, ROUND_UP); 02640 // Deducing `u - v <= (q*lb_u + (1-q)*ub_u) - lb_v'. 02641 add_assign_r(dbm_v[u], up_approx, minus_lb_v, ROUND_UP); 02642 } 02643 } 02644 } 02645 } 02646 }
| void Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape | ( | const Constraint_System & | cs, | |
| BD_Shape< T > & | limiting_shape | |||
| ) | const [inline, private] |
Adds to limiting_shape the bounded differences in cs that are satisfied by *this.
Definition at line 2240 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::div_round_up(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::BD_Shape< T >::extract_bounded_difference(), Parma_Polyhedra_Library::Constraint::inhomogeneous_term(), Parma_Polyhedra_Library::Constraint::is_inequality(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and TEMP_INTEGER.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign().
02241 { 02242 const dimension_type cs_space_dim = cs.space_dimension(); 02243 // Private method: the caller has to ensure the following. 02244 assert(cs_space_dim <= space_dimension()); 02245 02246 shortest_path_closure_assign(); 02247 bool changed = false; 02248 TEMP_INTEGER(coeff); 02249 TEMP_INTEGER(minus_c_term); 02250 DIRTY_TEMP(N, d); 02251 DIRTY_TEMP(N, d1); 02252 for (Constraint_System::const_iterator cs_i = cs.begin(), 02253 cs_end = cs.end(); cs_i != cs_end; ++cs_i) { 02254 const Constraint& c = *cs_i; 02255 dimension_type num_vars = 0; 02256 dimension_type i = 0; 02257 dimension_type j = 0; 02258 // Constraints that are not bounded differences are ignored. 02259 if (extract_bounded_difference(c, cs_space_dim, num_vars, i, j, coeff)) { 02260 // Select the cell to be modified for the "<=" part of the constraint, 02261 // and set `coeff' to the absolute value of itself. 02262 const bool negative = (coeff < 0); 02263 const N& x = negative ? dbm[i][j] : dbm[j][i]; 02264 const N& y = negative ? dbm[j][i] : dbm[i][j]; 02265 DB_Matrix<N>& ls_dbm = limiting_shape.dbm; 02266 N& ls_x = negative ? ls_dbm[i][j] : ls_dbm[j][i]; 02267 N& ls_y = negative ? ls_dbm[j][i] : ls_dbm[i][j]; 02268 if (negative) 02269 neg_assign(coeff); 02270 // Compute the bound for `x', rounding towards plus infinity. 02271 div_round_up(d, c.inhomogeneous_term(), coeff); 02272 if (x <= d) { 02273 if (c.is_inequality()) { 02274 if (ls_x > d) { 02275 ls_x = d; 02276 changed = true; 02277 } 02278 } 02279 else { 02280 // Compute the bound for `y', rounding towards plus infinity. 02281 neg_assign(minus_c_term, c.inhomogeneous_term()); 02282 div_round_up(d1, minus_c_term, coeff); 02283 if (y <= d1) 02284 if((ls_x >= d && ls_y > d1) || (ls_x > d && ls_y >= d1)) { 02285 ls_x = d; 02286 ls_y = d1; 02287 changed = true; 02288 } 02289 } 02290 } 02291 } 02292 } 02293 02294 // In general, adding a constraint does not preserve the shortest-path 02295 // closure of the bounded difference shape. 02296 if (changed && limiting_shape.marked_shortest_path_closed()) 02297 limiting_shape.reset_shortest_path_closed(); 02298 }
| void Parma_Polyhedra_Library::BD_Shape< T >::compute_predecessors | ( | std::vector< dimension_type > & | predecessor | ) | const [inline, private] |
Compute the (zero-equivalence classes) predecessor relation.
It is assumed that the BDS is not empty and shortest-path closed.
Definition at line 795 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::is_additive_inverse(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::affine_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::compute_leaders(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign().
00795 { 00796 assert(!marked_empty() && marked_shortest_path_closed()); 00797 assert(predecessor.size() == 0); 00798 // Variables are ordered according to their index. 00799 // The vector `predecessor' is used to indicate which variable 00800 // immediately precedes a given one in the corresponding equivalence class. 00801 // The `leader' of an equivalence class is the element having minimum 00802 // index: leaders are their own predecessors. 00803 const dimension_type pred_size = dbm.num_rows(); 00804 // Initially, each variable is leader of its own zero-equivalence class. 00805 predecessor.reserve(pred_size); 00806 for (dimension_type i = 0; i < pred_size; ++i) 00807 predecessor.push_back(i); 00808 // Now compute actual predecessors. 00809 for (dimension_type i = pred_size; i-- > 1; ) 00810 if (i == predecessor[i]) { 00811 const DB_Row<N>& dbm_i = dbm[i]; 00812 for (dimension_type j = i; j-- > 0; ) 00813 if (j == predecessor[j] 00814 && is_additive_inverse(dbm[j][i], dbm_i[j])) { 00815 // Choose as predecessor the variable having the smaller index. 00816 predecessor[i] = j; 00817 break; 00818 } 00819 } 00820 }
| void Parma_Polyhedra_Library::BD_Shape< T >::compute_leaders | ( | std::vector< dimension_type > & | leaders | ) | const [inline, private] |
Compute the leaders of zero-equivalence classes.
It is assumed that the BDS is not empty and shortest-path closed.
Definition at line 824 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::compute_predecessors(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), and Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::minimized_congruences(), and Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints().
00824 { 00825 assert(!marked_empty() && marked_shortest_path_closed()); 00826 assert(leaders.size() == 0); 00827 // Compute predecessor information. 00828 compute_predecessors(leaders); 00829 // Flatten the predecessor chains so as to obtain leaders. 00830 assert(leaders[0] == 0); 00831 for (dimension_type i = 1, l_size = leaders.size(); i != l_size; ++i) { 00832 const dimension_type l_i = leaders[i]; 00833 assert(l_i <= i); 00834 if (l_i != i) { 00835 const dimension_type ll_i = leaders[l_i]; 00836 assert(ll_i == leaders[ll_i]); 00837 leaders[i] = ll_i; 00838 } 00839 } 00840 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible | ( | const char * | method, | |
| const BD_Shape< T > & | x | |||
| ) | const [inline, private] |
Definition at line 5153 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::bounds(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::constrains(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::difference_assign(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::is_disjoint_from(), Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::max_min(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::relation_with(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::time_elapse_assign(), Parma_Polyhedra_Library::BD_Shape< T >::unconstrain(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
05154 { 05155 std::ostringstream s; 05156 s << "PPL::BD_Shape::" << method << ":" << std::endl 05157 << "this->space_dimension() == " << space_dimension() 05158 << ", y->space_dimension() == " << y.space_dimension() << "."; 05159 throw std::invalid_argument(s.str()); 05160 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible | ( | const char * | method, | |
| dimension_type | required_dim | |||
| ) | const [inline, private] |
Definition at line 5164 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
05165 { 05166 std::ostringstream s; 05167 s << "PPL::BD_Shape::" << method << ":" << std::endl 05168 << "this->space_dimension() == " << space_dimension() 05169 << ", required dimension == " << required_dim << "."; 05170 throw std::invalid_argument(s.str()); 05171 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible | ( | const char * | method, | |
| const Constraint & | c | |||
| ) | const [inline, private] |
Definition at line 5175 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Constraint::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
05176 { 05177 std::ostringstream s; 05178 s << "PPL::BD_Shape::" << method << ":" << std::endl 05179 << "this->space_dimension() == " << space_dimension() 05180 << ", c->space_dimension == " << c.space_dimension() << "."; 05181 throw std::invalid_argument(s.str()); 05182 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible | ( | const char * | method, | |
| const Congruence & | cg | |||
| ) | const [inline, private] |
Definition at line 5186 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Congruence::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
05187 { 05188 std::ostringstream s; 05189 s << "PPL::BD_Shape::" << method << ":" << std::endl 05190 << "this->space_dimension() == " << space_dimension() 05191 << ", cg->space_dimension == " << cg.space_dimension() << "."; 05192 throw std::invalid_argument(s.str()); 05193 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible | ( | const char * | method, | |
| const Generator & | g | |||
| ) | const [inline, private] |
Definition at line 5197 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Generator::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
05198 { 05199 std::ostringstream s; 05200 s << "PPL::BD_Shape::" << method << ":" << std::endl 05201 << "this->space_dimension() == " << space_dimension() 05202 << ", g->space_dimension == " << g.space_dimension() << "."; 05203 throw std::invalid_argument(s.str()); 05204 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_dimension_incompatible | ( | const char * | method, | |
| const char * | name_row, | |||
| const Linear_Expression & | y | |||
| ) | const [inline, private] |
Definition at line 5220 of file BD_Shape.templates.hh.
References Parma_Polyhedra_Library::Linear_Expression::space_dimension(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
05222 { 05223 std::ostringstream s; 05224 s << "PPL::BD_Shape::" << method << ":" << std::endl 05225 << "this->space_dimension() == " << space_dimension() 05226 << ", " << name_row << "->space_dimension() == " 05227 << y.space_dimension() << "."; 05228 throw std::invalid_argument(s.str()); 05229 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_expression_too_complex | ( | const char * | method, | |
| const Linear_Expression & | e | |||
| ) | [inline, static, private] |
Definition at line 5208 of file BD_Shape.templates.hh.
05209 { 05210 using namespace IO_Operators; 05211 std::ostringstream s; 05212 s << "PPL::BD_Shape::" << method << ":" << std::endl 05213 << e << " is too complex."; 05214 throw std::invalid_argument(s.str()); 05215 }
| void Parma_Polyhedra_Library::BD_Shape< T >::throw_generic | ( | const char * | method, | |
| const char * | reason | |||
| ) | [inline, static, private] |
Definition at line 5233 of file BD_Shape.templates.hh.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_congruence(), Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_preimage(), Parma_Polyhedra_Library::BD_Shape< T >::limited_BHMZ05_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::limited_CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::refine_with_congruences(), and Parma_Polyhedra_Library::BD_Shape< T >::refine_with_constraints().
05233 { 05234 std::ostringstream s; 05235 s << "PPL::BD_Shape::" << method << ":" << std::endl 05236 << reason << "."; 05237 throw std::invalid_argument(s.str()); 05238 }
friend class Parma_Polyhedra_Library::BD_Shape [friend] |
Definition at line 1806 of file BD_Shape.defs.hh.
friend class Parma_Polyhedra_Library::Box [friend] |
Definition at line 1807 of file BD_Shape.defs.hh.
Returns true if and only if x and y are the same BDS.
Note that x and y may be dimension-incompatible shapes: in this case, the value false is returned.
Definition at line 466 of file BD_Shape.inlines.hh.
00466 { 00467 const dimension_type x_space_dim = x.space_dimension(); 00468 // Dimension-compatibility check. 00469 if (x_space_dim != y.space_dimension()) 00470 return false; 00471 00472 // Zero-dim BDSs are equal if and only if they are both empty or universe. 00473 if (x_space_dim == 0) { 00474 if (x.marked_empty()) 00475 return y.marked_empty(); 00476 else 00477 return !y.marked_empty(); 00478 } 00479 00480 // The exact equivalence test requires shortest-path closure. 00481 x.shortest_path_closure_assign(); 00482 y.shortest_path_closure_assign(); 00483 00484 // If one of two BDSs is empty, then they are equal 00485 // if and only if the other BDS is empty too. 00486 if (x.marked_empty()) 00487 return y.marked_empty(); 00488 if (y.marked_empty()) 00489 return false; 00490 // Check for syntactic equivalence of the two (shortest-path closed) 00491 // systems of bounded differences. 00492 return x.dbm == y.dbm; 00493 }
| bool rectilinear_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< U > & | x, | |||
| const BD_Shape< U > & | y, | |||
| const Rounding_Dir | dir, | |||
| Temp & | tmp0, | |||
| Temp & | tmp1, | |||
| Temp & | tmp2 | |||
| ) | [friend] |
| bool euclidean_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< U > & | x, | |||
| const BD_Shape< U > & | y, | |||
| const Rounding_Dir | dir, | |||
| Temp & | tmp0, | |||
| Temp & | tmp1, | |||
| Temp & | tmp2 | |||
| ) | [friend] |
| bool l_infinity_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< U > & | x, | |||
| const BD_Shape< U > & | y, | |||
| const Rounding_Dir | dir, | |||
| Temp & | tmp0, | |||
| Temp & | tmp1, | |||
| Temp & | tmp2 | |||
| ) | [friend] |
| std::ostream & operator<< | ( | std::ostream & | s, | |
| const BD_Shape< T > & | c | |||
| ) | [friend] |
Output operator.
Writes a textual representation of bds on s: false is written if bds is an empty polyhedron; true is written if bds is the universe polyhedron; a system of constraints defining bds is written otherwise, all constraints separated by ", ".
Definition at line 4922 of file BD_Shape.templates.hh.
04922 { 04923 typedef typename BD_Shape<T>::coefficient_type N; 04924 if (c.is_universe()) 04925 s << "true"; 04926 else { 04927 // We control empty bounded difference shape. 04928 dimension_type n = c.space_dimension(); 04929 if (c.marked_empty()) 04930 s << "false"; 04931 else { 04932 DIRTY_TEMP(N, v); 04933 bool first = true; 04934 for (dimension_type i = 0; i <= n; ++i) 04935 for (dimension_type j = i + 1; j <= n; ++j) { 04936 const N& c_i_j = c.dbm[i][j]; 04937 const N& c_j_i = c.dbm[j][i]; 04938 if (is_additive_inverse(c_j_i, c_i_j)) { 04939 // We will print an equality. 04940 if (first) 04941 first = false; 04942 else 04943 s << ", "; 04944 if (i == 0) { 04945 // We have got a equality constraint with one Variable. 04946 s << Variable(j - 1); 04947 s << " == " << c_i_j; 04948 } 04949 else { 04950 // We have got a equality constraint with two Variables. 04951 if (sgn(c_i_j) >= 0) { 04952 s << Variable(j - 1); 04953 s << " - "; 04954 s << Variable(i - 1); 04955 s << " == " << c_i_j; 04956 } 04957 else { 04958 s << Variable(i - 1); 04959 s << " - "; 04960 s << Variable(j - 1); 04961 s << " == " << c_j_i; 04962 } 04963 } 04964 } 04965 else { 04966 // We will print a non-strict inequality. 04967 if (!is_plus_infinity(c_j_i)) { 04968 if (first) 04969 first = false; 04970 else 04971 s << ", "; 04972 if (i == 0) { 04973 // We have got a constraint with an only Variable. 04974 s << Variable(j - 1); 04975 neg_assign_r(v, c_j_i, ROUND_DOWN); 04976 s << " >= " << v; 04977 } 04978 else { 04979 // We have got a constraint with two Variables. 04980 if (sgn(c_j_i) >= 0) { 04981 s << Variable(i - 1); 04982 s << " - "; 04983 s << Variable(j - 1); 04984 s << " <= " << c_j_i; 04985 } 04986 else { 04987 s << Variable(j - 1); 04988 s << " - "; 04989 s << Variable(i - 1); 04990 neg_assign_r(v, c_j_i, ROUND_DOWN); 04991 s << " >= " << v; 04992 } 04993 } 04994 } 04995 if (!is_plus_infinity(c_i_j)) { 04996 if (first) 04997 first = false; 04998 else 04999 s << ", "; 05000 if (i == 0) { 05001 // We have got a constraint with an only Variable. 05002 s << Variable(j - 1); 05003 s << " <= " << c_i_j; 05004 } 05005 else { 05006 // We have got a constraint with two Variables. 05007 if (sgn(c_i_j) >= 0) { 05008 s << Variable(j - 1); 05009 s << " - "; 05010 s << Variable(i - 1); 05011 s << " <= " << c_i_j; 05012 } 05013 else { 05014 s << Variable(i - 1); 05015 s << " - "; 05016 s << Variable(j - 1); 05017 neg_assign_r(v, c_i_j, ROUND_DOWN); 05018 s << " >= " << v; 05019 } 05020 } 05021 } 05022 } 05023 } 05024 } 05025 } 05026 return s; 05027 }
Returns true if and only if x and y aren't the same BDS.
Note that x and y may be dimension-incompatible shapes: in this case, the value true is returned.
Definition at line 498 of file BD_Shape.inlines.hh.
| bool rectilinear_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< T > & | x, | |||
| const BD_Shape< T > & | y, | |||
| Rounding_Dir | dir | |||
| ) | [related] |
Computes the rectilinear (or Manhattan) distance between x and y.
If the rectilinear distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using variables of type Checked_Number<To, Extended_Number_Policy>.
If the rectilinear distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using variables of type Checked_Number<Temp, Extended_Number_Policy>.
Definition at line 546 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::rectilinear_distance_assign.
00549 { 00550 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp; 00551 DIRTY_TEMP(Checked_Temp, tmp0); 00552 DIRTY_TEMP(Checked_Temp, tmp1); 00553 DIRTY_TEMP(Checked_Temp, tmp2); 00554 return rectilinear_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2); 00555 }
| bool rectilinear_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< T > & | x, | |||
| const BD_Shape< T > & | y, | |||
| Rounding_Dir | dir, | |||
| Temp & | tmp0, | |||
| Temp & | tmp1, | |||
| Temp & | tmp2 | |||
| ) | [related] |
Computes the rectilinear (or Manhattan) distance between x and y.
If the rectilinear distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using the temporary variables tmp0, tmp1 and tmp2.
Definition at line 505 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), PLUS_INFINITY, Parma_Polyhedra_Library::BD_Shape< T >::rectilinear_distance_assign, Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00511 { 00512 const dimension_type x_space_dim = x.space_dimension(); 00513 // Dimension-compatibility check. 00514 if (x_space_dim != y.space_dimension()) 00515 return false; 00516 00517 // Zero-dim BDSs are equal if and only if they are both empty or universe. 00518 if (x_space_dim == 0) { 00519 if (x.marked_empty() == y.marked_empty()) 00520 assign_r(r, 0, ROUND_NOT_NEEDED); 00521 else 00522 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED); 00523 return true; 00524 } 00525 00526 // The distance computation requires shortest-path closure. 00527 x.shortest_path_closure_assign(); 00528 y.shortest_path_closure_assign(); 00529 00530 // If one of two BDSs is empty, then they are equal if and only if 00531 // the other BDS is empty too. 00532 if (x.marked_empty() || y.marked_empty()) { 00533 if (x.marked_empty() == y.marked_empty()) 00534 assign_r(r, 0, ROUND_NOT_NEEDED); 00535 else 00536 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED); 00537 return true; 00538 } 00539 00540 return rectilinear_distance_assign(r, x.dbm, y.dbm, dir, tmp0, tmp1, tmp2); 00541 }
| bool euclidean_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< T > & | x, | |||
| const BD_Shape< T > & | y, | |||
| Rounding_Dir | dir | |||
| ) | [related] |
Computes the euclidean distance between x and y.
If the euclidean distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using variables of type Checked_Number<To, Extended_Number_Policy>.
If the euclidean distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using variables of type Checked_Number<Temp, Extended_Number_Policy>.
Definition at line 611 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::euclidean_distance_assign.
00614 { 00615 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp; 00616 DIRTY_TEMP(Checked_Temp, tmp0); 00617 DIRTY_TEMP(Checked_Temp, tmp1); 00618 DIRTY_TEMP(Checked_Temp, tmp2); 00619 return euclidean_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2); 00620 }
| bool euclidean_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< T > & | x, | |||
| const BD_Shape< T > & | y, | |||
| Rounding_Dir | dir, | |||
| Temp & | tmp0, | |||
| Temp & | tmp1, | |||
| Temp & | tmp2 | |||
| ) | [related] |
Computes the euclidean distance between x and y.
If the euclidean distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using the temporary variables tmp0, tmp1 and tmp2.
Definition at line 570 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::euclidean_distance_assign, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), PLUS_INFINITY, Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00576 { 00577 const dimension_type x_space_dim = x.space_dimension(); 00578 // Dimension-compatibility check. 00579 if (x_space_dim != y.space_dimension()) 00580 return false; 00581 00582 // Zero-dim BDSs are equal if and only if they are both empty or universe. 00583 if (x_space_dim == 0) { 00584 if (x.marked_empty() == y.marked_empty()) 00585 assign_r(r, 0, ROUND_NOT_NEEDED); 00586 else 00587 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED); 00588 return true; 00589 } 00590 00591 // The distance computation requires shortest-path closure. 00592 x.shortest_path_closure_assign(); 00593 y.shortest_path_closure_assign(); 00594 00595 // If one of two BDSs is empty, then they are equal if and only if 00596 // the other BDS is empty too. 00597 if (x.marked_empty() || y.marked_empty()) { 00598 if (x.marked_empty() == y.marked_empty()) 00599 assign_r(r, 0, ROUND_NOT_NEEDED); 00600 else 00601 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED); 00602 return true; 00603 } 00604 00605 return euclidean_distance_assign(r, x.dbm, y.dbm, dir, tmp0, tmp1, tmp2); 00606 }
| bool l_infinity_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< T > & | x, | |||
| const BD_Shape< T > & | y, | |||
| Rounding_Dir | dir | |||
| ) | [related] |
Computes the
distance between x and y.
If the
distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using variables of type Checked_Number<To, Extended_Number_Policy>.
If the
distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using variables of type Checked_Number<Temp, Extended_Number_Policy>.
Definition at line 676 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::l_infinity_distance_assign.
00679 { 00680 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp; 00681 DIRTY_TEMP(Checked_Temp, tmp0); 00682 DIRTY_TEMP(Checked_Temp, tmp1); 00683 DIRTY_TEMP(Checked_Temp, tmp2); 00684 return l_infinity_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2); 00685 }
| bool l_infinity_distance_assign | ( | Checked_Number< To, Extended_Number_Policy > & | r, | |
| const BD_Shape< T > & | x, | |||
| const BD_Shape< T > & | y, | |||
| Rounding_Dir | dir, | |||
| Temp & | tmp0, | |||
| Temp & | tmp1, | |||
| Temp & | tmp2 | |||
| ) | [related] |
Computes the
distance between x and y.
If the
distance between x and y is defined, stores an approximation of it into r and returns true; returns false otherwise.
The direction of the approximation is specified by dir.
All computations are performed using the temporary variables tmp0, tmp1 and tmp2.
Definition at line 635 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::assign_r(), Parma_Polyhedra_Library::BD_Shape< T >::dbm, Parma_Polyhedra_Library::BD_Shape< T >::l_infinity_distance_assign, Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), PLUS_INFINITY, Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::space_dimension().
00641 { 00642 const dimension_type x_space_dim = x.space_dimension(); 00643 // Dimension-compatibility check. 00644 if (x_space_dim != y.space_dimension()) 00645 return false; 00646 00647 // Zero-dim BDSs are equal if and only if they are both empty or universe. 00648 if (x_space_dim == 0) { 00649 if (x.marked_empty() == y.marked_empty()) 00650 assign_r(r, 0, ROUND_NOT_NEEDED); 00651 else 00652 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED); 00653 return true; 00654 } 00655 00656 // The distance computation requires shortest-path closure. 00657 x.shortest_path_closure_assign(); 00658 y.shortest_path_closure_assign(); 00659 00660 // If one of two BDSs is empty, then they are equal if and only if 00661 // the other BDS is empty too. 00662 if (x.marked_empty() || y.marked_empty()) { 00663 if (x.marked_empty() == y.marked_empty()) 00664 assign_r(r, 0, ROUND_NOT_NEEDED); 00665 else 00666 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED); 00667 return true; 00668 } 00669 00670 return l_infinity_distance_assign(r, x.dbm, y.dbm, dir, tmp0, tmp1, tmp2); 00671 }
| bool extract_bounded_difference | ( | const Constraint & | c, | |
| dimension_type | c_space_dim, | |||
| dimension_type & | c_num_vars, | |||
| dimension_type & | c_first_var, | |||
| dimension_type & | c_second_var, | |||
| Coefficient & | c_coeff | |||
| ) | [related] |
Decodes the constraint c as a bounded difference.
true if the constraint c is a bounded difference; false otherwise.| c | The constraint to be decoded. | |
| c_space_dim | The space dimension of the constraint c (it is assumed to match the actual space dimension of c). | |
| c_num_vars | If true is returned, then it will be set to the number of variables having a non-zero coefficient. The only legal values will therefore be 0, 1 and 2. | |
| c_first_var | If true is returned and if c_num_vars is not set to 0, then it will be set to the index of the first variable having a non-zero coefficient in c. | |
| c_second_var | If true is returned and if c_num_vars is set to 2, then it will be set to the index of the second variable having a non-zero coefficient in c. | |
| c_coeff | If true is returned and if c_num_vars is not set to 0, then it will be set to the value of the first non-zero coefficient in c. |
Definition at line 32 of file BD_Shape.cc.
References Parma_Polyhedra_Library::Constraint::coefficient(), and Parma_Polyhedra_Library::Constraint::space_dimension().
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::bounds(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::BD_Shape< T >::max_min(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), and Parma_Polyhedra_Library::BD_Shape< T >::relation_with().
00037 { 00038 // Check for preconditions. 00039 assert(c.space_dimension() == c_space_dim); 00040 assert(c_num_vars == 0 && c_first_var == 0 && c_second_var == 0); 00041 // Store the indices of the non-zero components of `c', 00042 dimension_type non_zero_index[2] = { 0, 0 }; 00043 // Collect the non-zero components of `c'. 00044 for (dimension_type i = c_space_dim; i-- > 0; ) 00045 if (c.coefficient(Variable(i)) != 0) { 00046 if (c_num_vars <= 1) 00047 non_zero_index[c_num_vars++] = i + 1; 00048 else 00049 // Constraint `c' is not a bounded difference. 00050 return false; 00051 } 00052 00053 // Make sure that `c' is indeed a bounded difference, 00054 // i.e., it has one of the following forms: 00055 // 0 <=/= b, if c_num_vars == 0; 00056 // a*x <=/= b, if c_num_vars == 1; 00057 // a*x - a*y <=/= b, if c_num_vars == 2. 00058 switch (c_num_vars) { 00059 case 2: 00060 { 00061 const Coefficient& c0 = c.coefficient(Variable(non_zero_index[0]-1)); 00062 const Coefficient& c1 = c.coefficient(Variable(non_zero_index[1]-1)); 00063 if (sgn(c0) == sgn(c1) || c0 != -c1) 00064 // Constraint `c' is not a bounded difference. 00065 return false; 00066 c_coeff = c1; 00067 } 00068 c_first_var = non_zero_index[0]; 00069 c_second_var = non_zero_index[1]; 00070 break; 00071 case 1: 00072 c_coeff = -c.coefficient(Variable(non_zero_index[0]-1)); 00073 c_first_var = non_zero_index[0]; 00074 break; 00075 default: 00076 assert(c_num_vars == 0); 00077 break; 00078 } 00079 return true; 00080 }
| void compute_leader_indices | ( | const std::vector< dimension_type > & | predecessor, | |
| std::vector< dimension_type > & | indices | |||
| ) | [related] |
Extracts leader indices from the predecessor relation.
Definition at line 86 of file BD_Shape.cc.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints(), and Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign().
00087 { 00088 // The vector `indices' contains one entry for each equivalence 00089 // class, storing the index of the corresponding leader in 00090 // increasing order: it is used to avoid repeated tests for leadership. 00091 assert(indices.size() == 0); 00092 assert(0 == predecessor[0]); 00093 indices.push_back(0); 00094 for (dimension_type i = 1, p_size = predecessor.size(); i != p_size; ++i) 00095 if (i == predecessor[i]) 00096 indices.push_back(i); 00097 }
| void swap | ( | Parma_Polyhedra_Library::BD_Shape< T > & | x, | |
| Parma_Polyhedra_Library::BD_Shape< T > & | y | |||
| ) | [related] |
Specializes std::swap.
Definition at line 874 of file BD_Shape.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::swap().
00875 { 00876 x.swap(y); 00877 }
DB_Matrix<N> Parma_Polyhedra_Library::BD_Shape< T >::dbm [private] |
The matrix representing the system of bounded differences.
Definition at line 1810 of file BD_Shape.defs.hh.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::add_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_dbm_constraint(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_embed(), Parma_Polyhedra_Library::BD_Shape< T >::add_space_dimensions_and_project(), Parma_Polyhedra_Library::BD_Shape< T >::affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::ascii_dump(), Parma_Polyhedra_Library::BD_Shape< T >::ascii_load(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::bounded_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::bounds(), Parma_Polyhedra_Library::Box< ITV >::Box(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_extrapolation_assign(), Parma_Polyhedra_Library::BD_Shape< T >::CC76_narrowing_assign(), Parma_Polyhedra_Library::BD_Shape< T >::compute_predecessors(), Parma_Polyhedra_Library::BD_Shape< T >::concatenate_assign(), Parma_Polyhedra_Library::BD_Shape< T >::constrains(), Parma_Polyhedra_Library::BD_Shape< T >::constraints(), Parma_Polyhedra_Library::BD_Shape< T >::contains(), Parma_Polyhedra_Library::BD_Shape< T >::contains_integer_point(), Parma_Polyhedra_Library::BD_Shape< T >::deduce_u_minus_v_bounds(), Parma_Polyhedra_Library::BD_Shape< T >::deduce_v_minus_u_bounds(), Parma_Polyhedra_Library::BD_Shape< T >::euclidean_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::expand_space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::external_memory_in_bytes(), Parma_Polyhedra_Library::BD_Shape< T >::fold_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::forget_all_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::forget_binary_dbm_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::generalized_affine_image(), Parma_Polyhedra_Library::BD_Shape< T >::get_limiting_shape(), Parma_Polyhedra_Library::BD_Shape< T >::intersection_assign(), Parma_Polyhedra_Library::BD_Shape< T >::is_bounded(), Parma_Polyhedra_Library::BD_Shape< T >::is_disjoint_from(), Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::is_universe(), Parma_Polyhedra_Library::BD_Shape< T >::l_infinity_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::map_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::max_min(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_congruences(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::operator=(), Parma_Polyhedra_Library::BD_Shape< T >::rectilinear_distance_assign(), Parma_Polyhedra_Library::BD_Shape< T >::refine(), Parma_Polyhedra_Library::BD_Shape< T >::refine_no_check(), Parma_Polyhedra_Library::BD_Shape< T >::relation_with(), Parma_Polyhedra_Library::BD_Shape< T >::remove_higher_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::remove_space_dimensions(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_closure_assign(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), Parma_Polyhedra_Library::BD_Shape< T >::space_dimension(), Parma_Polyhedra_Library::BD_Shape< T >::swap(), and Parma_Polyhedra_Library::BD_Shape< T >::upper_bound_assign().
Status Parma_Polyhedra_Library::BD_Shape< T >::status [private] |
The status flags to keep track of the internal state.
Definition at line 1932 of file BD_Shape.defs.hh.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::ascii_dump(), Parma_Polyhedra_Library::BD_Shape< T >::ascii_load(), Parma_Polyhedra_Library::BD_Shape< T >::marked_empty(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::marked_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::marked_zero_dim_univ(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::operator=(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::reset_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::set_empty(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_closed(), Parma_Polyhedra_Library::BD_Shape< T >::set_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::set_zero_dim_univ(), and Parma_Polyhedra_Library::BD_Shape< T >::swap().
Bit_Matrix Parma_Polyhedra_Library::BD_Shape< T >::redundancy_dbm [private] |
A matrix indicating which constraints are redundant.
Definition at line 1935 of file BD_Shape.defs.hh.
Referenced by Parma_Polyhedra_Library::BD_Shape< T >::ascii_dump(), Parma_Polyhedra_Library::BD_Shape< T >::ascii_load(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::BD_Shape< T >::BHMZ05_widening_assign(), Parma_Polyhedra_Library::BD_Shape< T >::external_memory_in_bytes(), Parma_Polyhedra_Library::BD_Shape< T >::is_shortest_path_reduced(), Parma_Polyhedra_Library::BD_Shape< T >::minimized_constraints(), Parma_Polyhedra_Library::BD_Shape< T >::OK(), Parma_Polyhedra_Library::BD_Shape< T >::operator=(), Parma_Polyhedra_Library::BD_Shape< T >::shortest_path_reduction_assign(), and Parma_Polyhedra_Library::BD_Shape< T >::swap().
1.5.6