#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 ![]() *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 ![]() ![]() 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 ![]() ![]() 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 ![]() ![]() 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 ![]() ![]() 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 ![]() 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 ![]() 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:
T
is a (bounded or unbounded) integer type;T
is the unbounded rational type mpq_class
;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);
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. |
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. |
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
i
. If j
and true
is returned. If 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 var
has space dimension 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 var
has space dimension to_be_folded
is a set of variables whose maximum space dimension is also less than or equal to var
is not a member of to_be_folded
, then the space dimensions corresponding to variables in to_be_folded
are folded into the 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().