PPL  1.2
Parma_Polyhedra_Library::Grid Class Reference

A grid. More...

#include <Grid_defs.hh>

Collaboration diagram for Parma_Polyhedra_Library::Grid:

Classes

class  Status
 A conjunctive assertion about a grid. More...
 

Public Types

typedef Coefficient coefficient_type
 The numeric type of coefficients. More...
 

Public Member Functions

 Grid (dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
 Builds a grid having the specified properties. More...
 
 Grid (const Congruence_System &cgs)
 Builds a grid, copying a system of congruences. More...
 
 Grid (Congruence_System &cgs, Recycle_Input dummy)
 Builds a grid, recycling a system of congruences. More...
 
 Grid (const Constraint_System &cs)
 Builds a grid, copying a system of constraints. More...
 
 Grid (Constraint_System &cs, Recycle_Input dummy)
 Builds a grid, recycling a system of constraints. More...
 
 Grid (const Grid_Generator_System &ggs)
 Builds a grid, copying a system of grid generators. More...
 
 Grid (Grid_Generator_System &ggs, Recycle_Input dummy)
 Builds a grid, recycling a system of grid generators. More...
 
template<typename Interval >
 Grid (const Box< Interval > &box, Complexity_Class complexity=ANY_COMPLEXITY)
 Builds a grid out of a box. More...
 
template<typename U >
 Grid (const BD_Shape< U > &bd, Complexity_Class complexity=ANY_COMPLEXITY)
 Builds a grid out of a bounded-difference shape. More...
 
template<typename U >
 Grid (const Octagonal_Shape< U > &os, Complexity_Class complexity=ANY_COMPLEXITY)
 Builds a grid out of an octagonal shape. More...
 
 Grid (const Polyhedron &ph, Complexity_Class complexity=ANY_COMPLEXITY)
 Builds a grid from a polyhedron using algorithms whose complexity does not exceed the one specified by complexity. If complexity is ANY_COMPLEXITY, then the grid built is the smallest one containing ph. More...
 
 Grid (const Grid &y, Complexity_Class complexity=ANY_COMPLEXITY)
 Ordinary copy constructor. More...
 
Gridoperator= (const Grid &y)
 The assignment operator. (*this and y can be dimension-incompatible.) More...
 
Member Functions that Do Not Modify the Grid
dimension_type space_dimension () const
 Returns the dimension of the vector space enclosing *this. More...
 
dimension_type affine_dimension () const
 Returns $0$, if *this is empty; otherwise, returns the affine dimension of *this. More...
 
Constraint_System constraints () const
 Returns a system of equality constraints satisfied by *this with the same affine dimension as *this. More...
 
Constraint_System minimized_constraints () const
 Returns a minimal system of equality constraints satisfied by *this with the same affine dimension as *this. More...
 
const Congruence_Systemcongruences () const
 Returns the system of congruences. More...
 
const Congruence_Systemminimized_congruences () const
 Returns the system of congruences in minimal form. More...
 
const Grid_Generator_Systemgrid_generators () const
 Returns the system of generators. More...
 
const Grid_Generator_Systemminimized_grid_generators () const
 Returns the minimized system of generators. More...
 
Poly_Con_Relation relation_with (const Congruence &cg) const
 Returns the relations holding between *this and cg. More...
 
Poly_Gen_Relation relation_with (const Grid_Generator &g) const
 Returns the relations holding between *this and g. More...
 
Poly_Gen_Relation relation_with (const Generator &g) const
 Returns the relations holding between *this and g. More...
 
Poly_Con_Relation relation_with (const Constraint &c) const
 Returns the relations holding between *this and c. More...
 
bool is_empty () const
 Returns true if and only if *this is an empty grid. More...
 
bool is_universe () const
 Returns true if and only if *this is a universe grid. More...
 
bool is_topologically_closed () const
 Returns true if and only if *this is a topologically closed subset of the vector space. More...
 
bool is_disjoint_from (const Grid &y) const
 Returns true if and only if *this and y are disjoint. More...
 
bool is_discrete () const
 Returns true if and only if *this is discrete. More...
 
bool is_bounded () const
 Returns true if and only if *this is bounded. More...
 
bool contains_integer_point () const
 Returns true if and only if *this contains at least one integer point. More...
 
bool constrains (Variable var) const
 Returns true if and only if var is constrained in *this. More...
 
bool bounds_from_above (const Linear_Expression &expr) const
 Returns true if and only if expr is bounded in *this. More...
 
bool bounds_from_below (const Linear_Expression &expr) const
 Returns true if and only if expr is bounded in *this. More...
 
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. More...
 
bool maximize (const Linear_Expression &expr, Coefficient &sup_n, Coefficient &sup_d, bool &maximum, Generator &point) 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. More...
 
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. More...
 
bool minimize (const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum, Generator &point) 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. More...
 
bool frequency (const Linear_Expression &expr, Coefficient &freq_n, Coefficient &freq_d, Coefficient &val_n, Coefficient &val_d) const
 Returns true if and only if *this is not empty and frequency for *this with respect to expr is defined, in which case the frequency and the value for expr that is closest to zero are computed. More...
 
bool contains (const Grid &y) const
 Returns true if and only if *this contains y. More...
 
bool strictly_contains (const Grid &y) const
 Returns true if and only if *this strictly contains y. More...
 
bool OK (bool check_not_empty=false) const
 Checks if all the invariants are satisfied. More...
 
Space Dimension Preserving Member Functions that May Modify the Grid
void add_congruence (const Congruence &cg)
 Adds a copy of congruence cg to *this. More...
 
void add_grid_generator (const Grid_Generator &g)
 Adds a copy of grid generator g to the system of generators of *this. More...
 
void add_congruences (const Congruence_System &cgs)
 Adds a copy of each congruence in cgs to *this. More...
 
void add_recycled_congruences (Congruence_System &cgs)
 Adds the congruences in cgs to *this. More...
 
void add_constraint (const Constraint &c)
 Adds to *this a congruence equivalent to constraint c. More...
 
void add_constraints (const Constraint_System &cs)
 Adds to *this congruences equivalent to the constraints in cs. More...
 
void add_recycled_constraints (Constraint_System &cs)
 Adds to *this congruences equivalent to the constraints in cs. More...
 
void refine_with_congruence (const Congruence &cg)
 Uses a copy of the congruence cg to refine *this. More...
 
void refine_with_congruences (const Congruence_System &cgs)
 Uses a copy of the congruences in cgs to refine *this. More...
 
void refine_with_constraint (const Constraint &c)
 Uses a copy of the constraint c to refine *this. More...
 
void refine_with_constraints (const Constraint_System &cs)
 Uses a copy of the constraints in cs to refine *this. More...
 
void add_grid_generators (const Grid_Generator_System &gs)
 Adds a copy of the generators in gs to the system of generators of *this. More...
 
void add_recycled_grid_generators (Grid_Generator_System &gs)
 Adds the generators in gs to the system of generators of this. More...
 
void unconstrain (Variable var)
 Computes the cylindrification of *this with respect to space dimension var, assigning the result to *this. More...
 
void unconstrain (const Variables_Set &vars)
 Computes the cylindrification of *this with respect to the set of space dimensions vars, assigning the result to *this. More...
 
void intersection_assign (const Grid &y)
 Assigns to *this the intersection of *this and y. More...
 
void upper_bound_assign (const Grid &y)
 Assigns to *this the least upper bound of *this and y. More...
 
bool upper_bound_assign_if_exact (const Grid &y)
 If the upper bound of *this and y is exact it is assigned to this and true is returned, otherwise false is returned. More...
 
void difference_assign (const Grid &y)
 Assigns to *this the grid-difference of *this and y. More...
 
bool simplify_using_context_assign (const Grid &y)
 Assigns to *this a meet-preserving simplification of *this with respect to y. If false is returned, then the intersection is empty. More...
 
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 to the affine expression specified by expr and denominator. More...
 
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 to the affine expression specified by expr and denominator. More...
 
void generalized_affine_image (Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one(), Coefficient_traits::const_reference modulus=Coefficient_zero())
 Assigns to *this the image of *this with respect to the generalized affine relation $\mathrm{var}' = \frac{\mathrm{expr}}{\mathrm{denominator}} \pmod{\mathrm{modulus}}$. More...
 
void generalized_affine_preimage (Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one(), Coefficient_traits::const_reference modulus=Coefficient_zero())
 Assigns to *this the preimage of *this with respect to the generalized affine relation $\mathrm{var}' = \frac{\mathrm{expr}}{\mathrm{denominator}} \pmod{\mathrm{modulus}}$. More...
 
void generalized_affine_image (const Linear_Expression &lhs, Relation_Symbol relsym, const Linear_Expression &rhs, Coefficient_traits::const_reference modulus=Coefficient_zero())
 Assigns to *this the image of *this with respect to the generalized affine relation $\mathrm{lhs}' = \mathrm{rhs} \pmod{\mathrm{modulus}}$. More...
 
void generalized_affine_preimage (const Linear_Expression &lhs, Relation_Symbol relsym, const Linear_Expression &rhs, Coefficient_traits::const_reference modulus=Coefficient_zero())
 Assigns to *this the preimage of *this with respect to the generalized affine relation $\mathrm{lhs}' = \mathrm{rhs} \pmod{\mathrm{modulus}}$. More...
 
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 $\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} \leq \mathrm{var}' \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}$. More...
 
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 $\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} \leq \mathrm{var}' \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}$. More...
 
void time_elapse_assign (const Grid &y)
 Assigns to *this the result of computing the time-elapse between *this and y. More...
 
void wrap_assign (const Variables_Set &vars, Bounded_Integer_Type_Width w, Bounded_Integer_Type_Representation r, Bounded_Integer_Type_Overflow o, const Constraint_System *cs_p=0, unsigned complexity_threshold=16, bool wrap_individually=true)
 Wraps the specified dimensions of the vector space. More...
 
void drop_some_non_integer_points (Complexity_Class complexity=ANY_COMPLEXITY)
 Possibly tightens *this by dropping all points with non-integer coordinates. More...
 
void drop_some_non_integer_points (const Variables_Set &vars, Complexity_Class complexity=ANY_COMPLEXITY)
 Possibly tightens *this by dropping all points with non-integer coordinates for the space dimensions corresponding to vars. More...
 
void topological_closure_assign ()
 Assigns to *this its topological closure. More...
 
void congruence_widening_assign (const Grid &y, unsigned *tp=NULL)
 Assigns to *this the result of computing the Grid widening between *this and y using congruence systems. More...
 
void generator_widening_assign (const Grid &y, unsigned *tp=NULL)
 Assigns to *this the result of computing the Grid widening between *this and y using generator systems. More...
 
void widening_assign (const Grid &y, unsigned *tp=NULL)
 Assigns to *this the result of computing the Grid widening between *this and y. More...
 
void limited_congruence_extrapolation_assign (const Grid &y, const Congruence_System &cgs, unsigned *tp=NULL)
 Improves the result of the congruence variant of Grid widening computation by also enforcing those congruences in cgs that are satisfied by all the points of *this. More...
 
void limited_generator_extrapolation_assign (const Grid &y, const Congruence_System &cgs, unsigned *tp=NULL)
 Improves the result of the generator variant of the Grid widening computation by also enforcing those congruences in cgs that are satisfied by all the points of *this. More...
 
void limited_extrapolation_assign (const Grid &y, const Congruence_System &cgs, unsigned *tp=NULL)
 Improves the result of the Grid widening computation by also enforcing those congruences in cgs that are satisfied by all the points of *this. More...
 
Member Functions that May Modify the Dimension of the Vector Space
void add_space_dimensions_and_embed (dimension_type m)
 Adds m new space dimensions and embeds the old grid in the new vector space. More...
 
void add_space_dimensions_and_project (dimension_type m)
 Adds m new space dimensions to the grid and does not embed it in the new vector space. More...
 
void concatenate_assign (const Grid &y)
 Assigns to *this the concatenation of *this and y, taken in this order. More...
 
void remove_space_dimensions (const Variables_Set &vars)
 Removes all the specified dimensions from the vector space. More...
 
void remove_higher_space_dimensions (dimension_type new_dimension)
 Removes the higher dimensions of the vector space so that the resulting space will have dimension new_dimension.. More...
 
template<typename Partial_Function >
void map_space_dimensions (const Partial_Function &pfunc)
 Remaps the dimensions of the vector space according to a partial function. More...
 
void expand_space_dimension (Variable var, dimension_type m)
 Creates m copies of the space dimension corresponding to var. More...
 
void fold_space_dimensions (const Variables_Set &vars, Variable dest)
 Folds the space dimensions in vars into dest. More...
 
Miscellaneous Member Functions
 ~Grid ()
 Destructor. More...
 
void m_swap (Grid &y)
 Swaps *this with grid y. (*this and y can be dimension-incompatible.) More...
 
void ascii_dump () const
 Writes to std::cerr an ASCII representation of *this. More...
 
void ascii_dump (std::ostream &s) const
 Writes to s an ASCII representation of *this. More...
 
void print () const
 Prints *this to std::cerr using operator<<. More...
 
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. More...
 
memory_size_type total_memory_in_bytes () const
 Returns the total size in bytes of the memory occupied by *this. More...
 
memory_size_type external_memory_in_bytes () const
 Returns the size in bytes of the memory managed by *this. More...
 
int32_t hash_code () const
 Returns a 32-bit hash code for *this. More...
 

Static Public Member Functions

static dimension_type max_space_dimension ()
 Returns the maximum space dimension all kinds of Grid can handle. More...
 
static bool can_recycle_congruence_systems ()
 Returns true indicating that this domain has methods that can recycle congruences. More...
 
static bool can_recycle_constraint_systems ()
 Returns true indicating that this domain has methods that can recycle constraints. More...
 

Private Types

enum  Dimension_Kind {
  PARAMETER = 0, LINE = 1, GEN_VIRTUAL = 2, PROPER_CONGRUENCE = PARAMETER,
  CON_VIRTUAL = LINE, EQUALITY = GEN_VIRTUAL
}
 
enum  Three_Valued_Boolean { TVB_TRUE, TVB_FALSE, TVB_DONT_KNOW }
 
typedef std::vector< Dimension_KindDimension_Kinds
 

Private Member Functions

void construct (dimension_type num_dimensions, Degenerate_Element kind)
 Builds a grid universe or empty grid. More...
 
void construct (Congruence_System &cgs)
 Builds a grid from a system of congruences. More...
 
void construct (Grid_Generator_System &ggs)
 Builds a grid from a system of grid generators. More...
 
Three_Valued_Boolean quick_equivalence_test (const Grid &y) const
 Polynomial but incomplete equivalence test between grids. More...
 
bool is_included_in (const Grid &y) const
 Returns true if and only if *this is included in y. More...
 
bool bounds (const Linear_Expression &expr, const char *method_call) const
 Checks if and how expr is bounded in *this. More...
 
bool max_min (const Linear_Expression &expr, const char *method_call, Coefficient &ext_n, Coefficient &ext_d, bool &included, Generator *point=NULL) const
 Maximizes or minimizes expr subject to *this. More...
 
bool frequency_no_check (const Linear_Expression &expr, Coefficient &freq_n, Coefficient &freq_d, Coefficient &val_n, Coefficient &val_d) const
 Returns true if and only if *this is not empty and frequency for *this with respect to expr is defined, in which case the frequency and the value for expr that is closest to zero are computed. More...
 
bool bounds_no_check (const Linear_Expression &expr) const
 Checks if and how expr is bounded in *this. More...
 
void add_congruence_no_check (const Congruence &cg)
 Adds the congruence cg to *this. More...
 
void add_constraint_no_check (const Constraint &c)
 Uses the constraint c to refine *this. More...
 
void refine_no_check (const Constraint &c)
 Uses the constraint c to refine *this. More...
 
void add_space_dimensions (Congruence_System &cgs, Grid_Generator_System &gs, dimension_type dims)
 Adds new space dimensions to the given systems. More...
 
void add_space_dimensions (Grid_Generator_System &gs, Congruence_System &cgs, dimension_type dims)
 Adds new space dimensions to the given systems. More...
 
Private Verifiers: Verify if Individual Flags are Set
bool marked_empty () const
 Returns true if the grid is known to be empty. More...
 
bool congruences_are_up_to_date () const
 Returns true if the system of congruences is up-to-date. More...
 
bool generators_are_up_to_date () const
 Returns true if the system of generators is up-to-date. More...
 
bool congruences_are_minimized () const
 Returns true if the system of congruences is minimized. More...
 
bool generators_are_minimized () const
 Returns true if the system of generators is minimized. More...
 
State Flag Setters: Set Only the Specified Flags
void set_zero_dim_univ ()
 Sets status to express that the grid is the universe 0-dimension vector space, clearing all corresponding matrices. More...
 
void set_empty ()
 Sets status to express that the grid is empty, clearing all corresponding matrices. More...
 
void set_congruences_up_to_date ()
 Sets status to express that congruences are up-to-date. More...
 
void set_generators_up_to_date ()
 Sets status to express that generators are up-to-date. More...
 
void set_congruences_minimized ()
 Sets status to express that congruences are minimized. More...
 
void set_generators_minimized ()
 Sets status to express that generators are minimized. More...
 
State Flag Cleaners: Clear Only the Specified Flag
void clear_empty ()
 Clears the status flag indicating that the grid is empty. More...
 
void clear_congruences_up_to_date ()
 Sets status to express that congruences are out of date. More...
 
void clear_generators_up_to_date ()
 Sets status to express that generators are out of date. More...
 
void clear_congruences_minimized ()
 Sets status to express that congruences are no longer minimized. More...
 
void clear_generators_minimized ()
 Sets status to express that generators are no longer minimized. More...
 
Updating Matrices
void update_congruences () const
 Updates and minimizes the congruences from the generators. More...
 
bool update_generators () const
 Updates and minimizes the generators from the congruences. More...
 
Minimization of Descriptions
bool minimize () const
 Minimizes both the congruences and the generators. More...
 
Widening- and Extrapolation-Related Functions
void select_wider_congruences (const Grid &y, Congruence_System &selected_cgs) const
 Copies a widened selection of congruences from y to selected_cgs. More...
 
void select_wider_generators (const Grid &y, Grid_Generator_System &widened_ggs) const
 Copies widened generators from y to widened_ggs. More...
 

Static Private Member Functions

Minimization-related Static Member Functions
static void normalize_divisors (Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
 Normalizes the divisors in sys. More...
 
static void normalize_divisors (Grid_Generator_System &sys)
 Normalizes the divisors in sys. More...
 
static void normalize_divisors (Grid_Generator_System &sys, Grid_Generator_System &gen_sys)
 Normalize all the divisors in sys and gen_sys. More...
 
static void conversion (Congruence_System &source, Grid_Generator_System &dest, Dimension_Kinds &dim_kinds)
 Converts generator system dest to be equivalent to congruence system source. More...
 
static void conversion (Grid_Generator_System &source, Congruence_System &dest, Dimension_Kinds &dim_kinds)
 Converts congruence system dest to be equivalent to generator system source. More...
 
static bool simplify (Congruence_System &cgs, Dimension_Kinds &dim_kinds)
 Converts cgs to upper triangular (i.e. minimized) form. More...
 
static void simplify (Grid_Generator_System &ggs, Dimension_Kinds &dim_kinds)
 Converts gs to lower triangular (i.e. minimized) form. More...
 
static void reduce_line_with_line (Grid_Generator &row, Grid_Generator &pivot, dimension_type column)
 Reduces the line row using the line pivot. More...
 
static void reduce_equality_with_equality (Congruence &row, const Congruence &pivot, dimension_type column)
 Reduces the equality row using the equality pivot. More...
 
template<typename R >
static void reduce_pc_with_pc (R &row, R &pivot, dimension_type column, dimension_type start, dimension_type end)
 Reduces row using pivot. More...
 
static void reduce_parameter_with_line (Grid_Generator &row, const Grid_Generator &pivot, dimension_type column, Swapping_Vector< Grid_Generator > &sys, dimension_type num_columns)
 Reduce row using pivot. More...
 
static void reduce_congruence_with_equality (Congruence &row, const Congruence &pivot, dimension_type column, Swapping_Vector< Congruence > &sys)
 Reduce row using pivot. More...
 
template<typename M >
static void reduce_reduced (Swapping_Vector< typename M::row_type > &sys, dimension_type dim, dimension_type pivot_index, dimension_type start, dimension_type end, const Dimension_Kinds &sys_dim_kinds, bool generators=true)
 Reduce column dim in rows preceding pivot_index in sys. More...
 
static void multiply_grid (const Coefficient &multiplier, Congruence &cg, Swapping_Vector< Congruence > &dest, dimension_type num_rows)
 Multiply the elements of dest by multiplier. More...
 
static void multiply_grid (const Coefficient &multiplier, Grid_Generator &gen, Swapping_Vector< Grid_Generator > &dest, dimension_type num_rows)
 Multiply the elements of dest by multiplier. More...
 
static bool lower_triangular (const Congruence_System &sys, const Dimension_Kinds &dim_kinds)
 If sys is lower triangular return true, else return false. More...
 
static bool upper_triangular (const Grid_Generator_System &sys, const Dimension_Kinds &dim_kinds)
 If sys is upper triangular return true, else return false. More...
 
template<typename M , typename R >
static bool rows_are_zero (M &system, dimension_type first, dimension_type last, dimension_type row_size)
 Checks that trailing rows contain only zero terms. More...
 

Private Attributes

Congruence_System con_sys
 The system of congruences. More...
 
Grid_Generator_System gen_sys
 The system of generators. More...
 
Status status
 The status flags to keep track of the grid's internal state. More...
 
dimension_type space_dim
 The number of dimensions of the enclosing vector space. More...
 
Dimension_Kinds dim_kinds
 

Friends

class Parma_Polyhedra_Library::Grid_Certificate
 
template<typename Interval >
class Parma_Polyhedra_Library::Box
 
bool operator== (const Grid &x, const Grid &y)
 

Related Functions

(Note that these are not member functions.)

std::ostream & operator<< (std::ostream &s, const Grid &gr)
 Output operator. More...
 
void swap (Grid &x, Grid &y)
 Swaps x with y. More...
 
bool operator== (const Grid &x, const Grid &y)
 Returns true if and only if x and y are the same grid. More...
 
bool operator!= (const Grid &x, const Grid &y)
 Returns true if and only if x and y are different grids. More...
 
bool operator!= (const Grid &x, const Grid &y)
 
void swap (Grid &x, Grid &y)
 
bool operator== (const Grid &x, const Grid &y)
 
std::ostream & operator<< (std::ostream &s, const Grid &gr)
 

Exception Throwers

void throw_dimension_incompatible (const char *method, const char *other_name, dimension_type other_dim) const
 
void throw_dimension_incompatible (const char *method, const char *gr_name, const Grid &gr) const
 
void throw_dimension_incompatible (const char *method, const char *le_name, const Linear_Expression &le) const
 
void throw_dimension_incompatible (const char *method, const char *cg_name, const Congruence &cg) const
 
void throw_dimension_incompatible (const char *method, const char *c_name, const Constraint &c) const
 
void throw_dimension_incompatible (const char *method, const char *g_name, const Grid_Generator &g) const
 
void throw_dimension_incompatible (const char *method, const char *g_name, const Generator &g) const
 
void throw_dimension_incompatible (const char *method, const char *cgs_name, const Congruence_System &cgs) const
 
void throw_dimension_incompatible (const char *method, const char *cs_name, const Constraint_System &cs) const
 
void throw_dimension_incompatible (const char *method, const char *gs_name, const Grid_Generator_System &gs) const
 
void throw_dimension_incompatible (const char *method, const char *var_name, Variable var) const
 
void throw_dimension_incompatible (const char *method, dimension_type required_space_dim) const
 
static void throw_invalid_argument (const char *method, const char *reason)
 
static void throw_invalid_constraint (const char *method, const char *c_name)
 
static void throw_invalid_constraints (const char *method, const char *cs_name)
 
static void throw_invalid_generator (const char *method, const char *g_name)
 
static void throw_invalid_generators (const char *method, const char *gs_name)
 

Detailed Description

A grid.

An object of the class Grid represents a rational grid.

The domain of grids optimally supports:

  • all (proper and non-proper) congruences;
  • tautological and inconsistent constraints;
  • linear equality constraints (i.e., non-proper congruences).

Depending on the method, using a constraint that is not optimally supported by the domain will either raise an exception or result in a (possibly non-optimal) upward approximation.

The domain of grids support a concept of double description similar to the one developed for polyhedra: hence, a grid can be specified as either a finite system of congruences or a finite system of generators (see Section Rational Grids) and it is always possible to obtain either representation. That is, if we know the system of congruences, we can obtain from this a system of generators that define the same grid and vice versa. These systems can contain redundant members, or they can be in the minimal form.

A key attribute of any grid is its space dimension (the dimension $n \in \Nset$ of the enclosing vector space):

  • all grids, the empty ones included, are endowed with a space dimension;
  • most operations working on a grid and another object (another grid, a congruence, a generator, a set of variables, etc.) will throw an exception if the grid and the object are not dimension-compatible (see Section Space Dimensions and Dimension-compatibility for Grids);
  • the only ways in which the space dimension of a grid can be changed are with explicit calls to operators provided for that purpose, and with standard copy, assignment and swap operators.

Note that two different grids can be defined on the zero-dimension space: the empty grid and the universe grid $R^0$.

In all the examples it is assumed that variables x and y are defined (where they are used) as follows:
Variable x(0);
Variable y(1);
Example 1
The following code builds a grid corresponding to the even integer pairs in $\Rset^2$, given as a system of congruences:
Congruence_System cgs;
cgs.insert((x %= 0) / 2);
cgs.insert((y %= 0) / 2);
Grid gr(cgs);
The following code builds the same grid as above, but starting from a system of generators specifying three of the points:
Grid_Generator_System gs;
gs.insert(grid_point(0*x + 0*y));
gs.insert(grid_point(0*x + 2*y));
gs.insert(grid_point(2*x + 0*y));
Grid gr(gs);
Example 2
The following code builds a grid corresponding to a line in $\Rset^2$ by adding a single congruence to the universe grid:
Congruence_System cgs;
cgs.insert(x - y == 0);
Grid gr(cgs);
The following code builds the same grid as above, but starting from a system of generators specifying a point and a line:
Grid_Generator_System gs;
gs.insert(grid_point(0*x + 0*y));
gs.insert(grid_line(x + y));
Grid gr(gs);
Example 3
The following code builds a grid corresponding to the integral points on the line $x = y$ in $\Rset^2$ constructed by adding an equality and congruence to the universe grid:
Congruence_System cgs;
cgs.insert(x - y == 0);
cgs.insert(x %= 0);
Grid gr(cgs);
The following code builds the same grid as above, but starting from a system of generators specifying a point and a parameter:
Grid_Generator_System gs;
gs.insert(grid_point(0*x + 0*y));
gs.insert(parameter(x + y));
Grid gr(gs);
Example 4
The following code builds the grid corresponding to a plane by creating the universe grid in $\Rset^2$:
Grid gr(2);
The following code builds the same grid as above, but starting from the empty grid in $\Rset^2$ and inserting the appropriate generators (a point, and two lines).
Grid gr(2, EMPTY);
gr.add_grid_generator(grid_point(0*x + 0*y));
gr.add_grid_generator(grid_line(x));
gr.add_grid_generator(grid_line(y));
Note that a generator system must contain a point when describing a grid. To ensure that this is always the case it is required that the first generator inserted in an empty grid is a point (otherwise, an exception is thrown).
Example 5
The following code shows the use of the function add_space_dimensions_and_embed:
Grid gr(1);
gr.add_congruence(x == 2);
gr.add_space_dimensions_and_embed(1);
We build the universe grid in the 1-dimension space $\Rset$. Then we add a single equality congruence, thus obtaining the grid corresponding to the singleton set $\{ 2 \} \sseq \Rset$. After the last line of code, the resulting grid is

\[ \bigl\{\, (2, y)^\transpose \in \Rset^2 \bigm| y \in \Rset \,\bigr\}. \]

Example 6
The following code shows the use of the function add_space_dimensions_and_project:
Grid gr(1);
gr.add_congruence(x == 2);
gr.add_space_dimensions_and_project(1);
The first two lines of code are the same as in Example 4 for add_space_dimensions_and_embed. After the last line of code, the resulting grid is the singleton set $\bigl\{ (2, 0)^\transpose \bigr\} \sseq \Rset^2$.
Example 7
The following code shows the use of the function affine_image:
Grid gr(2, EMPTY);
gr.add_grid_generator(grid_point(0*x + 0*y));
gr.add_grid_generator(grid_point(4*x + 0*y));
gr.add_grid_generator(grid_point(0*x + 2*y));
Linear_Expression expr = x + 3;
gr.affine_image(x, expr);
In this example the starting grid is all the pairs of $x$ and $y$ in $\Rset^2$ where $x$ is an integer multiple of 4 and $y$ is an integer multiple of 2. The considered variable is $x$ and the affine expression is $x+3$. The resulting grid is the given grid translated 3 integers to the right (all the pairs $(x, y)$ where $x$ is -1 plus an integer multiple of 4 and $y$ is an integer multiple of 2). Moreover, if the affine transformation for the same variable x is instead $x+y$:
Linear_Expression expr = x + y;
the resulting grid is every second integral point along the $x=y$ line, with this line of points repeated at every fourth integral value along the $x$ axis. Instead, if we do not use an invertible transformation for the same variable; for example, the affine expression $y$:
Linear_Expression expr = y;
the resulting grid is every second point along the $x=y$ line.
Example 8
The following code shows the use of the function affine_preimage:
Grid gr(2, EMPTY);
gr.add_grid_generator(grid_point(0*x + 0*y));
gr.add_grid_generator(grid_point(4*x + 0*y));
gr.add_grid_generator(grid_point(0*x + 2*y));
Linear_Expression expr = x + 3;
gr.affine_preimage(x, expr);
In this example the starting grid, var and the affine expression and the denominator are the same as in Example 6, while the resulting grid is similar but translated 3 integers to the left (all the pairs $(x, y)$ where $x$ is -3 plus an integer multiple of 4 and $y$ is an integer multiple of 2).. Moreover, if the affine transformation for x is $x+y$
Linear_Expression expr = x + y;
the resulting grid is a similar grid to the result in Example 6, only the grid is slanted along $x=-y$. Instead, if we do not use an invertible transformation for the same variable x, for example, the affine expression $y$:
Linear_Expression expr = y;
the resulting grid is every fourth line parallel to the $x$ axis.
Example 9
For this example we also use the variables:
Variable z(2);
Variable w(3);
The following code shows the use of the function remove_space_dimensions:
Grid_Generator_System gs;
gs.insert(grid_point(3*x + y +0*z + 2*w));
Grid gr(gs);
Variables_Set vars;
vars.insert(y);
vars.insert(z);
gr.remove_space_dimensions(vars);
The starting grid is the singleton set $\bigl\{ (3, 1, 0, 2)^\transpose \bigr\} \sseq \Rset^4$, while the resulting grid is $\bigl\{ (3, 2)^\transpose \bigr\} \sseq \Rset^2$. Be careful when removing space dimensions incrementally: since dimensions are automatically renamed after each application of the remove_space_dimensions operator, unexpected results can be obtained. For instance, by using the following code we would obtain a different result:
set<Variable> vars1;
vars1.insert(y);
gr.remove_space_dimensions(vars1);
set<Variable> vars2;
vars2.insert(z);
gr.remove_space_dimensions(vars2);
In this case, the result is the grid $\bigl\{(3, 0)^\transpose \bigr\} \sseq \Rset^2$: when removing the set of dimensions vars2 we are actually removing variable $w$ of the original grid. For the same reason, the operator remove_space_dimensions is not idempotent: removing twice the same non-empty set of dimensions is never the same as removing them just once.

Definition at line 363 of file Grid_defs.hh.

Member Typedef Documentation

The numeric type of coefficients.

Definition at line 366 of file Grid_defs.hh.

Definition at line 1994 of file Grid_defs.hh.

Constructor & Destructor Documentation

Parma_Polyhedra_Library::Grid::Grid ( dimension_type  num_dimensions = 0,
Degenerate_Element  kind = UNIVERSE 
)
inlineexplicit

Builds a grid having the specified properties.

Parameters
num_dimensionsThe number of dimensions of the vector space enclosing the grid;
kindSpecifies whether the universe or the empty grid has to be built.
Exceptions
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 122 of file Grid_inlines.hh.

References construct(), and OK().

124  : con_sys(),
127  "PPL::Grid::",
128  "Grid(n, k)",
129  "n exceeds the maximum "
130  "allowed space dimension")) {
131  construct(num_dimensions, kind);
132  PPL_ASSERT(OK());
133 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Parma_Polyhedra_Library::Grid::Grid ( const Congruence_System cgs)
inlineexplicit

Builds a grid, copying a system of congruences.

The grid inherits the space dimension of the congruence system.

Parameters
cgsThe system of congruences defining the grid.
Exceptions
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 136 of file Grid_inlines.hh.

References construct().

137  : con_sys(check_space_dimension_overflow(cgs.space_dimension(),
139  "PPL::Grid::",
140  "Grid(cgs)",
141  "the space dimension of cgs "
142  "exceeds the maximum allowed "
143  "space dimension")),
144  gen_sys(cgs.space_dimension()) {
145  Congruence_System cgs_copy(cgs);
146  construct(cgs_copy);
147 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Parma_Polyhedra_Library::Grid::Grid ( Congruence_System cgs,
Recycle_Input  dummy 
)
inline

Builds a grid, recycling a system of congruences.

The grid inherits the space dimension of the congruence system.

Parameters
cgsThe system of congruences defining the grid. Its data-structures may be recycled to build the grid.
dummyA dummy tag to syntactically differentiate this one from the other constructors.
Exceptions
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 150 of file Grid_inlines.hh.

References construct().

151  : con_sys(check_space_dimension_overflow(cgs.space_dimension(),
153  "PPL::Grid::",
154  "Grid(cgs, recycle)",
155  "the space dimension of cgs "
156  "exceeds the maximum allowed "
157  "space dimension")),
158  gen_sys(cgs.space_dimension()) {
159  construct(cgs);
160 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Parma_Polyhedra_Library::Grid::Grid ( const Constraint_System cs)
explicit

Builds a grid, copying a system of constraints.

The grid inherits the space dimension of the constraint system.

Parameters
csThe system of constraints defining the grid.
Exceptions
std::invalid_argumentThrown if the constraint system cs contains inequality constraints.
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 64 of file Grid_public.cc.

References Parma_Polyhedra_Library::Constraint_System::begin(), con_sys, construct(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Congruence_System::insert(), OK(), Parma_Polyhedra_Library::Grid::Status::set_empty(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), status, throw_invalid_constraints(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().

65  : con_sys(check_space_dimension_overflow(cs.space_dimension(),
67  "PPL::Grid::",
68  "Grid(cs)",
69  "the space dimension of cs "
70  "exceeds the maximum allowed "
71  "space dimension")),
72  gen_sys(cs.space_dimension()) {
73  space_dim = cs.space_dimension();
74 
75  if (space_dim == 0) {
76  // See if an inconsistent constraint has been passed.
77  for (Constraint_System::const_iterator i = cs.begin(),
78  cs_end = cs.end(); i != cs_end; ++i) {
79  if (i->is_inconsistent()) {
80  // Inconsistent constraint found: the grid is empty.
81  status.set_empty();
82  // Insert the zero dim false congruence system into `con_sys'.
83  // `gen_sys' is already in empty form.
85  PPL_ASSERT(OK());
86  return;
87  }
88  }
90  PPL_ASSERT(OK());
91  return;
92  }
93 
94  Congruence_System cgs(cs.space_dimension());
95  for (Constraint_System::const_iterator i = cs.begin(),
96  cs_end = cs.end(); i != cs_end; ++i) {
97  if (i->is_equality()) {
98  cgs.insert(*i);
99  }
100  else {
101  throw_invalid_constraints("Grid(cs)", "cs");
102  }
103  }
104  construct(cgs);
105 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
static void throw_invalid_constraints(const char *method, const char *cs_name)
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Constraint_System_const_iterator const_iterator
Parma_Polyhedra_Library::Grid::Grid ( Constraint_System cs,
Recycle_Input  dummy 
)

Builds a grid, recycling a system of constraints.

The grid inherits the space dimension of the constraint system.

Parameters
csThe system of constraints defining the grid. Its data-structures may be recycled to build the grid.
dummyA dummy tag to syntactically differentiate this one from the other constructors.
Exceptions
std::invalid_argumentThrown if the constraint system cs contains inequality constraints.
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 107 of file Grid_public.cc.

References Parma_Polyhedra_Library::Constraint_System::begin(), con_sys, construct(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Congruence_System::insert(), OK(), Parma_Polyhedra_Library::Grid::Status::set_empty(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), status, throw_invalid_constraint(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().

108  : con_sys(check_space_dimension_overflow(cs.space_dimension(),
110  "PPL::Grid::",
111  "Grid(cs, recycle)",
112  "the space dimension of cs "
113  "exceeds the maximum allowed "
114  "space dimension")),
115  gen_sys(cs.space_dimension()) {
116  space_dim = cs.space_dimension();
117 
118  if (space_dim == 0) {
119  // See if an inconsistent constraint has been passed.
120  for (Constraint_System::const_iterator i = cs.begin(),
121  cs_end = cs.end(); i != cs_end; ++i) {
122  if (i->is_inconsistent()) {
123  // Inconsistent constraint found: the grid is empty.
124  status.set_empty();
125  // Insert the zero dim false congruence system into `con_sys'.
126  // `gen_sys' is already in empty form.
128  PPL_ASSERT(OK());
129  return;
130  }
131  }
133  PPL_ASSERT(OK());
134  return;
135  }
136 
137  Congruence_System cgs(space_dim);
138  for (Constraint_System::const_iterator i = cs.begin(),
139  cs_end = cs.end(); i != cs_end; ++i) {
140  if (i->is_equality()) {
141  cgs.insert(*i);
142  }
143  else {
144  throw_invalid_constraint("Grid(cs)", "cs");
145  }
146  }
147  construct(cgs);
148 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
static void throw_invalid_constraint(const char *method, const char *c_name)
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Constraint_System_const_iterator const_iterator
Parma_Polyhedra_Library::Grid::Grid ( const Grid_Generator_System ggs)
inlineexplicit

Builds a grid, copying a system of grid generators.

The grid inherits the space dimension of the generator system.

Parameters
ggsThe system of generators defining the grid.
Exceptions
std::invalid_argumentThrown if the system of generators is not empty but has no points.
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 163 of file Grid_inlines.hh.

References construct().

164  : con_sys(check_space_dimension_overflow(ggs.space_dimension(),
166  "PPL::Grid::",
167  "Grid(ggs)",
168  "the space dimension of ggs "
169  "exceeds the maximum allowed "
170  "space dimension")),
171  gen_sys(ggs.space_dimension()) {
172  Grid_Generator_System ggs_copy(ggs);
173  construct(ggs_copy);
174 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Parma_Polyhedra_Library::Grid::Grid ( Grid_Generator_System ggs,
Recycle_Input  dummy 
)
inline

Builds a grid, recycling a system of grid generators.

The grid inherits the space dimension of the generator system.

Parameters
ggsThe system of generators defining the grid. Its data-structures may be recycled to build the grid.
dummyA dummy tag to syntactically differentiate this one from the other constructors.
Exceptions
std::invalid_argumentThrown if the system of generators is not empty but has no points.
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 177 of file Grid_inlines.hh.

References construct().

178  : con_sys(check_space_dimension_overflow(ggs.space_dimension(),
180  "PPL::Grid::",
181  "Grid(ggs, recycle)",
182  "the space dimension of ggs "
183  "exceeds the maximum allowed "
184  "space dimension")),
185  gen_sys(ggs.space_dimension()) {
186  construct(ggs);
187 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
template<typename Interval >
Parma_Polyhedra_Library::Grid::Grid ( const Box< Interval > &  box,
Complexity_Class  complexity = ANY_COMPLEXITY 
)
explicit

Builds a grid out of a box.

The grid inherits the space dimension of the box. The built grid is the most precise grid that includes the box.

Parameters
boxThe box representing the grid to be built.
complexityThis argument is ignored as the algorithm used has polynomial complexity.
Exceptions
std::length_errorThrown if the space dimension of box exceeds the maximum allowed space dimension.

Definition at line 36 of file Grid_templates.hh.

References Parma_Polyhedra_Library::check_space_dimension_overflow(), con_sys, Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Grid_Generator::expr, Parma_Polyhedra_Library::gcd_assign(), gen_sys, Parma_Polyhedra_Library::Box< ITV >::has_lower_bound(), Parma_Polyhedra_Library::Box< ITV >::has_upper_bound(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Box< ITV >::is_empty(), max_space_dimension(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::Grid_Generator::OK(), OK(), PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Grid_Generator::scale_to_divisor(), Parma_Polyhedra_Library::Linear_Expression::set(), set_congruences_up_to_date(), set_empty(), set_generators_up_to_date(), Parma_Polyhedra_Library::Congruence_System::set_space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::set_space_dimension(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Box< ITV >::space_dimension(), and Parma_Polyhedra_Library::Grid_Generator_System::sys.

37  : con_sys(),
38  gen_sys() {
39  space_dim = check_space_dimension_overflow(box.space_dimension(),
41  "PPL::Grid::",
42  "Grid(box, from_bounding_box)",
43  "the space dimension of box "
44  "exceeds the maximum allowed "
45  "space dimension");
46 
47  if (box.is_empty()) {
48  // Empty grid.
49  set_empty();
50  PPL_ASSERT(OK());
51  return;
52  }
53 
54  if (space_dim == 0) {
56  }
57  else {
58  // Initialize the space dimension as indicated by the box.
61  // Add congruences and generators according to `box'.
66  gen_sys.insert(grid_point());
67  for (dimension_type k = space_dim; k-- > 0; ) {
68  const Variable v_k = Variable(k);
69  bool closed = false;
70  // TODO: Consider producing the system(s) in minimized form.
71  if (box.has_lower_bound(v_k, l_n, l_d, closed)) {
72  if (box.has_upper_bound(v_k, u_n, u_d, closed)) {
73  if (l_n * u_d == u_n * l_d) {
74  // A point interval sets dimension k of every point to a
75  // single value.
76  con_sys.insert(l_d * v_k == l_n);
77 
78  // This is declared here because it may be invalidated
79  // by the call to gen_sys.insert() at the end of the loop.
80  Grid_Generator& point = gen_sys.sys.rows[0];
81 
82  // Scale the point to use as divisor the lcm of the
83  // divisors of the existing point and the lower bound.
84  const Coefficient& point_divisor = point.divisor();
85  gcd_assign(u_n, l_d, point_divisor);
86  // `u_n' now holds the gcd.
87  exact_div_assign(u_n, point_divisor, u_n);
88  if (l_d < 0) {
89  neg_assign(u_n);
90  }
91  // l_d * u_n == abs(l_d * (point_divisor / gcd(l_d, point_divisor)))
92  point.scale_to_divisor(l_d * u_n);
93  // Set dimension k of the point to the lower bound.
94  if (l_d < 0) {
95  neg_assign(u_n);
96  }
97  // point[k + 1] = l_n * point_divisor / gcd(l_d, point_divisor)
98  point.expr.set(Variable(k), l_n * u_n);
99  PPL_ASSERT(point.OK());
100 
101  PPL_ASSERT(gen_sys.sys.OK());
102 
103  continue;
104  }
105  }
106  }
107  // A universe interval allows any value in dimension k.
108  gen_sys.insert(grid_line(v_k));
109  }
112  }
113 
114  PPL_ASSERT(OK());
115 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
bool set_space_dimension(dimension_type new_space_dim)
Sets the number of space dimensions to new_space_dim.
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
void set_space_dimension(dimension_type space_dim)
Resizes the system to the specified space dimension.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
void set_generators_up_to_date()
Sets status to express that generators are up-to-date.
Definition: Grid_inlines.hh:60
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void neg_assign(GMP_Integer &x)
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void set_congruences_up_to_date()
Sets status to express that congruences are up-to-date.
Definition: Grid_inlines.hh:65
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
template<typename U >
Parma_Polyhedra_Library::Grid::Grid ( const BD_Shape< U > &  bd,
Complexity_Class  complexity = ANY_COMPLEXITY 
)
inlineexplicit

Builds a grid out of a bounded-difference shape.

The grid inherits the space dimension of the BDS. The built grid is the most precise grid that includes the BDS.

Parameters
bdThe BDS representing the grid to be built.
complexityThis argument is ignored as the algorithm used has polynomial complexity.
Exceptions
std::length_errorThrown if the space dimension of bd exceeds the maximum allowed space dimension.

Definition at line 191 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::BD_Shape< T >::congruences(), and construct().

192  : con_sys(check_space_dimension_overflow(bd.space_dimension(),
194  "PPL::Grid::",
195  "Grid(bd)",
196  "the space dimension of bd "
197  "exceeds the maximum allowed "
198  "space dimension")),
199  gen_sys(bd.space_dimension()) {
200  Congruence_System cgs = bd.congruences();
201  construct(cgs);
202 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
template<typename U >
Parma_Polyhedra_Library::Grid::Grid ( const Octagonal_Shape< U > &  os,
Complexity_Class  complexity = ANY_COMPLEXITY 
)
inlineexplicit

Builds a grid out of an octagonal shape.

The grid inherits the space dimension of the octagonal shape. The built grid is the most precise grid that includes the octagonal shape.

Parameters
osThe octagonal shape representing the grid to be built.
complexityThis argument is ignored as the algorithm used has polynomial complexity.
Exceptions
std::length_errorThrown if the space dimension of os exceeds the maximum allowed space dimension.

Definition at line 206 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Octagonal_Shape< T >::congruences(), and construct().

207  : con_sys(check_space_dimension_overflow(os.space_dimension(),
209  "PPL::Grid::",
210  "Grid(os)",
211  "the space dimension of os "
212  "exceeds the maximum allowed "
213  "space dimension")),
214  gen_sys(os.space_dimension()) {
215  Congruence_System cgs = os.congruences();
216  construct(cgs);
217 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Parma_Polyhedra_Library::Grid::Grid ( const Polyhedron ph,
Complexity_Class  complexity = ANY_COMPLEXITY 
)
explicit

Builds a grid from a polyhedron using algorithms whose complexity does not exceed the one specified by complexity. If complexity is ANY_COMPLEXITY, then the grid built is the smallest one containing ph.

The grid inherits the space dimension of polyhedron.

Parameters
phThe polyhedron.
complexityThe complexity class.
Exceptions
std::length_errorThrown if num_dimensions exceeds the maximum allowed space dimension.

Definition at line 150 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::all_homogeneous_terms_are_zero(), Parma_Polyhedra_Library::ANY_COMPLEXITY, Parma_Polyhedra_Library::Coefficient_one(), Parma_Polyhedra_Library::Polyhedron::constraints(), Parma_Polyhedra_Library::Polyhedron::constraints_are_minimized(), Parma_Polyhedra_Library::Polyhedron::constraints_are_up_to_date(), construct(), Parma_Polyhedra_Library::Polyhedron::generators(), Parma_Polyhedra_Library::Polyhedron::generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Polyhedron::is_empty(), Parma_Polyhedra_Library::Linear_Expression::linear_combine(), Parma_Polyhedra_Library::Polyhedron::marked_empty(), Parma_Polyhedra_Library::Polyhedron::minimize(), OK(), PPL_DIRTY_TEMP_COEFFICIENT, set_empty(), Parma_Polyhedra_Library::Linear_Expression::set_space_dimension(), set_zero_dim_univ(), space_dim, and Parma_Polyhedra_Library::Polyhedron::space_dimension().

152  : con_sys(check_space_dimension_overflow(ph.space_dimension(),
154  "PPL::Grid::",
155  "Grid(ph)",
156  "the space dimension of ph "
157  "exceeds the maximum allowed "
158  "space dimension")),
159  gen_sys(ph.space_dimension()) {
160  space_dim = ph.space_dimension();
161 
162  // A zero-dim polyhedron causes no complexity problems.
163  if (space_dim == 0) {
164  if (ph.is_empty()) {
165  set_empty();
166  }
167  else {
169  }
170  return;
171  }
172 
173  // A polyhedron known to be empty causes no complexity problems.
174  if (ph.marked_empty()) {
175  set_empty();
176  return;
177  }
178 
179  const bool use_constraints = ph.constraints_are_minimized()
180  || !ph.generators_are_up_to_date();
181 
182  // Minimize the constraint description if it is needed and
183  // the complexity allows it.
184  if (use_constraints && complexity == ANY_COMPLEXITY) {
185  if (!ph.minimize()) {
186  set_empty();
187  return;
188  }
189  }
190  if (use_constraints) {
191  // Only the equality constraints need be used.
192  PPL_ASSERT(ph.constraints_are_up_to_date());
193  const Constraint_System& cs = ph.constraints();
194  Congruence_System cgs(space_dim);
195  for (Constraint_System::const_iterator i = cs.begin(),
196  cs_end = cs.end(); i != cs_end; ++i) {
197  if (i->is_equality()) {
198  cgs.insert(*i);
199  }
200  }
201  construct(cgs);
202  }
203  else {
204  // First find a point or closure point and convert it to a
205  // grid point and add to the (initially empty) set of grid generators.
206  PPL_ASSERT(ph.generators_are_up_to_date());
207  const Generator_System& gs = ph.generators();
208  Grid_Generator_System ggs(space_dim);
209  Linear_Expression point_expr;
210  point_expr.set_space_dimension(space_dim);
211  PPL_DIRTY_TEMP_COEFFICIENT(point_divisor);
212  for (Generator_System::const_iterator g = gs.begin(),
213  gs_end = gs.end(); g != gs_end; ++g) {
214  if (g->is_point() || g->is_closure_point()) {
215  point_expr.linear_combine(g->expr, Coefficient_one(), Coefficient_one(),
216  1, space_dim + 1);
217  point_divisor = g->divisor();
218  ggs.insert(grid_point(point_expr, point_divisor));
219  break;
220  }
221  }
222  // Add grid lines for all the other generators.
223  // If the polyhedron's generator is a (closure) point, the grid line must
224  // have the direction given by a line that joins the grid point already
225  // inserted and the new point.
226  for (Generator_System::const_iterator g = gs.begin(),
227  gs_end = gs.end(); g != gs_end; ++g) {
228  Linear_Expression e;
229  e.set_space_dimension(space_dim);
230  if (g->is_point() || g->is_closure_point()) {
231  e.linear_combine(point_expr, Coefficient_one(), g->divisor(),
232  1, space_dim + 1);
233  e.linear_combine(g->expr, Coefficient_one(), -point_divisor,
234  1, space_dim + 1);
235  if (e.all_homogeneous_terms_are_zero()) {
236  continue;
237  }
238  }
239  else {
240  e.linear_combine(g->expr, Coefficient_one(), Coefficient_one(),
241  1, space_dim + 1);
242  }
243  ggs.insert(grid_line(e));
244  }
245  construct(ggs);
246  }
247  PPL_ASSERT(OK());
248 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
Generator_System_const_iterator const_iterator
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
void construct(dimension_type num_dimensions, Degenerate_Element kind)
Builds a grid universe or empty grid.
Constraint_System_const_iterator const_iterator
Parma_Polyhedra_Library::Grid::Grid ( const Grid y,
Complexity_Class  complexity = ANY_COMPLEXITY 
)

Ordinary copy constructor.

The complexity argument is ignored.

Definition at line 38 of file Grid_public.cc.

References con_sys, congruences_are_up_to_date(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::set_space_dimension(), and space_dim.

39  : con_sys(),
40  gen_sys(),
41  status(y.status),
42  space_dim(y.space_dim),
43  dim_kinds(y.dim_kinds) {
44  if (space_dim == 0) {
45  con_sys = y.con_sys;
46  gen_sys = y.gen_sys;
47  }
48  else {
49  if (y.congruences_are_up_to_date()) {
50  con_sys = y.con_sys;
51  }
52  else {
54  }
55  if (y.generators_are_up_to_date()) {
56  gen_sys = y.gen_sys;
57  }
58  else {
59  gen_sys = Grid_Generator_System(y.space_dim);
60  }
61  }
62 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool set_space_dimension(dimension_type new_space_dim)
Sets the number of space dimensions to new_space_dim.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
Parma_Polyhedra_Library::Grid::~Grid ( )
inline

Destructor.

Definition at line 220 of file Grid_inlines.hh.

220  {
221 }

Member Function Documentation

void Parma_Polyhedra_Library::Grid::add_congruence ( const Congruence cg)
inline

Adds a copy of congruence cg to *this.

Exceptions
std::invalid_argumentThrown if *this and congruence cg are dimension-incompatible.

Definition at line 259 of file Grid_inlines.hh.

References add_congruence_no_check(), marked_empty(), space_dim, Parma_Polyhedra_Library::Congruence::space_dimension(), and throw_dimension_incompatible().

Referenced by Parma_Polyhedra_Library::Affine_Space::add_congruence(), Parma_Polyhedra_Library::Pointset_Powerset< PSET >::approximate_partition_aux(), refine_with_congruence(), and simplify_using_context_assign().

259  {
260  // Dimension-compatibility check.
261  if (space_dim < cg.space_dimension()) {
262  throw_dimension_incompatible("add_congruence(cg)", "cg", cg);
263  }
264 
265  if (!marked_empty()) {
267  }
268 }
void add_congruence_no_check(const Congruence &cg)
Adds the congruence cg to *this.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void Parma_Polyhedra_Library::Grid::add_congruence_no_check ( const Congruence cg)
private

Adds the congruence cg to *this.

Warning
If cg and *this are dimension-incompatible, the grid generator system is not minimized or *this is empty, then the behavior is undefined.

Definition at line 678 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Congruence::is_inconsistent(), and Parma_Polyhedra_Library::Congruence::space_dimension().

Referenced by add_congruence(), and difference_assign().

678  {
679  PPL_ASSERT(!marked_empty());
680  PPL_ASSERT(space_dim >= cg.space_dimension());
681 
682  // Dealing with a zero-dimensional space grid first.
683  if (space_dim == 0) {
684  if (cg.is_inconsistent()) {
685  set_empty();
686  }
687  return;
688  }
689 
692  }
693 
694  con_sys.insert(cg);
695 
699 
700  // Note: the congruence system may have become unsatisfiable, thus
701  // we do not check for satisfiability.
702  PPL_ASSERT(OK());
703 }
void clear_congruences_minimized()
Sets status to express that congruences are no longer minimized.
Definition: Grid_inlines.hh:87
void clear_generators_up_to_date()
Sets status to express that generators are out of date.
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void update_congruences() const
Updates and minimizes the congruences from the generators.
void set_congruences_up_to_date()
Sets status to express that congruences are up-to-date.
Definition: Grid_inlines.hh:65
void Parma_Polyhedra_Library::Grid::add_congruences ( const Congruence_System cgs)
inline

Adds a copy of each congruence in cgs to *this.

Parameters
cgsContains the congruences that will be added to the system of congruences of *this.
Exceptions
std::invalid_argumentThrown if *this and cgs are dimension-incompatible.

Definition at line 271 of file Grid_inlines.hh.

References add_recycled_congruences(), marked_empty(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), and throw_dimension_incompatible().

Referenced by Parma_Polyhedra_Library::Affine_Space::add_congruences(), refine_with_congruences(), and simplify_using_context_assign().

271  {
272  // TODO: this is just an executable specification.
273  // Space dimension compatibility check.
274  if (space_dim < cgs.space_dimension()) {
275  throw_dimension_incompatible("add_congruences(cgs)", "cgs", cgs);
276  }
277 
278  if (!marked_empty()) {
279  Congruence_System cgs_copy = cgs;
280  add_recycled_congruences(cgs_copy);
281  }
282 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void add_recycled_congruences(Congruence_System &cgs)
Adds the congruences in cgs to *this.
void Parma_Polyhedra_Library::Grid::add_constraint ( const Constraint c)
inline

Adds to *this a congruence equivalent to constraint c.

Parameters
cThe constraint to be added.
Exceptions
std::invalid_argumentThrown if *this and c are dimension-incompatible or if constraint c is not optimally supported by the grid domain.

Definition at line 305 of file Grid_inlines.hh.

References add_constraint_no_check(), marked_empty(), space_dim, Parma_Polyhedra_Library::Constraint::space_dimension(), and throw_dimension_incompatible().

Referenced by Parma_Polyhedra_Library::Affine_Space::add_constraint().

305  {
306  // Space dimension compatibility check.
307  if (space_dim < c.space_dimension()) {
308  throw_dimension_incompatible("add_constraint(c)", "c", c);
309  }
310  if (!marked_empty()) {
312  }
313 }
void add_constraint_no_check(const Constraint &c)
Uses the constraint c to refine *this.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
Coefficient c
Definition: PIP_Tree.cc:64
void Parma_Polyhedra_Library::Grid::add_constraint_no_check ( const Constraint c)
private

Uses the constraint c to refine *this.

Parameters
cThe constraint to be added.
Exceptions
std::invalid_argumentThrown if c is a non-trivial inequality constraint.
Warning
If c and *this are dimension-incompatible, the behavior is undefined.

Definition at line 706 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Constraint::is_inconsistent(), Parma_Polyhedra_Library::Constraint::is_inequality(), Parma_Polyhedra_Library::Constraint::is_tautological(), and Parma_Polyhedra_Library::Constraint::space_dimension().

Referenced by add_constraint().

706  {
707  PPL_ASSERT(!marked_empty());
708  PPL_ASSERT(space_dim >= c.space_dimension());
709 
710  if (c.is_inequality()) {
711  // Only trivial inequalities can be handled.
712  if (c.is_inconsistent()) {
713  set_empty();
714  return;
715  }
716  if (c.is_tautological()) {
717  return;
718  }
719  // Non-trivial inequality constraints are not allowed.
720  throw_invalid_constraint("add_constraint(c)", "c");
721  }
722 
723  PPL_ASSERT(c.is_equality());
724  const Congruence cg(c);
726 }
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
void add_congruence_no_check(const Congruence &cg)
Adds the congruence cg to *this.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
Coefficient c
Definition: PIP_Tree.cc:64
static void throw_invalid_constraint(const char *method, const char *c_name)
void Parma_Polyhedra_Library::Grid::add_constraints ( const Constraint_System cs)

Adds to *this congruences equivalent to the constraints in cs.

Parameters
csThe constraints to be added.
Exceptions
std::invalid_argumentThrown if *this and cs are dimension-incompatible or if cs contains a constraint which is not optimally supported by the grid domain.

Definition at line 1220 of file Grid_public.cc.

References Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Constraint_System::end(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

Referenced by add_recycled_constraints().

1220  {
1221  // The dimension of `cs' must be at most `space_dim'.
1222  if (space_dim < cs.space_dimension()) {
1223  throw_dimension_incompatible("add_constraints(cs)", "cs", cs);
1224  }
1225  if (marked_empty()) {
1226  return;
1227  }
1228 
1229  for (Constraint_System::const_iterator i = cs.begin(),
1230  cs_end = cs.end(); i != cs_end; ++i) {
1232  if (marked_empty()) {
1233  return;
1234  }
1235  }
1236 }
void add_constraint_no_check(const Constraint &c)
Uses the constraint c to refine *this.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
Constraint_System_const_iterator const_iterator
void Parma_Polyhedra_Library::Grid::add_grid_generator ( const Grid_Generator g)

Adds a copy of grid generator g to the system of generators of *this.

Exceptions
std::invalid_argumentThrown if *this and generator g are dimension-incompatible, or if *this is an empty grid and g is not a point.

Definition at line 1239 of file Grid_public.cc.

References Parma_Polyhedra_Library::Grid_Generator::is_line_or_parameter(), Parma_Polyhedra_Library::Grid_Generator::is_parameter(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), and Parma_Polyhedra_Library::Grid_Generator::space_dimension().

1239  {
1240  // The dimension of `g' must be at most space_dim.
1241  const dimension_type g_space_dim = g.space_dimension();
1242  if (space_dim < g_space_dim) {
1243  throw_dimension_incompatible("add_grid_generator(g)", "g", g);
1244  }
1245 
1246  // Deal with zero-dimension case first.
1247  if (space_dim == 0) {
1248  // Points and parameters are the only zero-dimension generators
1249  // that can be created.
1250  if (marked_empty()) {
1251  if (g.is_parameter()) {
1252  throw_invalid_generator("add_grid_generator(g)", "g");
1253  }
1255  }
1256  PPL_ASSERT(OK());
1257  return;
1258  }
1259 
1260  if (marked_empty()
1262  // Here the grid is empty: the specification says we can only
1263  // insert a point.
1264  if (g.is_line_or_parameter()) {
1265  throw_invalid_generator("add_grid_generator(g)", "g");
1266  }
1267  gen_sys.insert(g);
1268  clear_empty();
1269  }
1270  else {
1271  PPL_ASSERT(generators_are_up_to_date());
1272  gen_sys.insert(g);
1273  if (g.is_parameter_or_point()) {
1275  }
1276  }
1277 
1278  // With the added generator, congruences are out of date.
1280 
1283  PPL_ASSERT(OK());
1284 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
static void throw_invalid_generator(const char *method, const char *g_name)
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void set_generators_up_to_date()
Sets status to express that generators are up-to-date.
Definition: Grid_inlines.hh:60
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void clear_empty()
Clears the status flag indicating that the grid is empty.
Definition: Grid_inlines.hh:82
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
bool update_generators() const
Updates and minimizes the generators from the congruences.
void Parma_Polyhedra_Library::Grid::add_grid_generators ( const Grid_Generator_System gs)

Adds a copy of the generators in gs to the system of generators of *this.

Parameters
gsContains the generators that will be added to the system of generators of *this.
Exceptions
std::invalid_argumentThrown if *this and gs are dimension-incompatible, or if *this is empty and the system of generators gs is not empty, but has no points.

Definition at line 1396 of file Grid_public.cc.

1396  {
1397  // TODO: this is just an executable specification.
1398  Grid_Generator_System gs_copy = gs;
1400 }
void add_recycled_grid_generators(Grid_Generator_System &gs)
Adds the generators in gs to the system of generators of this.
void Parma_Polyhedra_Library::Grid::add_recycled_congruences ( Congruence_System cgs)

Adds the congruences in cgs to *this.

Parameters
cgsThe congruence system to be added to *this. The congruences in cgs may be recycled.
Exceptions
std::invalid_argumentThrown if *this and cgs are dimension-incompatible.
Warning
The only assumption that can be made about cgs upon successful or exceptional return is that it can be safely destroyed.

Definition at line 1287 of file Grid_public.cc.

References Parma_Polyhedra_Library::Congruence_System::begin(), Parma_Polyhedra_Library::Congruence_System::end(), Parma_Polyhedra_Library::Congruence_System::has_no_rows(), and Parma_Polyhedra_Library::Congruence_System::space_dimension().

Referenced by add_congruences(), congruence_widening_assign(), contains_integer_point(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), and simplify_using_context_assign().

1287  {
1288  // Dimension-compatibility check.
1289  const dimension_type cgs_space_dim = cgs.space_dimension();
1290  if (space_dim < cgs_space_dim) {
1291  throw_dimension_incompatible("add_recycled_congruences(cgs)", "cgs", cgs);
1292  }
1293 
1294  if (cgs.has_no_rows()) {
1295  return;
1296  }
1297 
1298  if (marked_empty()) {
1299  return;
1300  }
1301 
1302  if (space_dim == 0) {
1303  // In a 0-dimensional space the congruences are trivial (e.g., 0
1304  // == 0 or 1 %= 0) or false (e.g., 1 == 0). In a system of
1305  // congruences `begin()' and `end()' are equal if and only if the
1306  // system contains only trivial congruences.
1307  if (cgs.begin() != cgs.end()) {
1308  // There is a congruence, it must be false, the grid becomes empty.
1309  set_empty();
1310  }
1311  return;
1312  }
1313 
1314  // The congruences are required.
1315  if (!congruences_are_up_to_date()) {
1317  }
1318 
1319  // Swap (instead of copying) the coefficients of `cgs' (which is
1320  // writable).
1321  con_sys.insert(cgs, Recycle_Input());
1322 
1323  // Congruences may not be minimized and generators are out of date.
1326  // Note: the congruence system may have become unsatisfiable, thus
1327  // we do not check for satisfiability.
1328  PPL_ASSERT(OK());
1329 }
void clear_congruences_minimized()
Sets status to express that congruences are no longer minimized.
Definition: Grid_inlines.hh:87
void clear_generators_up_to_date()
Sets status to express that generators are out of date.
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void update_congruences() const
Updates and minimizes the congruences from the generators.
void Parma_Polyhedra_Library::Grid::add_recycled_constraints ( Constraint_System cs)
inline

Adds to *this congruences equivalent to the constraints in cs.

Parameters
csThe constraints to be added. They may be recycled.
Exceptions
std::invalid_argumentThrown if *this and cs are dimension-incompatible or if cs contains a constraint which is not optimally supported by the grid domain.
Warning
The only assumption that can be made about cs upon successful or exceptional return is that it can be safely destroyed.

Definition at line 316 of file Grid_inlines.hh.

References add_constraints().

Referenced by Parma_Polyhedra_Library::Affine_Space::add_recycled_constraints().

316  {
317  // TODO: really recycle the constraints.
318  add_constraints(cs);
319 }
void add_constraints(const Constraint_System &cs)
Adds to *this congruences equivalent to the constraints in cs.
void Parma_Polyhedra_Library::Grid::add_recycled_grid_generators ( Grid_Generator_System gs)

Adds the generators in gs to the system of generators of this.

Parameters
gsThe generator system to be added to *this. The generators in gs may be recycled.
Exceptions
std::invalid_argumentThrown if *this and gs are dimension-incompatible.
Warning
The only assumption that can be made about gs upon successful or exceptional return is that it can be safely destroyed.

Definition at line 1332 of file Grid_public.cc.

References Parma_Polyhedra_Library::Grid_Generator_System::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::has_points(), Parma_Polyhedra_Library::Grid_Generator_System::set_space_dimension(), and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().

Referenced by generator_widening_assign().

1332  {
1333  // Dimension-compatibility check.
1334  const dimension_type gs_space_dim = gs.space_dimension();
1335  if (space_dim < gs_space_dim) {
1336  throw_dimension_incompatible("add_recycled_grid_generators(gs)", "gs", gs);
1337  }
1338 
1339  // Adding no generators leaves the grid the same.
1340  if (gs.has_no_rows()) {
1341  return;
1342  }
1343 
1344  // Adding valid generators to a zero-dimensional grid transforms it
1345  // to the zero-dimensional universe grid.
1346  if (space_dim == 0) {
1347  if (marked_empty()) {
1349  }
1350  else {
1351  PPL_ASSERT(gs.has_points());
1352  }
1353  PPL_ASSERT(OK(true));
1354  return;
1355  }
1356 
1357  if (!marked_empty()) {
1358  // The grid contains at least one point.
1359 
1360  if (!generators_are_up_to_date()) {
1362  }
1364 
1365  gen_sys.insert(gs, Recycle_Input());
1366 
1367  // Congruences are out of date and generators are not minimized.
1370 
1371  PPL_ASSERT(OK(true));
1372  return;
1373  }
1374 
1375  // The grid is empty.
1376 
1377  // `gs' must contain at least one point.
1378  if (!gs.has_points()) {
1379  throw_invalid_generators("add_recycled_grid_generators(gs)", "gs");
1380  }
1381  // Adjust `gs' to the right dimension.
1382  gs.set_space_dimension(space_dim);
1383 
1384  gen_sys.m_swap(gs);
1385 
1387 
1388  // The grid is no longer empty and generators are up-to-date.
1390  clear_empty();
1391 
1392  PPL_ASSERT(OK());
1393 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void m_swap(Grid_Generator_System &y)
Swaps *this with y.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void set_generators_up_to_date()
Sets status to express that generators are up-to-date.
Definition: Grid_inlines.hh:60
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
static void throw_invalid_generators(const char *method, const char *gs_name)
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void clear_empty()
Clears the status flag indicating that the grid is empty.
Definition: Grid_inlines.hh:82
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
bool update_generators() const
Updates and minimizes the generators from the congruences.
void Parma_Polyhedra_Library::Grid::add_space_dimensions ( Congruence_System cgs,
Grid_Generator_System gs,
dimension_type  dims 
)
private

Adds new space dimensions to the given systems.

Parameters
cgsA congruence system, to which columns are added;
gsA generator system, to which rows and columns are added;
dimsThe number of space dimensions to add.

This method is invoked only by add_space_dimensions_and_embed().

Definition at line 34 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::Grid_Generator_System::add_universe_rows_and_columns(), CON_VIRTUAL, congruences_are_minimized(), dim_kinds, generators_are_minimized(), Parma_Polyhedra_Library::Congruence_System::set_space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and space_dimension().

36  {
37  PPL_ASSERT(cgs.space_dimension() == gs.space_dimension());
38  PPL_ASSERT(dims > 0);
39 
40  const dimension_type old_modulus_index = cgs.space_dimension() + 1;
41  cgs.set_space_dimension(space_dimension() + dims);
42 
44  dim_kinds.resize(old_modulus_index + dims, CON_VIRTUAL /* a.k.a. LINE */);
45  }
46 
47  gs.add_universe_rows_and_columns(dims);
48 }
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
size_t dimension_type
An unsigned integral type for representing space dimensions.
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
void Parma_Polyhedra_Library::Grid::add_space_dimensions ( Grid_Generator_System gs,
Congruence_System cgs,
dimension_type  dims 
)
private

Adds new space dimensions to the given systems.

Parameters
gsA generator system, to which columns are added;
cgsA congruence system, to which rows and columns are added;
dimsThe number of space dimensions to add.

This method is invoked only by add_space_dimensions_and_project().

Definition at line 52 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::Congruence_System::add_unit_rows_and_space_dimensions(), Parma_Polyhedra_Library::Grid_Generator_System::set_space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().

54  {
55  PPL_ASSERT(cgs.space_dimension() == gs.space_dimension());
56  PPL_ASSERT(dims > 0);
57 
58  cgs.add_unit_rows_and_space_dimensions(dims);
59 
60  // Add `dims' zero columns onto gs.
61  gs.set_space_dimension(space_dim + dims);
62 
64 
65  dim_kinds.resize(cgs.space_dimension() + 1, EQUALITY /* a.k.a GEN_VIRTUAL */);
66 }
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void Parma_Polyhedra_Library::Grid::add_space_dimensions_and_embed ( dimension_type  m)

Adds m new space dimensions and embeds the old grid in the new vector space.

Parameters
mThe number of dimensions to add.
Exceptions
std::length_errorThrown if adding m new space dimensions would cause the vector space to exceed dimension max_space_dimension().

The new space dimensions will be those having the highest indexes in the new grid, which is characterized by a system of congruences in which the variables which are the new dimensions can have any value. For instance, when starting from the grid $\cL \sseq \Rset^2$ and adding a third space dimension, the result will be the grid

\[ \bigl\{\, (x, y, z)^\transpose \in \Rset^3 \bigm| (x, y)^\transpose \in \cL \,\bigr\}. \]

Definition at line 77 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::check_space_dimension_overflow(), Parma_Polyhedra_Library::max_space_dimension(), and Parma_Polyhedra_Library::UNIVERSE.

Referenced by simplify_using_context_assign().

77  {
78  if (m == 0) {
79  return;
80  }
81 
82  // The space dimension of the resulting grid must be at most the
83  // maximum allowed space dimension.
85  "PPL::Grid::",
86  "add_space_dimensions_and_embed(m)",
87  "adding m new space dimensions exceeds "
88  "the maximum allowed space dimension");
89 
90  // Adding dimensions to an empty grid is obtained by adjusting
91  // `space_dim' and clearing `con_sys' (since it can contain the
92  // integrality congruence of the current dimension).
93  if (marked_empty()) {
94  space_dim += m;
95  set_empty();
96  return;
97  }
98 
99  // The case of a zero-dimension space grid.
100  if (space_dim == 0) {
101  // Since it is not empty, it has to be the universe grid.
102  PPL_ASSERT(status.test_zero_dim_univ());
103  // Swap *this with a newly created `m'-dimensional universe grid.
104  Grid gr(m, UNIVERSE);
105  m_swap(gr);
106  return;
107  }
108 
109  // To embed an n-dimension space grid in a (n+m)-dimension space, we
110  // add `m' zero-columns to the rows in the system of congruences; in
111  // contrast, the system of generators needs additional rows,
112  // corresponding to the vectors of the canonical basis for the added
113  // dimensions. That is, for each new dimension we add the line
114  // having that direction. This is done by invoking the function
115  // add_space_dimensions().
118  // Adds rows and/or columns to both matrices.
120  }
121  else {
122  // Only congruences are up-to-date, so modify only them.
126  }
127  }
128  }
129  else {
130  // Only generators are up-to-date, so modify only them.
131  PPL_ASSERT(generators_are_up_to_date());
133  if (generators_are_minimized()) {
134  dim_kinds.resize(gen_sys.space_dimension() + 1, LINE);
135  }
136  }
137  // Update the space dimension.
138  space_dim += m;
139 
140  // Note: we do not check for satisfiability, because the system of
141  // congruences may be unsatisfiable.
142  PPL_ASSERT(OK());
143 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void add_space_dimensions(Congruence_System &cgs, Grid_Generator_System &gs, dimension_type dims)
Adds new space dimensions to the given systems.
Definition: Grid_chdims.cc:34
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool set_space_dimension(dimension_type new_space_dim)
Sets the number of space dimensions to new_space_dim.
void add_universe_rows_and_columns(dimension_type dims)
Adds dims rows and dims columns of zeroes to the matrix, initializing the added rows as in the univer...
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
The universe element, i.e., the whole vector space.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void m_swap(Grid &y)
Swaps *this with grid y. (*this and y can be dimension-incompatible.)
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
void Parma_Polyhedra_Library::Grid::add_space_dimensions_and_project ( dimension_type  m)

Adds m new space dimensions to the grid and does not embed it in the new vector space.

Parameters
mThe number of space dimensions to add.
Exceptions
std::length_errorThrown if adding m new space dimensions would cause the vector space to exceed dimension max_space_dimension().

The new space dimensions will be those having the highest indexes in the new grid, which is characterized by a system of congruences in which the variables running through the new dimensions are all constrained to be equal to 0. For instance, when starting from the grid $\cL \sseq \Rset^2$ and adding a third space dimension, the result will be the grid

\[ \bigl\{\, (x, y, 0)^\transpose \in \Rset^3 \bigm| (x, y)^\transpose \in \cL \,\bigr\}. \]

Definition at line 154 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::check_space_dimension_overflow(), Parma_Polyhedra_Library::max_space_dimension(), and Parma_Polyhedra_Library::UNIVERSE.

154  {
155  if (m == 0) {
156  return;
157  }
158 
159  // The space dimension of the resulting grid should be at most the
160  // maximum allowed space dimension.
162  "PPL::Grid::",
163  "add_space_dimensions_and_project(m)",
164  "adding m new space dimensions exceeds "
165  "the maximum allowed space dimension");
166 
167  // Adding dimensions to an empty grid is obtained by merely
168  // adjusting `space_dim'.
169  if (marked_empty()) {
170  space_dim += m;
171  set_empty();
172  return;
173  }
174 
175  if (space_dim == 0) {
176  PPL_ASSERT(status.test_zero_dim_univ());
177  // Swap *this with a newly created `n'-dimensional universe grid.
178  Grid gr(m, UNIVERSE);
179  m_swap(gr);
180  return;
181  }
182 
183  // To project an n-dimension space grid in a (n+m)-dimension space,
184  // we just add to the system of generators `m' zero-columns; in
185  // contrast, in the system of congruences, new rows are needed in
186  // order to avoid embedding the old grid in the new space. Thus,
187  // for each new dimensions `x[k]', we add the constraint x[k] = 0;
188  // this is done by invoking the function add_space_dimensions()
189  // giving the system of constraints as the second argument.
192  // Add rows and/or columns to both matrices.
194  }
195  else {
196  // Only congruences are up-to-date so modify only them.
199  dim_kinds.resize(con_sys.space_dimension() + 1, EQUALITY);
200  }
201  }
202  }
203  else {
204  // Only generators are up-to-date so modify only them.
205  PPL_ASSERT(generators_are_up_to_date());
206 
207  // Add m zero columns onto gs.
209 
211 
212  if (generators_are_minimized()) {
213  dim_kinds.resize(gen_sys.space_dimension() + 1, EQUALITY);
214  }
215  }
216  // Now update the space dimension.
217  space_dim += m;
218 
219  // Note: we do not check for satisfiability, because the system of
220  // congruences may be unsatisfiable.
221  PPL_ASSERT(OK());
222 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void add_space_dimensions(Congruence_System &cgs, Grid_Generator_System &gs, dimension_type dims)
Adds new space dimensions to the given systems.
Definition: Grid_chdims.cc:34
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void set_space_dimension(dimension_type space_dim)
Resizes the system to the specified space dimension.
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
The universe element, i.e., the whole vector space.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void m_swap(Grid &y)
Swaps *this with grid y. (*this and y can be dimension-incompatible.)
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
void add_unit_rows_and_space_dimensions(dimension_type dims)
Adds dims rows and dims space dimensions to the matrix, initializing the added rows as in the unit co...
PPL::dimension_type Parma_Polyhedra_Library::Grid::affine_dimension ( ) const

Returns $0$, if *this is empty; otherwise, returns the affine dimension of *this.

Definition at line 273 of file Grid_public.cc.

273  {
274  if (space_dim == 0 || is_empty()) {
275  return 0;
276  }
277 
279  if (generators_are_minimized()) {
280  return gen_sys.num_rows() - 1;
281  }
283  return minimized_grid_generators().num_rows() - 1;
284  }
285  }
286  else {
288  }
289  PPL_ASSERT(congruences_are_minimized());
291  for (dimension_type i = con_sys.num_rows(); i-- > 0; ) {
292  if (con_sys[i].is_equality()) {
293  --d;
294  }
295  }
296  return d;
297 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
const Grid_Generator_System & minimized_grid_generators() const
Returns the minimized system of generators.
Definition: Grid_public.cc:356
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
const Congruence_System & minimized_congruences() const
Returns the system of congruences in minimal form.
Definition: Grid_public.cc:319
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
dimension_type num_rows() const
Returns the number of rows in the system.
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool is_empty() const
Returns true if and only if *this is an empty grid.
Definition: Grid_public.cc:742
void Parma_Polyhedra_Library::Grid::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 to the affine expression specified by expr and denominator.

Parameters
varThe variable to which the affine expression is assigned;
exprThe numerator of the affine expression;
denominatorThe denominator of the affine expression (optional argument with default value 1).
Exceptions
std::invalid_argumentThrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a space dimension of *this.

When considering the generators of a grid, the affine transformation

\[ \frac{\sum_{i=0}^{n-1} a_i x_i + b}{\mathrm{denominator}} \]

is assigned to var where expr is $\sum_{i=0}^{n-1} a_i x_i + b$ ( $b$ is the inhomogeneous term).

If congruences are up-to-date, it uses the specialized function affine_preimage() (for the system of congruences) and inverse transformation to reach the same result. To obtain the inverse transformation we use the following observation.

Observation:

  1. The affine transformation is invertible if the coefficient of var in this transformation (i.e., $a_\mathrm{var}$) is different from zero.
  2. If the transformation is invertible, then we can write

    \[ \mathrm{denominator} * {x'}_\mathrm{var} = \sum_{i = 0}^{n - 1} a_i x_i + b = a_\mathrm{var} x_\mathrm{var} + \sum_{i \neq var} a_i x_i + b, \]

    so that the inverse transformation is

    \[ a_\mathrm{var} x_\mathrm{var} = \mathrm{denominator} * {x'}_\mathrm{var} - \sum_{i \neq j} a_i x_i - b. \]

Then, if the transformation is invertible, all the entities that were up-to-date remain up-to-date. Otherwise only generators remain up-to-date.

Definition at line 1887 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::inverse(), Parma_Polyhedra_Library::Linear_Expression::set_coefficient(), Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

Referenced by fold_space_dimensions().

1889  {
1890  // The denominator cannot be zero.
1891  if (denominator == 0) {
1892  throw_invalid_argument("affine_image(v, e, d)", "d == 0");
1893  }
1894 
1895  // Dimension-compatibility checks.
1896  // The dimension of `expr' must be at most the dimension of `*this'.
1897  const dimension_type expr_space_dim = expr.space_dimension();
1898  if (space_dim < expr_space_dim) {
1899  throw_dimension_incompatible("affine_image(v, e, d)", "e", expr);
1900  }
1901  // `var' must be one of the dimensions of the grid.
1902  const dimension_type var_space_dim = var.space_dimension();
1903  if (space_dim < var_space_dim) {
1904  throw_dimension_incompatible("affine_image(v, e, d)", "v", var);
1905  }
1906 
1907  if (marked_empty()) {
1908  return;
1909  }
1910 
1911  Coefficient_traits::const_reference expr_var = expr.coefficient(var);
1912 
1913  if (var_space_dim <= expr_space_dim
1914  && expr_var != 0) {
1915  // The transformation is invertible.
1916  if (generators_are_up_to_date()) {
1917  // Grid_Generator_System::affine_image() requires the third argument
1918  // to be a positive Coefficient.
1919  if (denominator > 0) {
1920  gen_sys.affine_image(var, expr, denominator);
1921  }
1922  else {
1923  gen_sys.affine_image(var, -expr, -denominator);
1924  }
1926  // Strong normalization in gs::affine_image may have modified
1927  // divisors.
1929  }
1931  // To build the inverse transformation,
1932  // after copying and negating `expr',
1933  // we exchange the roles of `expr[var_space_dim]' and `denominator'.
1934  Linear_Expression inverse;
1935  if (expr_var > 0) {
1936  inverse = -expr;
1937  inverse.set_coefficient(var, denominator);
1938  con_sys.affine_preimage(var, inverse, expr_var);
1939  }
1940  else {
1941  // The new denominator is negative: we negate everything once
1942  // more, as Congruence_System::affine_preimage() requires the
1943  // third argument to be positive.
1944  inverse = expr;
1945  inverse.set_coefficient(var, -denominator);
1946  con_sys.affine_preimage(var, inverse, -expr_var);
1947  }
1949  }
1950  }
1951  else {
1952  // The transformation is not invertible.
1953  // We need an up-to-date system of generators.
1954  if (!generators_are_up_to_date()) {
1955  minimize();
1956  }
1957  if (!marked_empty()) {
1958  // Grid_Generator_System::affine_image() requires the third argument
1959  // to be a positive Coefficient.
1960  if (denominator > 0) {
1961  gen_sys.affine_image(var, expr, denominator);
1962  }
1963  else {
1964  gen_sys.affine_image(var, -expr, -denominator);
1965  }
1966 
1969  // Strong normalization in gs::affine_image may have modified
1970  // divisors.
1972  }
1973  }
1974  PPL_ASSERT(OK());
1975 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void clear_congruences_minimized()
Sets status to express that congruences are no longer minimized.
Definition: Grid_inlines.hh:87
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
Rounding_Dir inverse(Rounding_Dir dir)
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void affine_preimage(Variable v, const Linear_Expression &expr, Coefficient_traits::const_reference denominator)
Substitutes a given column of coefficients by a given affine expression.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void affine_image(Variable v, const Linear_Expression &expr, Coefficient_traits::const_reference denominator)
Assigns to a given variable an affine expression.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
bool minimize() const
Minimizes both the congruences and the generators.
void Parma_Polyhedra_Library::Grid::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 to the affine expression specified by expr and denominator.

Parameters
varThe variable to which the affine expression is substituted;
exprThe numerator of the affine expression;
denominatorThe denominator of the affine expression (optional argument with default value 1).
Exceptions
std::invalid_argumentThrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a space dimension of *this.

When considering congruences of a grid, the affine transformation

\[ \frac{\sum_{i=0}^{n-1} a_i x_i + b}{denominator}, \]

is assigned to var where expr is $\sum_{i=0}^{n-1} a_i x_i + b$ ( $b$ is the inhomogeneous term).

If generators are up-to-date, then the specialized function affine_image() is used (for the system of generators) and inverse transformation to reach the same result. To obtain the inverse transformation, we use the following observation.

Observation:

  1. The affine transformation is invertible if the coefficient of var in this transformation (i.e. $a_\mathrm{var}$) is different from zero.
  2. If the transformation is invertible, then we can write

    \[ \mathrm{denominator} * {x'}_\mathrm{var} = \sum_{i = 0}^{n - 1} a_i x_i + b = a_\mathrm{var} x_\mathrm{var} + \sum_{i \neq \mathrm{var}} a_i x_i + b, \]

    , the inverse transformation is

    \[ a_\mathrm{var} x_\mathrm{var} = \mathrm{denominator} * {x'}_\mathrm{var} - \sum_{i \neq j} a_i x_i - b. \]

    .

Then, if the transformation is invertible, all the entities that were up-to-date remain up-to-date. Otherwise only congruences remain up-to-date.

Definition at line 1979 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::inverse(), Parma_Polyhedra_Library::Linear_Expression::set_coefficient(), Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

1981  {
1982  // The denominator cannot be zero.
1983  if (denominator == 0) {
1984  throw_invalid_argument("affine_preimage(v, e, d)", "d == 0");
1985  }
1986 
1987  // Dimension-compatibility checks.
1988  // The dimension of `expr' should not be greater than the dimension
1989  // of `*this'.
1990  const dimension_type expr_space_dim = expr.space_dimension();
1991  if (space_dim < expr_space_dim) {
1992  throw_dimension_incompatible("affine_preimage(v, e, d)", "e", expr);
1993  }
1994  // `var' should be one of the dimensions of the grid.
1995  const dimension_type var_space_dim = var.space_dimension();
1996  if (space_dim < var_space_dim) {
1997  throw_dimension_incompatible("affine_preimage(v, e, d)", "v", var);
1998  }
1999 
2000  if (marked_empty()) {
2001  return;
2002  }
2003 
2004  Coefficient_traits::const_reference expr_var = expr.coefficient(var);
2005 
2006  if (var_space_dim <= expr_space_dim && expr_var != 0) {
2007  // The transformation is invertible.
2009  // Congruence_System::affine_preimage() requires the third argument
2010  // to be a positive Coefficient.
2011  if (denominator > 0) {
2012  con_sys.affine_preimage(var, expr, denominator);
2013  }
2014  else {
2015  con_sys.affine_preimage(var, -expr, -denominator);
2016  }
2018  }
2019  if (generators_are_up_to_date()) {
2020  // To build the inverse transformation,
2021  // after copying and negating `expr',
2022  // we exchange the roles of `expr[var_space_dim]' and `denominator'.
2023  Linear_Expression inverse;
2024  if (expr_var > 0) {
2025  inverse = -expr;
2026  inverse.set_coefficient(var, denominator);
2027  gen_sys.affine_image(var, inverse, expr_var);
2028  }
2029  else {
2030  // The new denominator is negative: we negate everything once
2031  // more, as Grid_Generator_System::affine_image() requires the
2032  // third argument to be positive.
2033  inverse = expr;
2034  inverse.set_coefficient(var, -denominator);
2035  gen_sys.affine_image(var, inverse, -expr_var);
2036  }
2038  }
2039  }
2040  else {
2041  // The transformation is not invertible.
2042  // We need an up-to-date system of congruences.
2043  if (!congruences_are_up_to_date()) {
2044  minimize();
2045  }
2046  // Congruence_System::affine_preimage() requires the third argument
2047  // to be a positive Coefficient.
2048  if (denominator > 0) {
2049  con_sys.affine_preimage(var, expr, denominator);
2050  }
2051  else {
2052  con_sys.affine_preimage(var, -expr, -denominator);
2053  }
2054 
2057  }
2058  PPL_ASSERT(OK());
2059 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void clear_congruences_minimized()
Sets status to express that congruences are no longer minimized.
Definition: Grid_inlines.hh:87
void clear_generators_up_to_date()
Sets status to express that generators are out of date.
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
Rounding_Dir inverse(Rounding_Dir dir)
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void affine_preimage(Variable v, const Linear_Expression &expr, Coefficient_traits::const_reference denominator)
Substitutes a given column of coefficients by a given affine expression.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void affine_image(Variable v, const Linear_Expression &expr, Coefficient_traits::const_reference denominator)
Assigns to a given variable an affine expression.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
bool minimize() const
Minimizes both the congruences and the generators.
void Parma_Polyhedra_Library::Grid::ascii_dump ( ) const

Writes to std::cerr an ASCII representation of *this.

void Parma_Polyhedra_Library::Grid::ascii_dump ( std::ostream &  s) const

Writes to s an ASCII representation of *this.

Definition at line 2798 of file Grid_public.cc.

2798  {
2799  using std::endl;
2800 
2801  s << "space_dim "
2802  << space_dim
2803  << endl;
2804  status.ascii_dump(s);
2805  s << "con_sys ("
2806  << (congruences_are_up_to_date() ? "" : "not_")
2807  << "up-to-date)"
2808  << endl;
2809  con_sys.ascii_dump(s);
2810  s << "gen_sys ("
2811  << (generators_are_up_to_date() ? "" : "not_")
2812  << "up-to-date)"
2813  << endl;
2814  gen_sys.ascii_dump(s);
2815  s << "dimension_kinds";
2818  for (Dimension_Kinds::const_iterator i = dim_kinds.begin();
2819  i != dim_kinds.end();
2820  ++i) {
2821  s << " " << *i;
2822  }
2823  }
2824  s << endl;
2825 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool Parma_Polyhedra_Library::Grid::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.

Definition at line 2830 of file Grid_public.cc.

2830  {
2831  std::string str;
2832 
2833  if (!(s >> str) || str != "space_dim") {
2834  return false;
2835  }
2836 
2837  if (!(s >> space_dim)) {
2838  return false;
2839  }
2840 
2841  if (!status.ascii_load(s)) {
2842  return false;
2843  }
2844 
2845  if (!(s >> str) || str != "con_sys") {
2846  return false;
2847  }
2848 
2849  if (!(s >> str)) {
2850  return false;
2851  }
2852  if (str == "(up-to-date)") {
2854  }
2855  else if (str != "(not_up-to-date)") {
2856  return false;
2857  }
2858 
2859  if (!con_sys.ascii_load(s)) {
2860  return false;
2861  }
2862 
2863  if (!(s >> str) || str != "gen_sys") {
2864  return false;
2865  }
2866 
2867  if (!(s >> str)) {
2868  return false;
2869  }
2870  if (str == "(up-to-date)") {
2872  }
2873  else if (str != "(not_up-to-date)") {
2874  return false;
2875  }
2876 
2877  if (!gen_sys.ascii_load(s)) {
2878  return false;
2879  }
2880 
2881  if (!(s >> str) || str != "dimension_kinds") {
2882  return false;
2883  }
2884 
2885  if (!marked_empty()
2888  dim_kinds.resize(space_dim + 1);
2889  for (Dimension_Kinds::size_type dim = 0; dim <= space_dim; ++dim) {
2890  short unsigned int dim_kind;
2891  if (!(s >> dim_kind)) {
2892  return false;
2893  }
2894  switch (dim_kind) {
2895  case 0:
2896  dim_kinds[dim] = PARAMETER;
2897  break;
2898  case 1:
2899  dim_kinds[dim] = LINE;
2900  break;
2901  case 2:
2902  dim_kinds[dim] = GEN_VIRTUAL;
2903  break;
2904  default:
2905  return false;
2906  }
2907  }
2908  }
2909 
2910  // Check invariants.
2911  PPL_ASSERT(OK());
2912  return true;
2913 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
bool ascii_load(std::istream &s)
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this ...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool ascii_load(std::istream &s)
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this ...
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void set_generators_up_to_date()
Sets status to express that generators are up-to-date.
Definition: Grid_inlines.hh:60
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
void set_congruences_up_to_date()
Sets status to express that congruences are up-to-date.
Definition: Grid_inlines.hh:65
bool ascii_load(std::istream &s)
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this ...
Definition: Grid_Status.cc:89
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
void Parma_Polyhedra_Library::Grid::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 $\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} \leq \mathrm{var}' \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}$.

Parameters
varThe variable updated by the affine relation;
lb_exprThe numerator of the lower bounding affine expression;
ub_exprThe numerator of the upper bounding affine expression;
denominatorThe (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1).
Exceptions
std::invalid_argumentThrown 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 2550 of file Grid_public.cc.

References Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

2553  {
2554 
2555  // The denominator cannot be zero.
2556  if (denominator == 0) {
2557  throw_invalid_argument("bounded_affine_image(v, lb, ub, d)", "d == 0");
2558  }
2559  // Dimension-compatibility checks.
2560  // `var' should be one of the dimensions of the grid.
2561  const dimension_type var_space_dim = var.space_dimension();
2562  if (space_dim < var_space_dim) {
2563  throw_dimension_incompatible("bounded_affine_image(v, lb, ub, d)",
2564  "v", var);
2565  }
2566  // The dimension of `lb_expr' and `ub_expr' should not be
2567  // greater than the dimension of `*this'.
2568  const dimension_type lb_space_dim = lb_expr.space_dimension();
2569  if (space_dim < lb_space_dim) {
2570  throw_dimension_incompatible("bounded_affine_image(v, lb, ub, d)",
2571  "lb", lb_expr);
2572  }
2573  const dimension_type ub_space_dim = ub_expr.space_dimension();
2574  if (space_dim < ub_space_dim) {
2575  throw_dimension_incompatible("bounded_affine_image(v, lb, ub, d)",
2576  "ub", ub_expr);
2577  }
2578 
2579  // Any image of an empty grid is empty.
2580  if (marked_empty()) {
2581  return;
2582  }
2583  // In all other cases, generalized_affine_preimage() must
2584  // just add a line in the direction of var.
2586  LESS_OR_EQUAL,
2587  ub_expr,
2588  denominator);
2589 
2590  PPL_ASSERT(OK());
2591 }
void generalized_affine_image(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one(), Coefficient_traits::const_reference modulus=Coefficient_zero())
Assigns to *this the image of *this with respect to the generalized affine relation ...
size_t dimension_type
An unsigned integral type for representing space dimensions.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
void Parma_Polyhedra_Library::Grid::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 $\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} \leq \mathrm{var}' \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}$.

Parameters
varThe variable updated by the affine relation;
lb_exprThe numerator of the lower bounding affine expression;
ub_exprThe numerator of the upper bounding affine expression;
denominatorThe (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1).
Exceptions
std::invalid_argumentThrown 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 2596 of file Grid_public.cc.

References Parma_Polyhedra_Library::LESS_OR_EQUAL, Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

2599  {
2600 
2601  // The denominator cannot be zero.
2602  if (denominator == 0) {
2603  throw_invalid_argument("bounded_affine_preimage(v, lb, ub, d)", "d == 0");
2604  }
2605  // Dimension-compatibility checks.
2606  // `var' should be one of the dimensions of the grid.
2607  const dimension_type var_space_dim = var.space_dimension();
2608  if (space_dim < var_space_dim) {
2609  throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub, d)",
2610  "v", var);
2611  }
2612  // The dimension of `lb_expr' and `ub_expr' should not be
2613  // greater than the dimension of `*this'.
2614  const dimension_type lb_space_dim = lb_expr.space_dimension();
2615  if (space_dim < lb_space_dim) {
2616  throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub, d)",
2617  "lb", lb_expr);
2618  }
2619  const dimension_type ub_space_dim = ub_expr.space_dimension();
2620  if (space_dim < ub_space_dim) {
2621  throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub, d)",
2622  "ub", ub_expr);
2623  }
2624 
2625  // Any preimage of an empty grid is empty.
2626  if (marked_empty()) {
2627  return;
2628  }
2629 
2630  // In all other cases, generalized_affine_preimage() must
2631  // just add a line in the direction of var.
2633  LESS_OR_EQUAL,
2634  ub_expr,
2635  denominator);
2636 
2637  PPL_ASSERT(OK());
2638 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
void generalized_affine_preimage(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one(), Coefficient_traits::const_reference modulus=Coefficient_zero())
Assigns to *this the preimage of *this with respect to the generalized affine relation ...
bool Parma_Polyhedra_Library::Grid::bounds ( const Linear_Expression expr,
const char *  method_call 
) const
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.

Parameters
exprThe linear expression to test;
method_callThe call description of the public parent method, for example "bounded_from_above(e)". Passed to throw_dimension_incompatible, as the first argument.
Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

Definition at line 289 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Linear_Expression::space_dimension().

Referenced by bounds_from_above(), and bounds_from_below().

290  {
291  // The dimension of `expr' must be at most the dimension of *this.
292  if (space_dim < expr.space_dimension()) {
293  throw_dimension_incompatible(method_call, "e", expr);
294  }
295  // A zero-dimensional or empty grid bounds everything.
296  if (space_dim == 0
297  || marked_empty()
299  return true;
300  }
301  if (!generators_are_minimized() && !minimize()) {
302  // Minimizing found `this' empty.
303  return true;
304  }
305 
306  return bounds_no_check(expr);
307 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool bounds_no_check(const Linear_Expression &expr) const
Checks if and how expr is bounded in *this.
bool update_generators() const
Updates and minimizes the generators from the congruences.
bool minimize() const
Minimizes both the congruences and the generators.
bool Parma_Polyhedra_Library::Grid::bounds_from_above ( const Linear_Expression expr) const
inline

Returns true if and only if expr is bounded in *this.

This method is the same as bounds_from_below.

Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

Definition at line 322 of file Grid_inlines.hh.

References bounds().

Referenced by Parma_Polyhedra_Library::Affine_Space::bounds_from_above().

322  {
323  return bounds(expr, "bounds_from_above(e)");
324 }
bool bounds(const Linear_Expression &expr, const char *method_call) const
Checks if and how expr is bounded in *this.
bool Parma_Polyhedra_Library::Grid::bounds_from_below ( const Linear_Expression expr) const
inline

Returns true if and only if expr is bounded in *this.

This method is the same as bounds_from_above.

Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

Definition at line 327 of file Grid_inlines.hh.

References bounds().

Referenced by Parma_Polyhedra_Library::Affine_Space::bounds_from_below().

327  {
328  return bounds(expr, "bounds_from_below(e)");
329 }
bool bounds(const Linear_Expression &expr, const char *method_call) const
Checks if and how expr is bounded in *this.
bool Parma_Polyhedra_Library::Grid::bounds_no_check ( const Linear_Expression expr) const
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.

Parameters
exprThe linear expression to test;

Definition at line 310 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Scalar_Products::homogeneous_sign(), Parma_Polyhedra_Library::Grid_Generator::is_line_or_parameter(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

Referenced by wrap_assign().

310  {
311  // The dimension of `expr' must be at most the dimension of *this.
312  PPL_ASSERT(space_dim > 0 && space_dim >= expr.space_dimension());
313  PPL_ASSERT(generators_are_minimized() && !marked_empty());
314 
315  // The generators are up to date and minimized.
316  for (dimension_type i = gen_sys.num_rows(); i-- > 0; ) {
317  const Grid_Generator& g = gen_sys[i];
318  // Only lines and parameters in `*this' can cause `expr' to be
319  // unbounded.
320  if (g.is_line_or_parameter()) {
321  const int sp_sign = Scalar_Products::homogeneous_sign(expr, g);
322  if (sp_sign != 0) {
323  // `*this' does not bound `expr'.
324  return false;
325  }
326  }
327  }
328  return true;
329 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
static int homogeneous_sign(const Linear_Expression &x, const Linear_Expression &y)
Returns the sign of the homogeneous scalar product of x and y, where the inhomogeneous terms are igno...
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool Parma_Polyhedra_Library::Grid::can_recycle_congruence_systems ( )
inlinestatic

Returns true indicating that this domain has methods that can recycle congruences.

Definition at line 300 of file Grid_inlines.hh.

Referenced by Parma_Polyhedra_Library::Affine_Space::can_recycle_congruence_systems().

300  {
301  return true;
302 }
bool Parma_Polyhedra_Library::Grid::can_recycle_constraint_systems ( )
inlinestatic

Returns true indicating that this domain has methods that can recycle constraints.

Definition at line 295 of file Grid_inlines.hh.

Referenced by Parma_Polyhedra_Library::Affine_Space::can_recycle_constraint_systems().

295  {
296  return true;
297 }
void Parma_Polyhedra_Library::Grid::clear_congruences_minimized ( )
inlineprivate

Sets status to express that congruences are no longer minimized.

Definition at line 87 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Grid::Status::reset_c_minimized(), and status.

Referenced by clear_congruences_up_to_date(), intersection_assign(), and map_space_dimensions().

87  {
89 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void Parma_Polyhedra_Library::Grid::clear_congruences_up_to_date ( )
inlineprivate

Sets status to express that congruences are out of date.

Definition at line 97 of file Grid_inlines.hh.

References clear_congruences_minimized(), Parma_Polyhedra_Library::Grid::Status::reset_c_up_to_date(), and status.

Referenced by time_elapse_assign(), and upper_bound_assign().

97  {
100  // Can get rid of con_sys here.
101 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void clear_congruences_minimized()
Sets status to express that congruences are no longer minimized.
Definition: Grid_inlines.hh:87
void Parma_Polyhedra_Library::Grid::clear_empty ( )
inlineprivate

Clears the status flag indicating that the grid is empty.

Definition at line 82 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Grid::Status::reset_empty(), and status.

82  {
84 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void Parma_Polyhedra_Library::Grid::clear_generators_minimized ( )
inlineprivate

Sets status to express that generators are no longer minimized.

Definition at line 92 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Grid::Status::reset_g_minimized(), and status.

Referenced by clear_generators_up_to_date(), map_space_dimensions(), time_elapse_assign(), and upper_bound_assign().

92  {
94 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void Parma_Polyhedra_Library::Grid::clear_generators_up_to_date ( )
inlineprivate

Sets status to express that generators are out of date.

Definition at line 104 of file Grid_inlines.hh.

References clear_generators_minimized(), Parma_Polyhedra_Library::Grid::Status::reset_g_up_to_date(), and status.

Referenced by intersection_assign(), and OK().

104  {
107  // Can get rid of gen_sys here.
108 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void Parma_Polyhedra_Library::Grid::concatenate_assign ( const Grid y)

Assigns to *this the concatenation of *this and y, taken in this order.

Exceptions
std::length_errorThrown if the concatenation would cause the vector space to exceed dimension max_space_dimension().

Definition at line 225 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::check_space_dimension_overflow(), congruences(), marked_empty(), Parma_Polyhedra_Library::max_space_dimension(), space_dim, and space_dimension().

225  {
226  // The space dimension of the resulting grid must be at most the
227  // maximum allowed space dimension.
228  check_space_dimension_overflow(y.space_dimension(),
230  "PPL::Grid::",
231  "concatenate_assign(y)",
232  "concatenation exceeds the maximum "
233  "allowed space dimension");
234 
235  const dimension_type added_columns = y.space_dim;
236 
237  // If `*this' or `y' are empty grids just adjust the space
238  // dimension.
239  if (marked_empty() || y.marked_empty()) {
240  space_dim += added_columns;
241  set_empty();
242  return;
243  }
244 
245  // If `y' is a universe 0-dim grid, the result is `*this'.
246  if (added_columns == 0) {
247  return;
248  }
249 
250  // If `*this' is a universe 0-dim space grid, the result is `y'.
251  if (space_dim == 0) {
252  *this = y;
253  return;
254  }
255 
258  }
259 
260  con_sys.concatenate(y.congruences());
261 
262  space_dim += added_columns;
263 
266 
267  // Check that the system is OK, taking into account that the system
268  // of congruences may now be empty.
269  PPL_ASSERT(OK());
270 }
void clear_congruences_minimized()
Sets status to express that congruences are no longer minimized.
Definition: Grid_inlines.hh:87
void clear_generators_up_to_date()
Sets status to express that generators are out of date.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void concatenate(const Congruence_System &y)
Concatenates copies of the congruences from y onto *this.
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void update_congruences() const
Updates and minimizes the congruences from the generators.
void Parma_Polyhedra_Library::Grid::congruence_widening_assign ( const Grid y,
unsigned *  tp = NULL 
)

Assigns to *this the result of computing the Grid widening between *this and y using congruence systems.

Parameters
yA grid that must be contained in *this;
tpAn optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique).
Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 77 of file Grid_widenings.cc.

References add_recycled_congruences(), con_sys, congruences_are_minimized(), congruences_are_up_to_date(), contains(), dim_kinds, m_swap(), marked_empty(), Parma_Polyhedra_Library::Congruence_System::num_equalities(), Parma_Polyhedra_Library::Congruence_System::num_rows(), OK(), select_wider_congruences(), set_congruences_minimized(), set_empty(), space_dim, and update_congruences().

Referenced by limited_congruence_extrapolation_assign(), and widening_assign().

77  {
78  Grid& x = *this;
79  // Dimension-compatibility check.
80  if (x.space_dim != y.space_dim) {
81  throw_dimension_incompatible("widening_assign(y)", "y", y);
82  }
83 
84  // Assume `y' is contained in or equal to `x'.
85  PPL_EXPECT_HEAVY(copy_contains(x, y));
86 
87  // Leave `x' the same if `x' or `y' is zero-dimensional or empty.
88  if (x.space_dim == 0 || x.marked_empty() || y.marked_empty()) {
89  return;
90  }
91 
92  // Ensure that the `x' congruences are in minimal form.
93  if (x.congruences_are_up_to_date()) {
94  if (!x.congruences_are_minimized()) {
95  if (simplify(x.con_sys, x.dim_kinds)) {
96  // `x' is empty.
97  x.set_empty();
98  return;
99  }
100  x.set_congruences_minimized();
101  }
102  }
103  else {
104  x.update_congruences();
105  }
106 
107  // Ensure that the `y' congruences are in minimal form.
108  Grid& yy = const_cast<Grid&>(y);
109  if (yy.congruences_are_up_to_date()) {
110  if (!yy.congruences_are_minimized()) {
111  if (simplify(yy.con_sys, yy.dim_kinds)) {
112  // `y' is empty.
113  yy.set_empty();
114  return;
115  }
116  yy.set_congruences_minimized();
117  }
118  }
119  else {
120  yy.update_congruences();
121  }
122 
123  if (con_sys.num_equalities() < yy.con_sys.num_equalities()) {
124  return;
125  }
126  // Copy into `cgs' the congruences of `x' that are common to `y',
127  // according to the grid widening.
128  Congruence_System cgs;
129  x.select_wider_congruences(yy, cgs);
130 
131  if (cgs.num_rows() == con_sys.num_rows()) {
132  // All congruences were selected, thus the result is `x'.
133  return;
134  }
135 
136  // A strict subset of the congruences was selected.
137 
138  Grid result(x.space_dim);
139  result.add_recycled_congruences(cgs);
140 
141  // Check whether we are using the widening-with-tokens technique
142  // and there are still tokens available.
143  if (tp != 0 && *tp > 0) {
144  // There are tokens available. If `result' is not a subset of
145  // `x', then it is less precise and we use one of the available
146  // tokens.
147  if (!x.contains(result)) {
148  --(*tp);
149  }
150  }
151  else {
152  // No tokens.
153  x.m_swap(result);
154  }
155 
156  PPL_ASSERT(x.OK(true));
157 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type num_equalities() const
Returns the number of equalities.
static bool simplify(Congruence_System &cgs, Dimension_Kinds &dim_kinds)
Converts cgs to upper triangular (i.e. minimized) form.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
dimension_type num_rows() const
Returns the number of rows in the system.
const PPL::Congruence_System & Parma_Polyhedra_Library::Grid::congruences ( ) const

Returns the system of congruences.

Definition at line 300 of file Grid_public.cc.

Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PSET >::approximate_partition(), Parma_Polyhedra_Library::Pointset_Powerset< PSET >::approximate_partition_aux(), concatenate_assign(), constraints(), and difference_assign().

300  {
301  if (marked_empty()) {
302  return con_sys;
303  }
304 
305  if (space_dim == 0) {
306  // Zero-dimensional universe.
307  PPL_ASSERT(con_sys.num_rows() == 0 && con_sys.space_dimension() == 0);
308  return con_sys;
309  }
310 
313  }
314 
315  return con_sys;
316 }
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
dimension_type num_rows() const
Returns the number of rows in the system.
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void update_congruences() const
Updates and minimizes the congruences from the generators.
bool Parma_Polyhedra_Library::Grid::congruences_are_minimized ( ) const
inlineprivate

Returns true if the system of congruences is minimized.

Definition at line 50 of file Grid_inlines.hh.

References status, and Parma_Polyhedra_Library::Grid::Status::test_c_minimized().

Referenced by add_space_dimensions(), congruence_widening_assign(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_included_in(), quick_equivalence_test(), select_wider_congruences(), and simplify_using_context_assign().

50  {
51  return status.test_c_minimized();
52 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
bool Parma_Polyhedra_Library::Grid::congruences_are_up_to_date ( ) const
inlineprivate

Returns true if the system of congruences is up-to-date.

Definition at line 40 of file Grid_inlines.hh.

References status, and Parma_Polyhedra_Library::Grid::Status::test_c_up_to_date().

Referenced by congruence_widening_assign(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), intersection_assign(), is_included_in(), map_space_dimensions(), operator=(), simplify_using_context_assign(), and widening_assign().

40  {
41  return status.test_c_up_to_date();
42 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
bool Parma_Polyhedra_Library::Grid::constrains ( Variable  var) const

Returns true if and only if var is constrained in *this.

Exceptions
std::invalid_argumentThrown if var is not a space dimension of *this.

Definition at line 886 of file Grid_public.cc.

References Parma_Polyhedra_Library::Expression_Hide_Last< T >::all_zeroes(), Parma_Polyhedra_Library::Grid_Generator::coefficient(), Parma_Polyhedra_Library::Grid_Generator::expression(), Parma_Polyhedra_Library::Grid_Generator::is_line(), Parma_Polyhedra_Library::Boundary_NS::sgn(), and Parma_Polyhedra_Library::Variable::space_dimension().

886  {
887  // `var' should be one of the dimensions of the grid.
888  const dimension_type var_space_dim = var.space_dimension();
889  if (space_dim < var_space_dim) {
890  throw_dimension_incompatible("constrains(v)", "v", var);
891  }
892 
893  // An empty grid constrains all variables.
894  if (marked_empty()) {
895  return true;
896  }
897 
899  // Since generators are up-to-date, the generator system (since it is
900  // well formed) contains a point. Hence the grid is not empty.
902  // Here a variable is constrained if and only if it is
903  // syntactically constrained.
904  goto syntactic_check;
905  }
906 
907  if (generators_are_minimized()) {
908  // Try a quick, incomplete check for the universe grid:
909  // a universe grid constrains no variable.
910  // Count the number of lines (they are linearly independent).
911  dimension_type num_lines = 0;
912  for (dimension_type i = gen_sys.num_rows(); i-- > 0; ) {
913  if (gen_sys[i].is_line()) {
914  ++num_lines;
915  }
916  }
917 
918  if (num_lines == space_dim) {
919  return false;
920  }
921  }
922 
923  // Scan generators: perhaps we will find line(var).
924  for (dimension_type i = gen_sys.num_rows(); i-- > 0; ) {
925  const Grid_Generator& g_i = gen_sys[i];
926  if (!g_i.is_line()) {
927  continue;
928  }
929  if (sgn(g_i.coefficient(var)) != 0) {
930  if (g_i.expression().all_zeroes(1, var.space_dimension())
931  && g_i.expression().all_zeroes(var.space_dimension() + 1, space_dim + 1)) {
932  // The only nonzero coefficient in g_i is the one of var.
933  return true;
934  }
935  }
936  }
937 
938  // We are still here: at least we know that the grid is not empty.
940  goto syntactic_check;
941  }
942 
943  // We must minimize to detect emptiness and obtain constraints.
944  if (!minimize()) {
945  return true;
946  }
947 
948  syntactic_check:
949  for (dimension_type i = con_sys.num_rows(); i-- > 0; ) {
950  if (con_sys[i].coefficient(var) != 0) {
951  return true;
952  }
953  }
954  return false;
955 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
dimension_type num_rows() const
Returns the number of rows in the system.
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
int sgn(Boundary_Type type, const T &x, const Info &info)
void update_congruences() const
Updates and minimizes the congruences from the generators.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool minimize() const
Minimizes both the congruences and the generators.
Constraint_System Parma_Polyhedra_Library::Grid::constraints ( ) const
inline

Returns a system of equality constraints satisfied by *this with the same affine dimension as *this.

Definition at line 239 of file Grid_inlines.hh.

References congruences().

Referenced by Parma_Polyhedra_Library::C_Polyhedron::C_Polyhedron(), Parma_Polyhedra_Library::Affine_Space::constraints(), and Parma_Polyhedra_Library::NNC_Polyhedron::NNC_Polyhedron().

239  {
240  return Constraint_System(congruences());
241 }
const Congruence_System & congruences() const
Returns the system of congruences.
Definition: Grid_public.cc:300
void Parma_Polyhedra_Library::Grid::construct ( dimension_type  num_dimensions,
Degenerate_Element  kind 
)
private

Builds a grid universe or empty grid.

Parameters
num_dimensionsThe number of dimensions of the vector space enclosing the grid;
kindspecifies whether the universe or the empty grid has to be built.

Definition at line 52 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Coefficient_one(), con_sys, CON_VIRTUAL, dim_kinds, Parma_Polyhedra_Library::EMPTY, gen_sys, Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Congruence_System::OK(), OK(), PROPER_CONGRUENCE, Parma_Polyhedra_Library::Congruence_System::rows, set_congruences_minimized(), Parma_Polyhedra_Library::Grid::Status::set_empty(), set_generators_minimized(), Parma_Polyhedra_Library::Congruence_System::set_space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::set_space_dimension(), set_zero_dim_univ(), space_dim, status, swap(), Parma_Polyhedra_Library::Congruence::zero_dim_false(), and Parma_Polyhedra_Library::Congruence::zero_dim_integrality().

Referenced by Grid().

53  {
54  space_dim = num_dimensions;
55 
56  if (kind == EMPTY) {
57  // Set emptiness directly instead of with set_empty, as gen_sys is
58  // already correctly initialized.
59  status.set_empty();
60 
61  // Extend the zero dim false congruence system to the appropriate
62  // dimension and then store it in `con_sys'.
63  Congruence_System cgs(Congruence::zero_dim_false());
64  cgs.set_space_dimension(space_dim);
65  swap(con_sys, cgs);
66 
67  PPL_ASSERT(OK());
68  return;
69  }
70 
71  if (space_dim == 0) {
73  return;
74  }
75 
76  // Initialize both systems to universe representations.
79  dim_kinds.resize(space_dim + 1);
80 
81  // Building a universe congruence system.
82  // Extend the zero dim integrality congruence system to the
83  // appropriate dimension and then store it in `con_sys'.
84  Congruence_System cgs(Congruence::zero_dim_integrality());
85  cgs.set_space_dimension(num_dimensions);
86  // Recover minimal form after cgs(zdi) normalization.
87  cgs.rows[0].expr.set_inhomogeneous_term(Coefficient_one());
88  PPL_ASSERT(cgs.OK());
89  swap(con_sys, cgs);
90 
91  // Building a universe grid generator system (and dim_kinds).
93  gen_sys.insert(grid_point());
94  dim_kinds[0] = PROPER_CONGRUENCE /* a.k.a. PARAMETER */;
95  for (dimension_type dim = 0; dim < space_dim; ++dim) {
96  gen_sys.insert(grid_line(Variable(dim)));
97  dim_kinds[1+dim] = CON_VIRTUAL /* a.k.a. LINE */;
98  }
99  PPL_ASSERT(OK());
100 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
The empty element, i.e., the empty set.
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void set_space_dimension(dimension_type space_dim)
Resizes the system to the specified space dimension.
void set_generators_minimized()
Sets status to express that generators are minimized.
Definition: Grid_inlines.hh:76
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
static const Congruence & zero_dim_integrality()
Returns a reference to the true (zero-dimension space) congruence , also known as the integrality con...
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void swap(Grid &x, Grid &y)
Swaps x with y.
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
void set_congruences_minimized()
Sets status to express that congruences are minimized.
Definition: Grid_inlines.hh:70
void Parma_Polyhedra_Library::Grid::construct ( Congruence_System cgs)
private

Builds a grid from a system of congruences.

The grid inherits the space dimension of the congruence system.

Parameters
cgsThe system of congruences defining the grid. Its data-structures may be recycled to build the grid.

Definition at line 103 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::max_space_dimension(), Parma_Polyhedra_Library::Congruence_System::num_rows(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().

103  {
104  // Protecting against space dimension overflow is up to the caller.
105  PPL_ASSERT(cgs.space_dimension() <= max_space_dimension());
106  // Preparing con_sys and gen_sys is up to the caller.
107  PPL_ASSERT(cgs.space_dimension() == con_sys.space_dimension());
108  PPL_ASSERT(cgs.space_dimension() == gen_sys.space_dimension());
109  PPL_ASSERT(con_sys.has_no_rows());
110  PPL_ASSERT(gen_sys.has_no_rows());
111 
112  // Set the space dimension.
113  space_dim = cgs.space_dimension();
114 
115  if (space_dim > 0) {
116  // Stealing the rows from `cgs'.
117  con_sys.m_swap(cgs);
120  }
121  else {
122  // Here `space_dim == 0'.
123  // See if an inconsistent congruence has been passed.
124  for (dimension_type i = cgs.num_rows(); i-- > 0; ) {
125  if (cgs[i].is_inconsistent()) {
126  // Inconsistent congruence found: the grid is empty.
127  status.set_empty();
128  // Insert the zero dim false congruence system into `con_sys'.
129  // `gen_sys' is already in empty form.
131  PPL_ASSERT(OK());
132  return;
133  }
134  }
136  }
137  PPL_ASSERT(OK());
138 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
size_t dimension_type
An unsigned integral type for representing space dimensions.
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void normalize_moduli()
Adjusts all expressions to have the same moduli.
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
bool has_no_rows() const
Returns true if num_rows()==0.
void set_congruences_up_to_date()
Sets status to express that congruences are up-to-date.
Definition: Grid_inlines.hh:65
void m_swap(Congruence_System &y)
Swaps *this with y.
void Parma_Polyhedra_Library::Grid::construct ( Grid_Generator_System ggs)
private

Builds a grid from a system of grid generators.

The grid inherits the space dimension of the generator system.

Parameters
ggsThe system of grid generators defining the grid. Its data-structures may be recycled to build the grid.

Definition at line 141 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Grid_Generator_System::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::has_points(), Parma_Polyhedra_Library::max_space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().

141  {
142  // Protecting against space dimension overflow is up to the caller.
143  PPL_ASSERT(ggs.space_dimension() <= max_space_dimension());
144  // Preparing con_sys and gen_sys is up to the caller.
145  PPL_ASSERT(ggs.space_dimension() == con_sys.space_dimension());
146  PPL_ASSERT(ggs.space_dimension() == gen_sys.space_dimension());
147  PPL_ASSERT(con_sys.has_no_rows());
148  PPL_ASSERT(gen_sys.has_no_rows());
149 
150  // Set the space dimension.
151  space_dim = ggs.space_dimension();
152 
153  // An empty set of generators defines the empty grid.
154  if (ggs.has_no_rows()) {
155  status.set_empty();
156  // Insert the zero dim false congruence system into `con_sys'.
157  // `gen_sys' is already in empty form.
159  return;
160  }
161 
162  // Non-empty valid generator systems have a supporting point, at least.
163  if (!ggs.has_points()) {
164  throw_invalid_generators("Grid(ggs)", "ggs");
165  }
166 
167  if (space_dim == 0) {
169  }
170  else {
171  // Steal the rows from `ggs'.
172  gen_sys.m_swap(ggs);
174  // Generators are now up-to-date.
176  }
177 
178  PPL_ASSERT(OK());
179 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void m_swap(Grid_Generator_System &y)
Swaps *this with y.
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_generators_up_to_date()
Sets status to express that generators are up-to-date.
Definition: Grid_inlines.hh:60
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
static void throw_invalid_generators(const char *method, const char *gs_name)
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
bool has_no_rows() const
Returns true if num_rows()==0.
bool Parma_Polyhedra_Library::Grid::contains ( const Grid y) const

Returns true if and only if *this contains y.

Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 2763 of file Grid_public.cc.

References is_empty(), is_included_in(), marked_empty(), quick_equivalence_test(), space_dim, and TVB_TRUE.

Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PSET >::check_containment(), congruence_widening_assign(), difference_assign(), generator_widening_assign(), and strictly_contains().

2763  {
2764  const Grid& x = *this;
2765 
2766  // Dimension-compatibility check.
2767  if (x.space_dim != y.space_dim) {
2768  throw_dimension_incompatible("contains(y)", "y", y);
2769  }
2770 
2771  if (y.marked_empty()) {
2772  return true;
2773  }
2774  if (x.marked_empty()) {
2775  return y.is_empty();
2776  }
2777  if (y.space_dim == 0) {
2778  return true;
2779  }
2780  if (x.quick_equivalence_test(y) == Grid::TVB_TRUE) {
2781  return true;
2782  }
2783  return y.is_included_in(x);
2784 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool Parma_Polyhedra_Library::Grid::contains_integer_point ( ) const

Returns true if and only if *this contains at least one integer point.

Definition at line 861 of file Grid_public.cc.

References add_recycled_congruences(), Parma_Polyhedra_Library::Congruence_System::insert(), and is_empty().

861  {
862  // Empty grids have no points.
863  if (marked_empty()) {
864  return false;
865  }
866 
867  // A zero-dimensional, universe grid has, by convention, an
868  // integer point.
869  if (space_dim == 0) {
870  return true;
871  }
872 
873  // A grid has an integer point if its intersection with the integer
874  // grid is non-empty.
875  Congruence_System cgs;
876  for (dimension_type var_index = space_dim; var_index-- > 0; ) {
877  cgs.insert(Variable(var_index) %= 0);
878  }
879 
880  Grid gr = *this;
881  gr.add_recycled_congruences(cgs);
882  return !gr.is_empty();
883 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void Parma_Polyhedra_Library::Grid::conversion ( Congruence_System source,
Grid_Generator_System dest,
Dimension_Kinds dim_kinds 
)
staticprivate

Converts generator system dest to be equivalent to congruence system source.

Definition at line 337 of file Grid_conversion.cc.

References Parma_Polyhedra_Library::Grid_Generator_System::clear(), Parma_Polyhedra_Library::Coefficient_one(), Parma_Polyhedra_Library::Coefficient_zero(), CON_VIRTUAL, dim_kinds, EQUALITY, Parma_Polyhedra_Library::Linear_Expression::exact_div_assign(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Grid_Generator::expr, Parma_Polyhedra_Library::Grid_Generator_System::first_pending_row(), Parma_Polyhedra_Library::gcd_assign(), GEN_VIRTUAL, Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Grid_Generator_System::insert_verbatim(), Parma_Polyhedra_Library::lcm_assign(), LINE, lower_triangular(), multiply_grid(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), PARAMETER, PPL_DIRTY_TEMP_COEFFICIENT, PROPER_CONGRUENCE, Parma_Polyhedra_Library::Grid_Generator_System::representation(), Parma_Polyhedra_Library::Linear_Expression::set(), Parma_Polyhedra_Library::Grid_Generator_System::set_space_dimension(), Parma_Polyhedra_Library::Grid_Generator::set_topology(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), Parma_Polyhedra_Library::sub_mul_assign(), Parma_Polyhedra_Library::Grid_Generator_System::sys, Parma_Polyhedra_Library::Grid_Generator_System::topology(), and upper_triangular().

338  {
339  // Quite similar to the generator to congruence version above.
340  // Changes here may be needed there too.
341 
342  PPL_ASSERT(lower_triangular(source, dim_kinds));
343 
344  // Initialize matrix row number counters and compute the LCM of the
345  // diagonal entries of the proper congruences in `source'.
346  dimension_type source_num_rows = 0;
347  dimension_type dest_num_rows = 0;
348  PPL_DIRTY_TEMP_COEFFICIENT(diagonal_lcm);
349  diagonal_lcm = 1;
350  const dimension_type dims = source.space_dimension() + 1;
351  for (dimension_type dim = dims; dim-- > 0; ) {
352  if (dim_kinds[dim] == CON_VIRTUAL) {
353  // Virtual congruences map to lines.
354  ++dest_num_rows;
355  }
356  else {
357  if (dim_kinds[dim] == PROPER_CONGRUENCE) {
358  // Dimension `dim' has a proper congruence row at
359  // `source_num_rows' in `source', so include in `diagonal_lcm'
360  // the `dim'th element of that row.
361  lcm_assign(diagonal_lcm, diagonal_lcm, source[source_num_rows].expr.get(dim));
362  // Proper congruences map to parameters.
363  ++dest_num_rows;
364  }
365  // Equalities map to virtual generators.
366  ++source_num_rows;
367  }
368 
369  }
370  // `source' must be regular.
371  PPL_ASSERT(diagonal_lcm != 0);
372 
373  dest.clear();
374  PPL_ASSERT(dims > 0);
375  dest.set_space_dimension(dims - 1);
376 
377  // In `dest' initialize row types and elements, including setting
378  // the diagonal elements to the inverse ratio of the `source'
379  // diagonal elements.
380  //
381  // The top-down order of the congruence system rows corresponds to
382  // the right-left order of the dimensions.
383  dimension_type source_index = source_num_rows;
384  // The generator system has a bottom-up ordering.
385  for (dimension_type dim = 0; dim < dims; ++dim) {
386  if (dim_kinds[dim] == EQUALITY) {
387  --source_index;
388  }
389  else {
390  Grid_Generator g(dest.representation());
391  g.set_topology(dest.topology());
392  g.expr.set_space_dimension(dims);
393 
394  if (dim_kinds[dim] == CON_VIRTUAL) {
395  g.set_is_line();
396  g.expr.set(0, Coefficient_zero());
397  g.expr.set(dim, Coefficient_one());
398  }
399  else {
400  PPL_ASSERT(dim_kinds[dim] == PROPER_CONGRUENCE);
401  g.set_is_parameter_or_point();
402  --source_index;
404  exact_div_assign(tmp, diagonal_lcm,
405  source[source_index].expr.get(dim));
406  g.expr.set(0, Coefficient_zero());
407  g.expr.set(dim, tmp);
408  }
409  // Don't assert g.OK() here, because it may fail.
410  // All the rows in `dest' are checked at the end of this function.
411  dest.insert_verbatim(g);
412  }
413  }
414 
415  PPL_ASSERT(dest.num_rows() == dest_num_rows);
416  PPL_ASSERT(dest.first_pending_row() == dest_num_rows);
417  PPL_ASSERT(upper_triangular(dest, dim_kinds));
418 
419  // Convert.
420  //
421  // `source_index' and `dest_index' hold the positions of pivot rows
422  // in `source' and `dest'. The order of the rows in `dest' is the
423  // reverse of the order in `source', so the rows are iterated from
424  // last to first (index 0) in `source' and from first to last in
425  // `dest'.
426  source_index = source_num_rows;
427  dimension_type dest_index = 0;
428  PPL_DIRTY_TEMP_COEFFICIENT(reduced_source_dim);
429 
430  for (dimension_type dim = 0; dim < dims; ++dim) {
431  if (dim_kinds[dim] != CON_VIRTUAL) {
432  --source_index;
433  Coefficient_traits::const_reference source_dim
434  = source[source_index].expr.get(dim);
435 
436  // In the rows in `dest' above `dest_index' divide each element
437  // at column `dim' by `source_dim'.
438 
439  for (dimension_type i = dest_index; i-- > 0; ) {
440  Grid_Generator& g = dest.sys.rows[i];
441 
442  // Multiply the representation of `dest' such that entry `dim'
443  // of `g' is a multiple of `source_dim'. This ensures that
444  // the result of the division that follows is a whole number.
445  gcd_assign(reduced_source_dim, g.expr.get(dim), source_dim);
446  exact_div_assign(reduced_source_dim, source_dim, reduced_source_dim);
447  multiply_grid(reduced_source_dim, g, dest.sys.rows, dest_num_rows);
448 
449  g.expr.exact_div_assign(source_dim, dim, dim + 1);
450  // Don't assert g.OK() here, because it may fail.
451  // All the rows in `dest' are checked at the end of this function.
452  }
453  }
454 
455  // Invert and transpose the source row at `source_index' into the
456  // destination row at `dest_index'.
457  //
458  // Consider each dimension `dim_fol' that follows `dim', as the
459  // rows in `dest' that follow row `dest_index' are zero at index
460  // `dim'.
461  dimension_type tmp_source_index = source_index;
462  if (dim_kinds[dim] != EQUALITY) {
463  ++dest_index;
464  }
465  for (dimension_type dim_fol = dim + 1; dim_fol < dims; ++dim_fol) {
466  if (dim_kinds[dim_fol] != CON_VIRTUAL) {
467  --tmp_source_index;
468  Coefficient_traits::const_reference source_dim
469  = source[tmp_source_index].expr.get(dim);
470  // In order to compute the transpose of the inverse of
471  // `source', subtract source[tmp_source_index][dim] times the
472  // column vector in `dest' at `dim' from the column vector in
473  // `dest' at `dim_fol'.
474  //
475  // I.e., for each row `dest_index' in `dest' that is above the
476  // row `dest_index', subtract dest[tmp_source_index][dim]
477  // times the entry `dim' from the entry at `dim_fol'.
478 
480  for (dimension_type i = dest_index; i-- > 0; ) {
481  PPL_ASSERT(i < dest_num_rows);
482  Grid_Generator& row = dest.sys.rows[i];
483  tmp = row.expr.get(dim_fol);
484  sub_mul_assign(tmp, source_dim,
485  row.expr.get(dim));
486  row.expr.set(dim_fol, tmp);
487  // Don't assert row.OK() here, because it may fail.
488  // All the rows in `dest' are checked at the end of this function.
489  }
490  }
491  }
492  }
493 
494  PPL_ASSERT(upper_triangular(dest, dim_kinds));
495 
496  // Since we are reducing the system to "strong minimal form",
497  // reduce the coordinates in the grid_generator system
498  // using "diagonal" values.
499  for (dimension_type dim = 0, i = 0; dim < dims; ++dim) {
500  if (dim_kinds[dim] != GEN_VIRTUAL) {
501  // Factor the "diagonal" generator out of the preceding rows.
502  reduce_reduced<Grid_Generator_System>
503  (dest.sys.rows, dim, i++, dim, dims - 1, dim_kinds);
504  }
505  }
506 
507  // Ensure that the parameter divisors are the same as the divisor of
508  // the point.
509  const Coefficient& system_divisor
510  = dest.sys.rows[0].expr.inhomogeneous_term();
511 
512  for (dimension_type i = dest.sys.rows.size() - 1, dim = dims; dim-- > 1; ) {
513  switch (dim_kinds[dim]) {
514  case PARAMETER:
515  dest.sys.rows[i].set_divisor(system_divisor);
516  // Intentionally fall through.
517  case LINE:
518  --i;
519  break;
520  case GEN_VIRTUAL:
521  break;
522  }
523  }
524 
525 #ifndef NDEBUG
526  // The previous code can modify the rows' fields, exploiting the friendness.
527  // Check that all rows are OK now.
528  for (dimension_type i = dest.sys.rows.size(); i-- > 0; ) {
529  PPL_ASSERT(dest.sys.rows[i].OK());
530  }
531 #endif
532 
533  PPL_ASSERT(dest.sys.OK());
534 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void lcm_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
static bool upper_triangular(const Grid_Generator_System &sys, const Dimension_Kinds &dim_kinds)
If sys is upper triangular return true, else return false.
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void sub_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static bool lower_triangular(const Congruence_System &sys, const Dimension_Kinds &dim_kinds)
If sys is lower triangular return true, else return false.
static void multiply_grid(const Coefficient &multiplier, Congruence &cg, Swapping_Vector< Congruence > &dest, dimension_type num_rows)
Multiply the elements of dest by multiplier.
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
void Parma_Polyhedra_Library::Grid::conversion ( Grid_Generator_System source,
Congruence_System dest,
Dimension_Kinds dim_kinds 
)
staticprivate

Converts congruence system dest to be equivalent to generator system source.

Definition at line 160 of file Grid_conversion.cc.

References Parma_Polyhedra_Library::Congruence_System::clear(), Parma_Polyhedra_Library::Coefficient_one(), Parma_Polyhedra_Library::Coefficient_zero(), CON_VIRTUAL, dim_kinds, Parma_Polyhedra_Library::Linear_Expression::exact_div_assign(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Congruence::expr, Parma_Polyhedra_Library::Congruence::expression(), Parma_Polyhedra_Library::gcd_assign(), GEN_VIRTUAL, Parma_Polyhedra_Library::Expression_Adapter< T >::get(), Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Congruence_System::insert_verbatim(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::lcm_assign(), Parma_Polyhedra_Library::Boundary_NS::le(), LINE, lower_triangular(), multiply_grid(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), Parma_Polyhedra_Library::Congruence_System::num_rows(), Parma_Polyhedra_Library::Congruence_System::OK(), OK(), PARAMETER, PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Congruence_System::rows, Parma_Polyhedra_Library::Linear_Expression::set(), Parma_Polyhedra_Library::Congruence::set_modulus(), Parma_Polyhedra_Library::Congruence_System::set_space_dimension(), Parma_Polyhedra_Library::Linear_Expression::set_space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), Parma_Polyhedra_Library::sub_mul_assign(), and upper_triangular().

161  {
162  // Quite similar to the congruence to generator version below.
163  // Changes here may be needed there too.
164 
165  PPL_ASSERT(upper_triangular(source, dim_kinds));
166 
167  // Initialize matrix row number counters and compute the LCM of the
168  // diagonal entries of the parameters in `source'.
169  //
170  // The top-down order of the generator system rows corresponds to
171  // the left-right order of the dimensions, while the congruence
172  // system rows have a bottom-up ordering.
173  dimension_type dest_num_rows = 0;
174  PPL_DIRTY_TEMP_COEFFICIENT(diagonal_lcm);
175  diagonal_lcm = 1;
176  const dimension_type dims = source.space_dimension() + 1;
177  dimension_type source_index = source.num_rows();
178  for (dimension_type dim = dims; dim-- > 0; ) {
179  if (dim_kinds[dim] == GEN_VIRTUAL) {
180  // Virtual generators map to equalities.
181  ++dest_num_rows;
182  }
183  else {
184  --source_index;
185  if (dim_kinds[dim] == PARAMETER) {
186  // Dimension `dim' has a parameter row at `source_index' in
187  // `source', so include in `diagonal_lcm' the `dim'th element
188  // of that row.
189  lcm_assign(diagonal_lcm, diagonal_lcm, source[source_index].expr.get(dim));
190  // Parameters map to proper congruences.
191  ++dest_num_rows;
192  }
193  // Lines map to virtual congruences.
194  }
195  }
196  PPL_ASSERT(source_index == 0);
197 
198  // `source' must be regular.
199  PPL_ASSERT(diagonal_lcm != 0);
200 
201  dest.clear();
202  dest.set_space_dimension(dims - 1);
203 
204  // In `dest' initialize row types and elements, including setting
205  // the diagonal elements to the inverse ratio of the `source'
206  // diagonal elements.
207  source_index = source.num_rows();
208  for (dimension_type dim = dims; dim-- > 0; ) {
209  if (dim_kinds[dim] == LINE) {
210  --source_index;
211  }
212  else {
213  Linear_Expression le;
214  le.set_space_dimension(dest.space_dimension());
215 
216  if (dim_kinds[dim] == GEN_VIRTUAL) {
217  le.set(dim, Coefficient_one());
218  Congruence cg(le, Coefficient_zero(), Recycle_Input());
219  dest.insert_verbatim(cg, Recycle_Input());
220  }
221  else {
222  PPL_ASSERT(dim_kinds[dim] == PARAMETER);
223  --source_index;
225  exact_div_assign(tmp, diagonal_lcm,
226  source[source_index].expr.get(dim));
227  le.set(dim, tmp);
228  Congruence cg(le, Coefficient_one(), Recycle_Input());
229  dest.insert_verbatim(cg, Recycle_Input());
230  }
231  }
232  }
233 
234  PPL_ASSERT(source_index == 0);
235  PPL_ASSERT(lower_triangular(dest, dim_kinds));
236 
237  // Convert.
238  //
239  // `source_index' and `dest_index' hold the positions of pivot rows
240  // in `source' and `dest'. The order of the rows in `dest' is the
241  // reverse of the order in `source', so the rows are iterated from
242  // last to first (index 0) in `source' and from first to last in
243  // `dest'.
244  source_index = source.num_rows();
245  dimension_type dest_index = 0;
246  PPL_DIRTY_TEMP_COEFFICIENT(multiplier);
247 
248  for (dimension_type dim = dims; dim-- > 0; ) {
249  if (dim_kinds[dim] != GEN_VIRTUAL) {
250  --source_index;
251  const Coefficient& source_dim = source[source_index].expr.get(dim);
252 
253  // In the rows in `dest' above `dest_index' divide each element
254  // at column `dim' by `source_dim'.
255  for (dimension_type row = dest_index; row-- > 0; ) {
256  Congruence& cg = dest.rows[row];
257 
258  // Multiply the representation of `dest' such that entry `dim'
259  // of `g' is a multiple of `source_dim'. This ensures that
260  // the result of the division that follows is a whole number.
261  gcd_assign(multiplier, cg.expression().get(dim), source_dim);
262  exact_div_assign(multiplier, source_dim, multiplier);
263  multiply_grid(multiplier, cg, dest.rows, dest_num_rows);
264 
265  cg.expr.exact_div_assign(source_dim, dim, dim + 1);
266  }
267  }
268 
269  // Invert and transpose the source row at `source_index' into the
270  // destination row at `dest_index'.
271  //
272  // Consider each dimension `dim_prec' that precedes `dim', as the
273  // rows in `dest' that follow `dim_index' have zeroes at index
274  // `dim'.
275  dimension_type tmp_source_index = source_index;
276  if (dim_kinds[dim] != LINE) {
277  ++dest_index;
278  }
279  for (dimension_type dim_prec = dim; dim_prec-- > 0; ) {
280  if (dim_kinds[dim_prec] != GEN_VIRTUAL) {
281  --tmp_source_index;
282  const Coefficient& source_dim = source[tmp_source_index].expr.get(dim);
283 
284  // In order to compute the transpose of the inverse of
285  // `source', subtract source[tmp_source_index][dim] times the
286  // column vector in `dest' at `dim' from the column vector in
287  // `dest' at `dim_prec'.
288  //
289  // I.e., for each row `dest_index' in `dest' that is above the
290  // row `dest_index', subtract dest[tmp_source_index][dim]
291  // times the entry `dim' from the entry at `dim_prec'.
293  for (dimension_type row = dest_index; row-- > 0; ) {
294  PPL_ASSERT(row < dest_num_rows);
295  Congruence& cg = dest.rows[row];
296  tmp = cg.expr.get(dim_prec);
297  sub_mul_assign(tmp, source_dim, cg.expression().get(dim));
298  cg.expr.set(dim_prec, tmp);
299  }
300  }
301  }
302  }
303  // Set the modulus in every congruence.
304  Coefficient_traits::const_reference modulus
305  = dest.rows[dest_num_rows - 1].inhomogeneous_term();
306  for (dimension_type row = dest_num_rows; row-- > 0; ) {
307  Congruence& cg = dest.rows[row];
308  if (cg.is_proper_congruence()) {
309  cg.set_modulus(modulus);
310  }
311  }
312 
313  PPL_ASSERT(lower_triangular(dest, dim_kinds));
314 
315  // Since we are reducing the system to "strong minimal form",
316  // reduce the coefficients in the congruence system
317  // using "diagonal" values.
318  for (dimension_type dim = dims, i = 0; dim-- > 0; ) {
319  if (dim_kinds[dim] != CON_VIRTUAL) {
320  // Factor the "diagonal" congruence out of the preceding rows.
321  reduce_reduced<Congruence_System>
322  (dest.rows, dim, i++, 0, dim, dim_kinds, false);
323  }
324  }
325 
326 #ifndef NDEBUG
327  // Make sure that all the rows are now OK.
328  for (dimension_type i = dest.num_rows(); i-- > 0; ) {
329  PPL_ASSERT(dest[i].OK());
330  }
331 #endif
332 
333  PPL_ASSERT(dest.OK());
334 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void lcm_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
static bool upper_triangular(const Grid_Generator_System &sys, const Dimension_Kinds &dim_kinds)
If sys is upper triangular return true, else return false.
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void sub_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static bool lower_triangular(const Congruence_System &sys, const Dimension_Kinds &dim_kinds)
If sys is lower triangular return true, else return false.
static void multiply_grid(const Coefficient &multiplier, Congruence &cg, Swapping_Vector< Congruence > &dest, dimension_type num_rows)
Multiply the elements of dest by multiplier.
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
void Parma_Polyhedra_Library::Grid::difference_assign ( const Grid y)

Assigns to *this the grid-difference of *this and y.

The grid difference between grids x and y is the smallest grid containing all the points from x and y that are only in x.

Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 1604 of file Grid_public.cc.

References add_congruence_no_check(), Parma_Polyhedra_Library::Congruence_System::begin(), congruences(), contains(), Parma_Polyhedra_Library::EMPTY, Parma_Polyhedra_Library::Congruence_System::end(), Parma_Polyhedra_Library::Congruence::expression(), Parma_Polyhedra_Library::Poly_Con_Relation::implies(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), marked_empty(), Parma_Polyhedra_Library::Congruence::modulus(), relation_with(), set_empty(), space_dim, and upper_bound_assign().

Referenced by upper_bound_assign_if_exact().

1604  {
1605  Grid& x = *this;
1606  // Dimension-compatibility check.
1607  if (x.space_dim != y.space_dim) {
1608  throw_dimension_incompatible("difference_assign(y)", "y", y);
1609  }
1610 
1611  if (y.marked_empty() || x.marked_empty()) {
1612  return;
1613  }
1614 
1615  // If both grids are zero-dimensional, then they are necessarily
1616  // universe grids, so the result is empty.
1617  if (x.space_dim == 0) {
1618  x.set_empty();
1619  return;
1620  }
1621 
1622  if (y.contains(x)) {
1623  x.set_empty();
1624  return;
1625  }
1626 
1627  Grid new_grid(x.space_dim, EMPTY);
1628 
1629  const Congruence_System& y_cgs = y.congruences();
1630  for (Congruence_System::const_iterator i = y_cgs.begin(),
1631  y_cgs_end = y_cgs.end(); i != y_cgs_end; ++i) {
1632  const Congruence& cg = *i;
1633 
1634  // The 2-complement cg2 of cg = ((e %= 0) / m) is the congruence
1635  // defining the sets of points exactly half-way between successive
1636  // hyperplanes e = km and e = (k+1)m, for any integer k; that is,
1637  // the hyperplanes defined by 2e = (2k + 1)m, for any integer k.
1638  // Thus `cg2' is the congruence ((2e %= m) / 2m).
1639 
1640  // As the grid difference must be a grid, only add the
1641  // 2-complement congruence to x if the resulting grid includes all
1642  // the points in x that did not satisfy `cg'.
1643 
1644  // The 2-complement of cg can be included in the result only if x
1645  // holds points other than those in cg.
1646  if (x.relation_with(cg).implies(Poly_Con_Relation::is_included())) {
1647  continue;
1648  }
1649 
1650  if (cg.is_proper_congruence()) {
1651  const Linear_Expression e(cg.expression());
1652  // Congruence cg is ((e %= 0) / m).
1653  const Coefficient& m = cg.modulus();
1654  // If x is included in the grid defined by the congruences cg
1655  // and its 2-complement (i.e. the grid defined by the congruence
1656  // (2e %= 0) / m) then add the 2-complement to the potential
1657  // result.
1658  if (x.relation_with((2*e %= 0) / m)
1659  .implies(Poly_Con_Relation::is_included())) {
1660  Grid z = x;
1661  z.add_congruence_no_check((2*e %= m) / (2*m));
1662  new_grid.upper_bound_assign(z);
1663  continue;
1664  }
1665  }
1666  return;
1667  }
1668 
1669  *this = new_grid;
1670 
1671  PPL_ASSERT(OK());
1672 }
The empty element, i.e., the empty set.
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
void Parma_Polyhedra_Library::Grid::drop_some_non_integer_points ( Complexity_Class  complexity = ANY_COMPLEXITY)

Possibly tightens *this by dropping all points with non-integer coordinates.

Parameters
complexityThis argument is ignored as the algorithm used has polynomial complexity.

Definition at line 3112 of file Grid_public.cc.

3112  {
3113  if (marked_empty() || space_dim == 0) {
3114  return;
3115  }
3116 
3117  // By adding integral congruences for each dimension to the
3118  // congruence system, defining \p *this, the grid will keep only
3119  // those points that have integral coordinates. All points in \p
3120  // *this with non-integral coordinates are removed.
3121  for (dimension_type i = space_dim; i-- > 0; ) {
3122  add_congruence(Variable(i) %= 0);
3123  }
3124 
3125  PPL_ASSERT(OK());
3126 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void add_congruence(const Congruence &cg)
Adds a copy of congruence cg to *this.
void Parma_Polyhedra_Library::Grid::drop_some_non_integer_points ( const Variables_Set vars,
Complexity_Class  complexity = ANY_COMPLEXITY 
)

Possibly tightens *this by dropping all points with non-integer coordinates for the space dimensions corresponding to vars.

Parameters
varsPoints with non-integer coordinates for these variables/space-dimensions can be discarded.
complexityThis argument is ignored as the algorithm used has polynomial complexity.

Definition at line 3129 of file Grid_public.cc.

References Parma_Polyhedra_Library::Variables_Set::space_dimension().

3130  {
3131  // Dimension-compatibility check.
3132  const dimension_type min_space_dim = vars.space_dimension();
3133  if (space_dimension() < min_space_dim) {
3134  throw_dimension_incompatible("drop_some_non_integer_points(vs, cmpl)",
3135  min_space_dim);
3136  }
3137 
3138  if (marked_empty() || min_space_dim == 0) {
3139  return;
3140  }
3141 
3142  // By adding the integral congruences for each dimension in vars to
3143  // the congruence system defining \p *this, the grid will keep only
3144  // those points that have integer coordinates for all the dimensions
3145  // in vars. All points in \p *this with non-integral coordinates for
3146  // the dimensions in vars are removed.
3147  for (Variables_Set::const_iterator i = vars.begin(),
3148  vars_end = vars.end(); i != vars_end; ++i) {
3149  add_congruence(Variable(*i) %= 0);
3150  }
3151 
3152  PPL_ASSERT(OK());
3153 }
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void add_congruence(const Congruence &cg)
Adds a copy of congruence cg to *this.
void Parma_Polyhedra_Library::Grid::expand_space_dimension ( Variable  var,
dimension_type  m 
)

Creates m copies of the space dimension corresponding to var.

Parameters
varThe variable corresponding to the space dimension to be replicated;
mThe number of replicas to be created.
Exceptions
std::invalid_argumentThrown if var does not correspond to a dimension of the vector space.
std::length_errorThrown if adding m new space dimensions would cause the vector space to exceed dimension max_space_dimension().

If *this has space dimension $n$, with $n > 0$, and var has space dimension $k \leq n$, then the $k$-th space dimension is expanded to m new space dimensions $n$, $n+1$, $\dots$, $n+m-1$.

Definition at line 406 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::Congruence_System::begin(), Parma_Polyhedra_Library::check_space_dimension_overflow(), Parma_Polyhedra_Library::Congruence::coefficient(), Parma_Polyhedra_Library::Coefficient_zero(), Parma_Polyhedra_Library::Congruence_System::end(), Parma_Polyhedra_Library::Congruence::expr, Parma_Polyhedra_Library::Congruence_System::insert_verbatim(), Parma_Polyhedra_Library::max_space_dimension(), Parma_Polyhedra_Library::Linear_Expression::set_coefficient(), and Parma_Polyhedra_Library::Variable::space_dimension().

406  {
407  // `var' must be one of the dimensions of the vector space.
408  if (var.space_dimension() > space_dim) {
409  throw_dimension_incompatible("expand_space_dimension(v, m)", "v", var);
410  }
411 
412  // Adding 0 dimensions leaves the same grid.
413  if (m == 0) {
414  return;
415  }
416 
417  // The resulting space dimension must be at most the maximum.
419  "PPL::Grid::",
420  "expand_space_dimension(v, m)",
421  "adding m new space dimensions exceeds "
422  "the maximum allowed space dimension");
423 
424  // Save the number of dimensions before adding new ones.
425  const dimension_type old_dim = space_dim;
426 
427  // Add the required new dimensions.
429 
430  const Congruence_System& cgs = congruences();
431  Congruence_System new_congruences;
432  for (Congruence_System::const_iterator i = cgs.begin(),
433  cgs_end = cgs.end(); i != cgs_end; ++i) {
434  const Congruence& cg = *i;
435 
436  Coefficient_traits::const_reference coeff = cg.coefficient(var);
437 
438  // Only consider congruences that constrain `var'.
439  if (coeff == 0) {
440  continue;
441  }
442 
443  Congruence cg_copy = cg;
444  cg_copy.expr.set_coefficient(var, Coefficient_zero());
445 
446  // Each relevant congruence results in `m' new congruences.
447  for (dimension_type dst_d = old_dim; dst_d < old_dim+m; ++dst_d) {
448  Congruence x = cg_copy;
449  add_mul_assign(x.expr, coeff, Variable(dst_d));
450  new_congruences.insert_verbatim(x, Recycle_Input());
451  }
452  }
453  add_recycled_congruences(new_congruences);
454  PPL_ASSERT(OK());
455 }
void add_space_dimensions_and_embed(dimension_type m)
Adds m new space dimensions and embeds the old grid in the new vector space.
Definition: Grid_chdims.cc:77
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
size_t dimension_type
An unsigned integral type for representing space dimensions.
const Congruence_System & congruences() const
Returns the system of congruences.
Definition: Grid_public.cc:300
void add_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Definition: globals.cc:48
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Grid can handle.
void add_recycled_congruences(Congruence_System &cgs)
Adds the congruences in cgs to *this.
PPL::memory_size_type Parma_Polyhedra_Library::Grid::external_memory_in_bytes ( ) const

Returns the size in bytes of the memory managed by *this.

Definition at line 2916 of file Grid_public.cc.

Referenced by total_memory_in_bytes().

2916  {
2917  return
2920 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
void Parma_Polyhedra_Library::Grid::fold_space_dimensions ( const Variables_Set vars,
Variable  dest 
)

Folds the space dimensions in vars into dest.

Parameters
varsThe set of Variable objects corresponding to the space dimensions to be folded;
destThe variable corresponding to the space dimension that is the destination of the folding operation.
Exceptions
std::invalid_argumentThrown if *this is dimension-incompatible with dest or with one of the Variable objects contained in vars. Also thrown if dest is contained in vars.

If *this has space dimension $n$, with $n > 0$, dest has space dimension $k \leq n$, vars is a set of variables whose maximum space dimension is also less than or equal to $n$, and dest is not a member of vars, then the space dimensions corresponding to variables in vars are folded into the $k$-th space dimension.

Definition at line 458 of file Grid_chdims.cc.

References affine_image(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Variables_Set::space_dimension(), Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::upper_bound_assign().

458  {
459  // TODO: this implementation is _really_ an executable specification.
460 
461  // `dest' should be one of the dimensions of the grid.
462  if (dest.space_dimension() > space_dim) {
463  throw_dimension_incompatible("fold_space_dimensions(vs, v)", "v", dest);
464  }
465 
466  // Folding only has effect if dimensions are given.
467  if (vars.empty()) {
468  return;
469  }
470 
471  // All variables in `vars' must be dimensions of the grid.
472  if (vars.space_dimension() > space_dim) {
473  throw_dimension_incompatible("fold_space_dimensions(vs, v)",
474  "vs.space_dimension()",
475  vars.space_dimension());
476  }
477 
478  // Moreover, `dest.id()' must not occur in `vars'.
479  if (vars.find(dest.id()) != vars.end()) {
480  throw_invalid_argument("fold_space_dimensions(vs, v)",
481  "v should not occur in vs");
482  }
483  // All of the affine images we are going to compute are not invertible,
484  // hence we will need to compute the grid generators of the polyhedron.
485  // Since we keep taking copies, make sure that a single conversion
486  // from congruences to grid generators is computed.
487  (void) grid_generators();
488  // Having grid generators, we now know if the grid is empty:
489  // in that case, folding is equivalent to just removing space dimensions.
490  if (!marked_empty()) {
491  for (Variables_Set::const_iterator i = vars.begin(),
492  vs_end = vars.end(); i != vs_end; ++i) {
493  Grid copy = *this;
494  copy.affine_image(dest, Linear_Expression(Variable(*i)));
495  upper_bound_assign(copy);
496  }
497  }
499  PPL_ASSERT(OK());
500 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void remove_space_dimensions(const Variables_Set &vars)
Removes all the specified dimensions from the vector space.
Definition: Grid_chdims.cc:273
const Grid_Generator_System & grid_generators() const
Returns the system of generators.
Definition: Grid_public.cc:334
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
void upper_bound_assign(const Grid &y)
Assigns to *this the least upper bound of *this and y.
bool Parma_Polyhedra_Library::Grid::frequency ( const Linear_Expression expr,
Coefficient freq_n,
Coefficient freq_d,
Coefficient val_n,
Coefficient val_d 
) const

Returns true if and only if *this is not empty and frequency for *this with respect to expr is defined, in which case the frequency and the value for expr that is closest to zero are computed.

Parameters
exprThe linear expression for which the frequency is needed;
freq_nThe numerator of the maximum frequency of expr;
freq_dThe denominator of the maximum frequency of expr;
val_nThe numerator of them value of expr at a point in the grid that is closest to zero;
val_dThe denominator of a value of expr at a point in the grid that is closest to zero;
Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

If *this is empty or frequency is undefined with respect to expr, then false is returned and freq_n, freq_d, val_n and val_d are left untouched.

Definition at line 2700 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::space_dimension().

Referenced by Parma_Polyhedra_Library::Affine_Space::frequency().

2702  {
2703  // The dimension of `expr' must be at most the dimension of *this.
2704  if (space_dim < expr.space_dimension()) {
2705  throw_dimension_incompatible("frequency(e, ...)", "e", expr);
2706  }
2707 
2708  // Space dimension is 0: if empty, then return false;
2709  // otherwise the frequency is 1 and the value is 0.
2710  if (space_dim == 0) {
2711  if (is_empty()) {
2712  return false;
2713  }
2714  freq_n = 0;
2715  freq_d = 1;
2716  val_n = 0;
2717  val_d = 1;
2718  return true;
2719  }
2720  if (!generators_are_minimized() && !minimize()) {
2721  // Minimizing found `this' empty.
2722  return false;
2723  }
2724 
2725  return frequency_no_check(expr, freq_n, freq_d, val_n, val_d);
2726 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool frequency_no_check(const Linear_Expression &expr, Coefficient &freq_n, Coefficient &freq_d, Coefficient &val_n, Coefficient &val_d) const
Returns true if and only if *this is not empty and frequency for *this with respect to expr is define...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool is_empty() const
Returns true if and only if *this is an empty grid.
Definition: Grid_public.cc:742
bool minimize() const
Minimizes both the congruences and the generators.
bool Parma_Polyhedra_Library::Grid::frequency_no_check ( const Linear_Expression expr,
Coefficient freq_n,
Coefficient freq_d,
Coefficient val_n,
Coefficient val_d 
) const
private

Returns true if and only if *this is not empty and frequency for *this with respect to expr is defined, in which case the frequency and the value for expr that is closest to zero are computed.

Parameters
exprThe linear expression for which the frequency is needed;
freq_nThe numerator of the maximum frequency of expr;
freq_dThe denominator of the maximum frequency of expr;
val_nThe numerator of a value of expr at a point in the grid that is closest to zero;
val_dThe denominator of a value of expr at a point in the grid that is closest to zero;

If *this is empty or frequency is undefined with respect to expr, then false is returned and freq_n, freq_d, val_n and val_d are left untouched.

Warning
If expr and *this are dimension-incompatible, the grid generator system is not minimized or *this is empty, then the behavior is undefined.

Definition at line 332 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Scalar_Products::homogeneous_assign(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::Grid_Generator::is_line(), Parma_Polyhedra_Library::Grid_Generator::is_parameter(), Parma_Polyhedra_Library::Grid_Generator::is_point(), PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Boundary_NS::sgn(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

Referenced by wrap_assign().

334  {
335 
336  // The dimension of `expr' must be at most the dimension of *this.
337  PPL_ASSERT(space_dim >= expr.space_dimension());
338  PPL_ASSERT(generators_are_minimized() && !marked_empty());
339 
340  // The generators are up to date and minimized and the grid is non-empty.
341 
342  // If the grid is bounded for the expression `expr',
343  // then `expr' has a constant value and the frequency is 0.
344  if (bounds_no_check(expr)) {
345  freq_n = 0;
346  freq_d = 1;
347  // Find the value of the constant expression.
348  const Grid_Generator& point = gen_sys[0];
349  val_d = point.divisor();
350  Scalar_Products::homogeneous_assign(val_n, expr, point);
351  val_n += expr.inhomogeneous_term() * val_d;
352  // Reduce `val_n' and `val_d'.
354  gcd_assign(gcd, val_n, val_d);
355  exact_div_assign(val_n, val_n, gcd);
356  exact_div_assign(val_d, val_d, gcd);
357  return true;
358  }
359 
360  // The frequency is the gcd of the scalar products of the parameters
361  // in `gen_sys'.
362  const dimension_type num_rows = gen_sys.num_rows();
364  freq_n = 0;
365 
366  // As the generators are minimized, `gen_sys[0]' is a point
367  // and considered later.
368  for (dimension_type row = 1; row < num_rows; ++row) {
369  const Grid_Generator& gen = gen_sys[row];
371  if (gen.is_line()) {
372  if (sgn(sp) != 0) {
373  return false;
374  }
375  continue;
376  }
377  // `gen' must be a parameter.
378  PPL_ASSERT(gen.is_parameter());
379  if (sgn(sp) != 0) {
380  gcd_assign(freq_n, freq_n, sp);
381  }
382  }
383  const Grid_Generator& point = gen_sys[0];
384  PPL_ASSERT(point.is_point());
385 
386  // The denominator of the frequency and of the value is
387  // the divisor for the generators.
388  freq_d = point.divisor();
389  val_d = freq_d;
390 
391  // As point is a grid generator, homogeneous_assign() must be used.
392  Scalar_Products::homogeneous_assign(val_n, expr, point);
393  val_n += expr.inhomogeneous_term() * val_d;
394 
395  // Reduce `val_n' by the frequency `freq_n'.
396  val_n %= freq_n;
397 
399  // Reduce `freq_n' and `freq_d'.
400  gcd_assign(gcd, freq_n, freq_d);
401  exact_div_assign(freq_n, freq_n, gcd);
402  exact_div_assign(freq_d, freq_d, gcd);
403 
404  // Reduce `val_n' and `val_d'.
405  gcd_assign(gcd, val_n, val_d);
406  exact_div_assign(val_n, val_n, gcd);
407  exact_div_assign(val_d, val_d, gcd);
408 
409  return true;
410 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
int sgn(Boundary_Type type, const T &x, const Info &info)
static void homogeneous_assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the homogeneous scalar product of x and y, where the inhomogeneous terms are ignored...
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool bounds_no_check(const Linear_Expression &expr) const
Checks if and how expr is bounded in *this.
void Parma_Polyhedra_Library::Grid::generalized_affine_image ( Variable  var,
Relation_Symbol  relsym,
const Linear_Expression expr,
Coefficient_traits::const_reference  denominator = Coefficient_one(),
Coefficient_traits::const_reference  modulus = Coefficient_zero() 
)

Assigns to *this the image of *this with respect to the generalized affine relation $\mathrm{var}' = \frac{\mathrm{expr}}{\mathrm{denominator}} \pmod{\mathrm{modulus}}$.

Parameters
varThe left hand side variable of the generalized affine relation;
relsymThe relation symbol where EQUAL is the symbol for a congruence relation;
exprThe numerator of the right hand side affine expression;
denominatorThe denominator of the right hand side affine expression. Optional argument with an automatic value of one;
modulusThe modulus of the congruence lhs %= rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero.
Exceptions
std::invalid_argumentThrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a space dimension of this.

Definition at line 2063 of file Grid_public.cc.

References Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::NOT_EQUAL, Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

2067  {
2068  // The denominator cannot be zero.
2069  if (denominator == 0) {
2070  throw_invalid_argument("generalized_affine_image(v, r, e, d, m)",
2071  "d == 0");
2072  }
2073 
2074  // Dimension-compatibility checks.
2075  // The dimension of `expr' should not be greater than the dimension
2076  // of `*this'.
2077  const dimension_type expr_space_dim = expr.space_dimension();
2078  if (space_dim < expr_space_dim) {
2079  throw_dimension_incompatible("generalized_affine_image(v, r, e, d, m)",
2080  "e", expr);
2081  }
2082  // `var' should be one of the dimensions of the grid.
2083  const dimension_type var_space_dim = var.space_dimension();
2084  if (space_dim < var_space_dim) {
2085  throw_dimension_incompatible("generalized_affine_image(v, r, e, d, m)",
2086  "v", var);
2087  }
2088  // The relation symbol cannot be a disequality.
2089  if (relsym == NOT_EQUAL) {
2090  throw_invalid_argument("generalized_affine_image(v, r, e, d, m)",
2091  "r is the disequality relation symbol");
2092  }
2093 
2094  // Any image of an empty grid is empty.
2095  if (marked_empty()) {
2096  return;
2097  }
2098 
2099  // If relsym is not EQUAL, then we return a safe approximation
2100  // by adding a line in the direction of var.
2101  if (relsym != EQUAL) {
2102 
2103  if (modulus != 0) {
2104  throw_invalid_argument("generalized_affine_image(v, r, e, d, m)",
2105  "r != EQUAL && m != 0");
2106  }
2107 
2108  if (!generators_are_up_to_date()) {
2109  minimize();
2110  }
2111 
2112  // Any image of an empty grid is empty.
2113  if (marked_empty()) {
2114  return;
2115  }
2116 
2117  add_grid_generator(grid_line(var));
2118 
2119  PPL_ASSERT(OK());
2120  return;
2121  }
2122 
2123  PPL_ASSERT(relsym == EQUAL);
2124 
2125  affine_image(var, expr, denominator);
2126 
2127  if (modulus == 0) {
2128  return;
2129  }
2130 
2131  // Modulate dimension `var' according to `modulus'.
2132 
2133  if (!generators_are_up_to_date()) {
2134  minimize();
2135  }
2136 
2137  // Test if minimization, possibly in affine_image, found an empty
2138  // grid.
2139  if (marked_empty()) {
2140  return;
2141  }
2142 
2143  if (modulus < 0) {
2144  gen_sys.insert(parameter(-modulus * var));
2145  }
2146  else {
2147  gen_sys.insert(parameter(modulus * var));
2148  }
2149 
2151 
2154 
2155  PPL_ASSERT(OK());
2156 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void add_grid_generator(const Grid_Generator &g)
Adds a copy of grid generator g to the system of generators of *this.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
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 to the affine expre...
bool minimize() const
Minimizes both the congruences and the generators.
void Parma_Polyhedra_Library::Grid::generalized_affine_image ( const Linear_Expression lhs,
Relation_Symbol  relsym,
const Linear_Expression rhs,
Coefficient_traits::const_reference  modulus = Coefficient_zero() 
)

Assigns to *this the image of *this with respect to the generalized affine relation $\mathrm{lhs}' = \mathrm{rhs} \pmod{\mathrm{modulus}}$.

Parameters
lhsThe left hand side affine expression.
relsymThe relation symbol where EQUAL is the symbol for a congruence relation;
rhsThe right hand side affine expression.
modulusThe modulus of the congruence lhs %= rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero.
Exceptions
std::invalid_argumentThrown if *this is dimension-incompatible with lhs or rhs.

Definition at line 2269 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::begin(), Parma_Polyhedra_Library::Linear_Expression::end(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::Linear_Expression::have_a_common_variable(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Linear_Expression::last_nonzero(), Parma_Polyhedra_Library::Linear_Expression::lower_bound(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::NOT_EQUAL, PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Grid_Generator_System::set_space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

2272  {
2273  // Dimension-compatibility checks.
2274  // The dimension of `lhs' should be at most the dimension of
2275  // `*this'.
2276  dimension_type lhs_space_dim = lhs.space_dimension();
2277  if (space_dim < lhs_space_dim) {
2278  throw_dimension_incompatible("generalized_affine_image(e1, r, e2, m)",
2279  "e1", lhs);
2280  }
2281  // The dimension of `rhs' should be at most the dimension of
2282  // `*this'.
2283  const dimension_type rhs_space_dim = rhs.space_dimension();
2284  if (space_dim < rhs_space_dim) {
2285  throw_dimension_incompatible("generalized_affine_image(e1, r, e2, m)",
2286  "e2", rhs);
2287  }
2288  // The relation symbol cannot be a disequality.
2289  if (relsym == NOT_EQUAL) {
2290  throw_invalid_argument("generalized_affine_image(e1, r, e2, m)",
2291  "r is the disequality relation symbol");
2292  }
2293 
2294  // Any image of an empty grid is empty.
2295  if (marked_empty()) {
2296  return;
2297  }
2298 
2299  // If relsym is not EQUAL, then we return a safe approximation
2300  // by adding a line in the direction of var.
2301  if (relsym != EQUAL) {
2302 
2303  if (modulus != 0) {
2304  throw_invalid_argument("generalized_affine_image(e1, r, e2, m)",
2305  "r != EQUAL && m != 0");
2306  }
2307 
2308  if (!generators_are_up_to_date()) {
2309  minimize();
2310  }
2311 
2312  // Any image of an empty grid is empty.
2313  if (marked_empty()) {
2314  return;
2315  }
2316 
2317  for (Linear_Expression::const_iterator i = lhs.begin(), i_end = lhs.end();
2318  i != i_end; ++i) {
2319  add_grid_generator(grid_line(i.variable()));
2320  }
2321 
2322  PPL_ASSERT(OK());
2323  return;
2324  }
2325 
2326  PPL_ASSERT(relsym == EQUAL);
2327 
2328  PPL_DIRTY_TEMP_COEFFICIENT(tmp_modulus);
2329  tmp_modulus = modulus;
2330  if (tmp_modulus < 0) {
2331  neg_assign(tmp_modulus);
2332  }
2333 
2334  // Compute the actual space dimension of `lhs',
2335  // i.e., the highest dimension having a non-zero coefficient in `lhs'.
2336 
2337  lhs_space_dim = lhs.last_nonzero();
2338  if (lhs_space_dim == 0) {
2339  // All variables have zero coefficients, so `lhs' is a constant.
2340  add_congruence_no_check((lhs %= rhs) / tmp_modulus);
2341  return;
2342  }
2343 
2344  // Gather in `new_lines' the collections of all the lines having the
2345  // direction of variables occurring in `lhs'.
2346  Grid_Generator_System new_lines;
2347  for (Linear_Expression::const_iterator i = lhs.begin(),
2348  i_end = lhs.lower_bound(Variable(lhs_space_dim)); i != i_end; ++i) {
2349  new_lines.insert(grid_line(i.variable()));
2350  }
2351 
2352  const dimension_type num_common_dims = std::min(lhs_space_dim, rhs_space_dim);
2353  if (lhs.have_a_common_variable(rhs, Variable(0), Variable(num_common_dims))) {
2354  // Some variables in `lhs' also occur in `rhs'.
2355  // To ease the computation, add an additional dimension.
2356  const Variable new_var(space_dim);
2358 
2359  // Constrain the new dimension to be equal to the right hand side.
2360  // TODO: Use add_congruence() when it has been updated.
2361  Congruence_System new_cgs1(new_var == rhs);
2362  add_recycled_congruences(new_cgs1);
2363  if (!is_empty()) {
2364  // The grid still contains points.
2365 
2366  // Existentially quantify all the variables occurring in the left
2367  // hand side expression.
2368 
2369  // Adjust `new_lines' to the right dimension.
2370  new_lines.set_space_dimension(space_dim);
2371  // Add the lines to `gen_sys' (first make sure they are up-to-date).
2373  gen_sys.insert(new_lines, Recycle_Input());
2375  // Update the flags.
2378 
2379  // Constrain the new dimension so that it is congruent to the left
2380  // hand side expression modulo `modulus'.
2381  // TODO: Use add_congruence() when it has been updated.
2382  Congruence_System new_cgs2((lhs %= new_var) / tmp_modulus);
2383  add_recycled_congruences(new_cgs2);
2384  }
2385 
2386  // Remove the temporarily added dimension.
2388  }
2389  else {
2390  // `lhs' and `rhs' variables are disjoint:
2391  // there is no need to add a further dimension.
2392 
2393  // Only add the lines and congruence if there are points.
2394  if (is_empty()) {
2395  return;
2396  }
2397 
2398  // Existentially quantify all the variables occurring in the left hand
2399  // side expression.
2400  add_recycled_grid_generators(new_lines);
2401 
2402  // Constrain the left hand side expression so that it is congruent to
2403  // the right hand side expression modulo `modulus'.
2404  add_congruence_no_check((lhs %= rhs) / tmp_modulus);
2405  }
2406 
2407  PPL_ASSERT(OK());
2408 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void add_space_dimensions_and_embed(dimension_type m)
Adds m new space dimensions and embeds the old grid in the new vector space.
Definition: Grid_chdims.cc:77
void remove_higher_space_dimensions(dimension_type new_dimension)
Removes the higher dimensions of the vector space so that the resulting space will have dimension new...
Definition: Grid_chdims.cc:318
size_t dimension_type
An unsigned integral type for representing space dimensions.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void add_congruence_no_check(const Congruence &cg)
Adds the congruence cg to *this.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void add_recycled_grid_generators(Grid_Generator_System &gs)
Adds the generators in gs to the system of generators of this.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void add_grid_generator(const Grid_Generator &g)
Adds a copy of grid generator g to the system of generators of *this.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void neg_assign(GMP_Integer &x)
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
void add_recycled_congruences(Congruence_System &cgs)
Adds the congruences in cgs to *this.
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
bool update_generators() const
Updates and minimizes the generators from the congruences.
bool is_empty() const
Returns true if and only if *this is an empty grid.
Definition: Grid_public.cc:742
bool minimize() const
Minimizes both the congruences and the generators.
void Parma_Polyhedra_Library::Grid::generalized_affine_preimage ( Variable  var,
Relation_Symbol  relsym,
const Linear_Expression expr,
Coefficient_traits::const_reference  denominator = Coefficient_one(),
Coefficient_traits::const_reference  modulus = Coefficient_zero() 
)

Assigns to *this the preimage of *this with respect to the generalized affine relation $\mathrm{var}' = \frac{\mathrm{expr}}{\mathrm{denominator}} \pmod{\mathrm{modulus}}$.

Parameters
varThe left hand side variable of the generalized affine relation;
relsymThe relation symbol where EQUAL is the symbol for a congruence relation;
exprThe numerator of the right hand side affine expression;
denominatorThe denominator of the right hand side affine expression. Optional argument with an automatic value of one;
modulusThe modulus of the congruence lhs %= rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero.
Exceptions
std::invalid_argumentThrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a space dimension of this.

Definition at line 2160 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::NOT_EQUAL, PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Variable::space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

2164  {
2165  // The denominator cannot be zero.
2166  if (denominator == 0) {
2167  throw_invalid_argument("generalized_affine_preimage(v, r, e, d, m)",
2168  "d == 0");
2169  }
2170 
2171  // The dimension of `expr' should be at most the dimension of
2172  // `*this'.
2173  const dimension_type expr_space_dim = expr.space_dimension();
2174  if (space_dim < expr_space_dim) {
2175  throw_dimension_incompatible("generalized_affine_preimage(v, r, e, d, m)",
2176  "e", expr);
2177  }
2178  // `var' should be one of the dimensions of the grid.
2179  const dimension_type var_space_dim = var.space_dimension();
2180  if (space_dim < var_space_dim) {
2181  throw_dimension_incompatible("generalized_affine_preimage(v, r, e, d, m)",
2182  "v", var);
2183  }
2184  // The relation symbol cannot be a disequality.
2185  if (relsym == NOT_EQUAL) {
2186  throw_invalid_argument("generalized_affine_preimage(v, r, e, d, m)",
2187  "r is the disequality relation symbol");
2188  }
2189 
2190  // If relsym is not EQUAL, then we return a safe approximation
2191  // by adding a line in the direction of var.
2192  if (relsym != EQUAL) {
2193 
2194  if (modulus != 0) {
2195  throw_invalid_argument("generalized_affine_preimage(v, r, e, d, m)",
2196  "r != EQUAL && m != 0");
2197  }
2198 
2199  if (!generators_are_up_to_date()) {
2200  minimize();
2201  }
2202 
2203  // Any image of an empty grid is empty.
2204  if (marked_empty()) {
2205  return;
2206  }
2207 
2208  add_grid_generator(grid_line(var));
2209 
2210  PPL_ASSERT(OK());
2211  return;
2212  }
2213 
2214  PPL_ASSERT(relsym == EQUAL);
2215  // Any image of an empty grid is empty.
2216  if (marked_empty()) {
2217  return;
2218  }
2219  // Check whether the affine relation is an affine function.
2220  if (modulus == 0) {
2221  affine_preimage(var, expr, denominator);
2222  return;
2223  }
2224 
2225  // Check whether the preimage of this affine relation can be easily
2226  // computed as the image of its inverse relation.
2227  const Coefficient& var_coefficient = expr.coefficient(var);
2228  if (var_space_dim <= expr_space_dim && var_coefficient != 0) {
2229  const Linear_Expression inverse_expr
2230  = expr - (denominator + var_coefficient) * var;
2231  PPL_DIRTY_TEMP_COEFFICIENT(inverse_denominator);
2232  neg_assign(inverse_denominator, var_coefficient);
2233  if (modulus < 0) {
2234  generalized_affine_image(var, EQUAL, inverse_expr, inverse_denominator,
2235  - modulus);
2236  }
2237  else {
2238  generalized_affine_image(var, EQUAL, inverse_expr, inverse_denominator,
2239  modulus);
2240  }
2241  return;
2242  }
2243 
2244  // Here `var_coefficient == 0', so that the preimage cannot be
2245  // easily computed by inverting the affine relation. Add the
2246  // congruence induced by the affine relation.
2247  {
2248  Congruence cg((denominator*var %= expr) / denominator);
2249  if (modulus < 0) {
2250  cg /= -modulus;
2251  }
2252  else {
2253  cg /= modulus;
2254  }
2256  }
2257 
2258  // If the resulting grid is empty, its preimage is empty too.
2259  // Note: DO check for emptiness here, as we will later add a line.
2260  if (is_empty()) {
2261  return;
2262  }
2263  add_grid_generator(grid_line(var));
2264  PPL_ASSERT(OK());
2265 }
void generalized_affine_image(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one(), Coefficient_traits::const_reference modulus=Coefficient_zero())
Assigns to *this the image of *this with respect to the generalized affine relation ...
size_t dimension_type
An unsigned integral type for representing space dimensions.
void add_congruence_no_check(const Congruence &cg)
Adds the congruence cg to *this.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
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 to the affine e...
void add_grid_generator(const Grid_Generator &g)
Adds a copy of grid generator g to the system of generators of *this.
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void neg_assign(GMP_Integer &x)
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
bool is_empty() const
Returns true if and only if *this is an empty grid.
Definition: Grid_public.cc:742
bool minimize() const
Minimizes both the congruences and the generators.
void Parma_Polyhedra_Library::Grid::generalized_affine_preimage ( const Linear_Expression lhs,
Relation_Symbol  relsym,
const Linear_Expression rhs,
Coefficient_traits::const_reference  modulus = Coefficient_zero() 
)

Assigns to *this the preimage of *this with respect to the generalized affine relation $\mathrm{lhs}' = \mathrm{rhs} \pmod{\mathrm{modulus}}$.

Parameters
lhsThe left hand side affine expression;
relsymThe relation symbol where EQUAL is the symbol for a congruence relation;
rhsThe right hand side affine expression;
modulusThe modulus of the congruence lhs %= rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero.
Exceptions
std::invalid_argumentThrown if *this is dimension-incompatible with lhs or rhs.

Definition at line 2412 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::begin(), Parma_Polyhedra_Library::Linear_Expression::end(), Parma_Polyhedra_Library::EQUAL, Parma_Polyhedra_Library::Linear_Expression::have_a_common_variable(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Linear_Expression::last_nonzero(), Parma_Polyhedra_Library::Linear_Expression::lower_bound(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::NOT_EQUAL, PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Grid_Generator_System::set_space_dimension(), and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

2415  {
2416  // The dimension of `lhs' must be at most the dimension of `*this'.
2417  dimension_type lhs_space_dim = lhs.space_dimension();
2418  if (space_dim < lhs_space_dim) {
2419  throw_dimension_incompatible("generalized_affine_preimage(e1, r, e2, m)",
2420  "lhs", lhs);
2421  }
2422  // The dimension of `rhs' must be at most the dimension of `*this'.
2423  const dimension_type rhs_space_dim = rhs.space_dimension();
2424  if (space_dim < rhs_space_dim) {
2425  throw_dimension_incompatible("generalized_affine_preimage(e1, r, e2, m)",
2426  "e2", rhs);
2427  }
2428  // The relation symbol cannot be a disequality.
2429  if (relsym == NOT_EQUAL) {
2430  throw_invalid_argument("generalized_affine_preimage(e1, r, e2, m)",
2431  "r is the disequality relation symbol");
2432  }
2433 
2434  // Any preimage of an empty grid is empty.
2435  if (marked_empty()) {
2436  return;
2437  }
2438 
2439  // If relsym is not EQUAL, then we return a safe approximation
2440  // by adding a line in the direction of var.
2441  if (relsym != EQUAL) {
2442 
2443  if (modulus != 0) {
2444  throw_invalid_argument("generalized_affine_preimage(e1, r, e2, m)",
2445  "r != EQUAL && m != 0");
2446  }
2447 
2448  if (!generators_are_up_to_date()) {
2449  minimize();
2450  }
2451  // Any image of an empty grid is empty.
2452  if (marked_empty()) {
2453  return;
2454  }
2455 
2456  for (Linear_Expression::const_iterator i = lhs.begin(), i_end = lhs.end();
2457  i != i_end; ++i) {
2458  add_grid_generator(grid_line(i.variable()));
2459  }
2460 
2461  PPL_ASSERT(OK());
2462  return;
2463  }
2464 
2465  PPL_ASSERT(relsym == EQUAL);
2466 
2467  PPL_DIRTY_TEMP_COEFFICIENT(tmp_modulus);
2468  tmp_modulus = modulus;
2469  if (tmp_modulus < 0) {
2470  neg_assign(tmp_modulus);
2471  }
2472 
2473  // Compute the actual space dimension of `lhs',
2474  // i.e., the highest dimension having a non-zero coefficient in `lhs'.
2475  lhs_space_dim = lhs.last_nonzero();
2476  if (lhs_space_dim == 0) {
2477  // All variables have zero coefficients, so `lhs' is a constant.
2478  // In this case, preimage and image happen to be the same.
2479  add_congruence_no_check((lhs %= rhs) / tmp_modulus);
2480  return;
2481  }
2482 
2483  // Gather in `new_lines' the collections of all the lines having
2484  // the direction of variables occurring in `lhs'.
2485  Grid_Generator_System new_lines;
2486  for (Linear_Expression::const_iterator i = lhs.begin(),
2487  i_end = lhs.lower_bound(Variable(lhs_space_dim)); i != i_end; ++i) {
2488  new_lines.insert(grid_line(i.variable()));
2489  }
2490 
2491  const dimension_type num_common_dims
2492  = std::min(lhs_space_dim, rhs_space_dim);
2493  if (lhs.have_a_common_variable(rhs, Variable(0), Variable(num_common_dims))) {
2494  // Some variables in `lhs' also occur in `rhs'.
2495  // To ease the computation, add an additional dimension.
2496  const Variable new_var(space_dim);
2498 
2499  // Constrain the new dimension to be equal to `lhs'
2500  // TODO: Use add_congruence() when it has been updated.
2501  Congruence_System new_cgs1(new_var == lhs);
2502  add_recycled_congruences(new_cgs1);
2503  if (!is_empty()) {
2504  // The grid still contains points.
2505 
2506  // Existentially quantify all the variables occurring in the left
2507  // hand side
2508 
2509  // Adjust `new_lines' to the right dimension.
2510  new_lines.set_space_dimension(space_dim);
2511  // Add the lines to `gen_sys' (first make sure they are up-to-date).
2513  gen_sys.insert(new_lines, Recycle_Input());
2515  // Update the flags.
2518 
2519  // Constrain the new dimension so that it is related to
2520  // the right hand side modulo `modulus'.
2521  // TODO: Use add_congruence() when it has been updated.
2522  Congruence_System new_cgs2((rhs %= new_var) / tmp_modulus);
2523  add_recycled_congruences(new_cgs2);
2524  }
2525 
2526  // Remove the temporarily added dimension.
2528  }
2529  else {
2530  // `lhs' and `rhs' variables are disjoint:
2531  // there is no need to add a further dimension.
2532 
2533  // Constrain the left hand side expression so that it is congruent to
2534  // the right hand side expression modulo `mod'.
2535  add_congruence_no_check((lhs %= rhs) / tmp_modulus);
2536 
2537  // Any image of an empty grid is empty.
2538  if (is_empty()) {
2539  return;
2540  }
2541 
2542  // Existentially quantify all the variables occurring in `lhs'.
2543  add_recycled_grid_generators(new_lines);
2544  }
2545  PPL_ASSERT(OK());
2546 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void add_space_dimensions_and_embed(dimension_type m)
Adds m new space dimensions and embeds the old grid in the new vector space.
Definition: Grid_chdims.cc:77
void remove_higher_space_dimensions(dimension_type new_dimension)
Removes the higher dimensions of the vector space so that the resulting space will have dimension new...
Definition: Grid_chdims.cc:318
size_t dimension_type
An unsigned integral type for representing space dimensions.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void add_congruence_no_check(const Congruence &cg)
Adds the congruence cg to *this.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void add_recycled_grid_generators(Grid_Generator_System &gs)
Adds the generators in gs to the system of generators of this.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void add_grid_generator(const Grid_Generator &g)
Adds a copy of grid generator g to the system of generators of *this.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void neg_assign(GMP_Integer &x)
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
void add_recycled_congruences(Congruence_System &cgs)
Adds the congruences in cgs to *this.
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
bool update_generators() const
Updates and minimizes the generators from the congruences.
bool is_empty() const
Returns true if and only if *this is an empty grid.
Definition: Grid_public.cc:742
bool minimize() const
Minimizes both the congruences and the generators.
void Parma_Polyhedra_Library::Grid::generator_widening_assign ( const Grid y,
unsigned *  tp = NULL 
)

Assigns to *this the result of computing the Grid widening between *this and y using generator systems.

Parameters
yA grid that must be contained in *this;
tpAn optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique).
Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 282 of file Grid_widenings.cc.

References add_recycled_grid_generators(), contains(), dim_kinds, Parma_Polyhedra_Library::EMPTY, gen_sys, generators_are_minimized(), generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::has_no_rows(), m_swap(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_lines(), Parma_Polyhedra_Library::Grid_Generator_System::num_parameters(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), OK(), select_wider_generators(), set_generators_minimized(), space_dim, and update_generators().

Referenced by limited_generator_extrapolation_assign(), and widening_assign().

282  {
283  Grid& x = *this;
284 
285  // Dimension-compatibility check.
286  if (x.space_dim != y.space_dim) {
287  throw_dimension_incompatible("generator_widening_assign(y)", "y", y);
288  }
289 
290  // Assume `y' is contained in or equal to `x'.
291  PPL_EXPECT_HEAVY(copy_contains(x, y));
292 
293  // Leave `x' the same if `x' or `y' is zero-dimensional or empty.
294  if (x.space_dim == 0 || x.marked_empty() || y.marked_empty()) {
295  return;
296  }
297 
298  // Ensure that the `x' generators are in minimal form.
299  if (x.generators_are_up_to_date()) {
300  if (!x.generators_are_minimized()) {
301  simplify(x.gen_sys, x.dim_kinds);
302  PPL_ASSERT(!x.gen_sys.has_no_rows());
303  x.set_generators_minimized();
304  }
305  }
306  else {
307  x.update_generators();
308  }
309 
310  if (x.marked_empty()) {
311  return;
312  }
313 
314  // Ensure that the `y' generators are in minimal form.
315  Grid& yy = const_cast<Grid&>(y);
316  if (yy.generators_are_up_to_date()) {
317  if (!yy.generators_are_minimized()) {
318  simplify(yy.gen_sys, yy.dim_kinds);
319  PPL_ASSERT(!yy.gen_sys.has_no_rows());
320  yy.set_generators_minimized();
321  }
322  }
323  else {
324  yy.update_generators();
325  }
326 
327  if (gen_sys.num_rows() > yy.gen_sys.num_rows()) {
328  return;
329  }
330 
331  if (gen_sys.num_lines() > yy.gen_sys.num_lines()) {
332  return;
333  }
334 
335  // Copy into `ggs' the generators of `x' that are common to `y',
336  // according to the grid widening.
337  Grid_Generator_System ggs;
338  x.select_wider_generators(yy, ggs);
339 
340  if (ggs.num_parameters() == gen_sys.num_parameters()) {
341  // All parameters are kept as parameters, thus the result is `x'.
342  return;
343  }
344 
345  // A strict subset of the parameters was selected.
346 
347  Grid result(x.space_dim, EMPTY);
348  result.add_recycled_grid_generators(ggs);
349 
350  // Check whether we are using the widening-with-tokens technique
351  // and there are still tokens available.
352  if (tp != 0 && *tp > 0) {
353  // There are tokens available. If `result' is not a subset of
354  // `x', then it is less precise and we use one of the available
355  // tokens.
356  if (!x.contains(result)) {
357  --(*tp);
358  }
359  }
360  else {
361  // No tokens.
362  x.m_swap(result);
363  }
364 
365  PPL_ASSERT(x.OK(true));
366 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
The empty element, i.e., the empty set.
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
dimension_type num_lines() const
Returns the number of lines in the system.
static bool simplify(Congruence_System &cgs, Dimension_Kinds &dim_kinds)
Converts cgs to upper triangular (i.e. minimized) form.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
dimension_type num_parameters() const
Returns the number of parameters in the system.
bool Parma_Polyhedra_Library::Grid::generators_are_minimized ( ) const
inlineprivate

Returns true if the system of generators is minimized.

Definition at line 55 of file Grid_inlines.hh.

References status, and Parma_Polyhedra_Library::Grid::Status::test_g_minimized().

Referenced by add_space_dimensions(), generator_widening_assign(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), quick_equivalence_test(), select_wider_generators(), and simplify_using_context_assign().

55  {
56  return status.test_g_minimized();
57 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
bool Parma_Polyhedra_Library::Grid::generators_are_up_to_date ( ) const
inlineprivate
const PPL::Grid_Generator_System & Parma_Polyhedra_Library::Grid::grid_generators ( ) const

Returns the system of generators.

Definition at line 334 of file Grid_public.cc.

References set_empty().

Referenced by map_space_dimensions().

334  {
335  if (space_dim == 0) {
336  PPL_ASSERT(gen_sys.space_dimension() == 0
337  && gen_sys.num_rows() == (marked_empty() ? 0U : 1U));
338  return gen_sys;
339  }
340 
341  if (marked_empty()) {
342  PPL_ASSERT(gen_sys.has_no_rows());
343  return gen_sys;
344  }
345 
347  // Updating found the grid empty.
348  const_cast<Grid&>(*this).set_empty();
349  return gen_sys;
350  }
351 
352  return gen_sys;
353 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool update_generators() const
Updates and minimizes the generators from the congruences.
int32_t Parma_Polyhedra_Library::Grid::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 234 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::hash_code_from_dimension(), and space_dimension().

Referenced by Parma_Polyhedra_Library::Affine_Space::hash_code().

234  {
236 }
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
int32_t hash_code_from_dimension(dimension_type dim)
Returns the hash code for space dimension dim.
void Parma_Polyhedra_Library::Grid::intersection_assign ( const Grid y)

Assigns to *this the intersection of *this and y.

Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 1485 of file Grid_public.cc.

References clear_congruences_minimized(), clear_generators_up_to_date(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::has_no_rows(), Parma_Polyhedra_Library::Congruence_System::insert(), marked_empty(), OK(), set_empty(), space_dim, and update_congruences().

Referenced by is_disjoint_from().

1485  {
1486  Grid& x = *this;
1487  // Dimension-compatibility check.
1488  if (x.space_dim != y.space_dim) {
1489  throw_dimension_incompatible("intersection_assign(y)", "y", y);
1490  }
1491  // If one of the two grids is empty, the intersection is empty.
1492  if (x.marked_empty()) {
1493  return;
1494  }
1495  if (y.marked_empty()) {
1496  x.set_empty();
1497  return;
1498  }
1499 
1500  // If both grids are zero-dimensional, then at this point they are
1501  // necessarily universe, so the intersection is also universe.
1502  if (x.space_dim == 0) {
1503  return;
1504  }
1505 
1506  // The congruences must be up-to-date.
1507  if (!x.congruences_are_up_to_date()) {
1508  x.update_congruences();
1509  }
1510  if (!y.congruences_are_up_to_date()) {
1511  y.update_congruences();
1512  }
1513 
1514  if (!y.con_sys.has_no_rows()) {
1515  x.con_sys.insert(y.con_sys);
1516  // Grid_Generators may be out of date and congruences may have changed
1517  // from minimal form.
1518  x.clear_generators_up_to_date();
1519  x.clear_congruences_minimized();
1520  }
1521 
1522  PPL_ASSERT(x.OK() && y.OK());
1523 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool Parma_Polyhedra_Library::Grid::is_bounded ( ) const

Returns true if and only if *this is bounded.

Definition at line 810 of file Grid_public.cc.

References Parma_Polyhedra_Library::Grid_Generator::is_line_or_parameter().

810  {
811  // A zero-dimensional or empty grid is bounded.
812  if (space_dim == 0
813  || marked_empty()
815  return true;
816  }
817  // TODO: Consider using con_sys when gen_sys is out of date.
818 
819  if (gen_sys.num_rows() > 1) {
820  // Check if all generators are the same point.
821  const Grid_Generator& first_point = gen_sys[0];
822  if (first_point.is_line_or_parameter()) {
823  return false;
824  }
825  for (dimension_type row = gen_sys.num_rows(); row-- > 0; ) {
826  const Grid_Generator& gen = gen_sys[row];
827  if (gen.is_line_or_parameter() || gen != first_point) {
828  return false;
829  }
830  }
831  }
832  return true;
833 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
bool update_generators() const
Updates and minimizes the generators from the congruences.
bool Parma_Polyhedra_Library::Grid::is_discrete ( ) const

Returns true if and only if *this is discrete.

A grid is discrete if it can be defined by a generator system which contains only points and parameters. This includes the empty grid and any grid in dimension zero.

Definition at line 836 of file Grid_public.cc.

836  {
837  // A zero-dimensional or empty grid is discrete.
838  if (space_dim == 0
839  || marked_empty()
841  return true;
842  }
843  // Search for lines in the generator system.
844  for (dimension_type row = gen_sys.num_rows(); row-- > 1; ) {
845  if (gen_sys[row].is_line()) {
846  return false;
847  }
848  }
849 
850  // The system of generators is composed only by
851  // points and parameters: the grid is discrete.
852  return true;
853 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
bool update_generators() const
Updates and minimizes the generators from the congruences.
bool Parma_Polyhedra_Library::Grid::is_disjoint_from ( const Grid y) const

Returns true if and only if *this and y are disjoint.

Exceptions
std::invalid_argumentThrown if x and y are dimension-incompatible.

Definition at line 2787 of file Grid_public.cc.

References intersection_assign(), is_empty(), and space_dim.

Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PSET >::check_containment().

2787  {
2788  // Dimension-compatibility check.
2789  if (space_dim != y.space_dim) {
2790  throw_dimension_incompatible("is_disjoint_from(y)", "y", y);
2791  }
2792  Grid z = *this;
2793  z.intersection_assign(y);
2794  return z.is_empty();
2795 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool Parma_Polyhedra_Library::Grid::is_empty ( ) const

Returns true if and only if *this is an empty grid.

Definition at line 742 of file Grid_public.cc.

References con_sys, dim_kinds, set_congruences_minimized(), set_empty(), and simplify().

Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PSET >::approximate_partition_aux(), Parma_Polyhedra_Library::Pointset_Powerset< PSET >::check_containment(), contains(), contains_integer_point(), is_disjoint_from(), operator<<(), operator==(), Parma_Polyhedra_Library::Pointset_Powerset< PSET >::Pointset_Powerset(), and simplify_using_context_assign().

742  {
743  if (marked_empty()) {
744  return true;
745  }
746  // Try a fast-fail test: if generators are up-to-date then the
747  // generator system (since it is well formed) contains a point.
749  return false;
750  }
751  if (space_dim == 0) {
752  return false;
753  }
755  // If the grid was empty it would be marked empty.
756  return false;
757  }
758  // Minimize the congruences to check if the grid is empty.
759  Grid& gr = const_cast<Grid&>(*this);
760  if (gr.simplify(gr.con_sys, gr.dim_kinds)) {
761  gr.set_empty();
762  return true;
763  }
764  gr.set_congruences_minimized();
765  return false;
766 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
bool Parma_Polyhedra_Library::Grid::is_included_in ( const Grid y) const
private

Returns true if and only if *this is included in y.

Definition at line 247 of file Grid_nonpublic.cc.

References con_sys, congruences_are_minimized(), congruences_are_up_to_date(), marked_empty(), minimize(), Parma_Polyhedra_Library::Congruence_System::num_rows(), OK(), Parma_Polyhedra_Library::Congruence_System::satisfies_all_congruences(), space_dim, and update_congruences().

Referenced by contains(), operator==(), simplify_using_context_assign(), and upper_bound_assign_if_exact().

247  {
248  // Private method: the caller must ensure the following.
249  PPL_ASSERT(space_dim == y.space_dim);
250  PPL_ASSERT(!marked_empty() && !y.marked_empty() && space_dim > 0);
251 
252  const Grid& x = *this;
253 
254 #if BE_LAZY
255  if (!x.generators_are_up_to_date() && !x.update_generators()) {
256  // Updating found `x' empty.
257  return true;
258  }
259  if (!y.congruences_are_up_to_date()) {
260  y.update_congruences();
261  }
262 #else
263  if (!x.generators_are_minimized() && !x.minimize()) {
264  // Minimizing found `x' empty.
265  return true;
266  }
267  if (!y.congruences_are_minimized())
268  y.minimize();
269 #endif
270 
271  PPL_ASSERT(x.OK());
272  PPL_ASSERT(y.OK());
273 
274  const Grid_Generator_System& gs = x.gen_sys;
275  const Congruence_System& cgs = y.con_sys;
276 
277  const dimension_type num_rows = gs.num_rows();
278  for (dimension_type i = num_rows; i-- > 0; ) {
279  if (!cgs.satisfies_all_congruences(gs[i])) {
280  return false;
281  }
282  }
283 
284  // Inclusion holds.
285  return true;
286 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool Parma_Polyhedra_Library::Grid::is_topologically_closed ( ) const

Returns true if and only if *this is a topologically closed subset of the vector space.

A grid is always topologically closed.

Definition at line 856 of file Grid_public.cc.

856  {
857  return true;
858 }
bool Parma_Polyhedra_Library::Grid::is_universe ( ) const

Returns true if and only if *this is a universe grid.

Definition at line 769 of file Grid_public.cc.

References Parma_Polyhedra_Library::Linear_Expression::set_space_dimension().

Referenced by operator<<().

769  {
770  if (marked_empty()) {
771  return false;
772  }
773 
774  if (space_dim == 0) {
775  return true;
776  }
777 
780  // The minimized universe congruence system has only one row,
781  // the integrality congruence.
782  return con_sys.num_rows() == 1 && con_sys[0].is_tautological();
783  }
784  }
785  else {
787  return con_sys.num_rows() == 1 && con_sys[0].is_tautological();
788  }
789 
790  // Test con_sys's inclusion in a universe generator system.
791 
792  // The zero dimension cases are handled above.
793  for (dimension_type i = space_dim; i-- > 0; ) {
794  Linear_Expression expr;
796  expr += Variable(i);
797  if (!con_sys.satisfies_all_congruences(grid_line(expr))) {
798  return false;
799  }
800  }
801 #ifndef NDEBUG
802  Linear_Expression expr;
803  expr.set_space_dimension(space_dim);
804  PPL_ASSERT(con_sys.satisfies_all_congruences(grid_point(expr)));
805 #endif
806  return true;
807 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool set_space_dimension(dimension_type new_space_dim)
Sets the number of space dimensions to new_space_dim.
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
bool satisfies_all_congruences(const Grid_Generator &g) const
Returns true if g satisfies all the congruences.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
dimension_type num_rows() const
Returns the number of rows in the system.
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
void update_congruences() const
Updates and minimizes the congruences from the generators.
void Parma_Polyhedra_Library::Grid::limited_congruence_extrapolation_assign ( const Grid y,
const Congruence_System cgs,
unsigned *  tp = NULL 
)

Improves the result of the congruence variant of Grid widening computation by also enforcing those congruences in cgs that are satisfied by all the points of *this.

Parameters
yA grid that must be contained in *this;
cgsThe system of congruences used to improve the widened grid;
tpAn optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique).
Exceptions
std::invalid_argumentThrown if *this, y and cgs are dimension-incompatible.

Definition at line 160 of file Grid_widenings.cc.

References add_recycled_congruences(), congruence_widening_assign(), generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), marked_empty(), Parma_Polyhedra_Library::Congruence_System::num_rows(), relation_with(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), update_generators(), and widening_assign().

162  {
163  Grid& x = *this;
164 
165  // Check dimension compatibility.
166  if (x.space_dim != y.space_dim) {
167  throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)",
168  "y", y);
169  }
170  // `cgs' must be dimension-compatible with the two grids.
171  const dimension_type cgs_space_dim = cgs.space_dimension();
172  if (x.space_dim < cgs_space_dim) {
173  throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)",
174  "cgs", cgs);
175  }
176 
177  const dimension_type cgs_num_rows = cgs.num_rows();
178  // If `cgs' is empty (of rows), fall back to ordinary widening.
179  if (cgs_num_rows == 0) {
180  x.widening_assign(y, tp);
181  return;
182  }
183 
184  // Assume `y' is contained in or equal to `x'.
185  PPL_EXPECT_HEAVY(copy_contains(x, y));
186 
187  if (y.marked_empty()) {
188  return;
189  }
190  if (x.marked_empty()) {
191  return;
192  }
193 
194  // The limited widening between two grids in a zero-dimensional
195  // space is also a grid in a zero-dimensional space.
196  if (x.space_dim == 0) {
197  return;
198  }
199 
200  // Update the generators of `x': these are used to select, from the
201  // congruences in `cgs', those that must be added to the widened
202  // grid.
203  if (!x.generators_are_up_to_date() && !x.update_generators()) {
204  // `x' is empty.
205  return;
206  }
207 
208  if (tp == NULL || *tp == 0) {
209  // Widening may change the grid, so add the congruences.
210  Congruence_System new_cgs;
211  // The congruences to be added need only be satisfied by all the
212  // generators of `x', as `y <= x'. Iterate upwards here, to keep
213  // the relative ordering of congruences (just for aesthetics).
214  for (dimension_type i = 0; i < cgs_num_rows; ++i) {
215  const Congruence& cg = cgs[i];
216  if (x.relation_with(cg) == Poly_Con_Relation::is_included()) {
217  new_cgs.insert(cg);
218  }
219  }
220  x.congruence_widening_assign(y, tp);
221  x.add_recycled_congruences(new_cgs);
222  }
223  else {
224  // There are tokens, so widening will leave the grid the same.
225  x.congruence_widening_assign(y, tp);
226  }
227 
228  PPL_ASSERT(OK());
229 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void Parma_Polyhedra_Library::Grid::limited_extrapolation_assign ( const Grid y,
const Congruence_System cgs,
unsigned *  tp = NULL 
)

Improves the result of the Grid widening computation by also enforcing those congruences in cgs that are satisfied by all the points of *this.

Parameters
yA grid that must be contained in *this;
cgsThe system of congruences used to improve the widened grid;
tpAn optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique).
Exceptions
std::invalid_argumentThrown if *this, y and cgs are dimension-incompatible.

Definition at line 470 of file Grid_widenings.cc.

References add_recycled_congruences(), generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), marked_empty(), Parma_Polyhedra_Library::Congruence_System::num_rows(), relation_with(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), update_generators(), and widening_assign().

472  {
473  Grid& x = *this;
474 
475  // Check dimension compatibility.
476  if (x.space_dim != y.space_dim) {
477  throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)",
478  "y", y);
479  }
480 
481  // `cgs' must be dimension-compatible with the two grids.
482  const dimension_type cgs_space_dim = cgs.space_dimension();
483  if (x.space_dim < cgs_space_dim) {
484  throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)",
485  "cgs", cgs);
486  }
487 
488  const dimension_type cgs_num_rows = cgs.num_rows();
489  // If `cgs' is empty (of rows), fall back to ordinary widening.
490  if (cgs_num_rows == 0) {
491  x.widening_assign(y, tp);
492  return;
493  }
494 
495  // Assume `y' is contained in or equal to `x'.
496  PPL_EXPECT_HEAVY(copy_contains(x, y));
497 
498  if (y.marked_empty()) {
499  return;
500  }
501  if (x.marked_empty()) {
502  return;
503  }
504 
505  // The limited widening between two grids in a zero-dimensional
506  // space is also a grid in a zero-dimensional space.
507  if (x.space_dim == 0) {
508  return;
509  }
510 
511  // Update the generators of `x': these are used to select, from the
512  // congruences in `cgs', those that must be added to the widened
513  // grid.
514  if (!x.generators_are_up_to_date() && !x.update_generators()) {
515  // `x' is empty.
516  return;
517  }
518 
519  if (tp == NULL || *tp == 0) {
520  // Widening may change the grid, so add the congruences.
521  Congruence_System new_cgs;
522  // The congruences to be added need only be satisfied by all the
523  // generators of `x', as `y <= x'. Iterate upwards here, to keep
524  // the relative ordering of congruences (just for aesthetics).
525  for (dimension_type i = 0; i < cgs_num_rows; ++i) {
526  const Congruence& cg = cgs[i];
527  if (x.relation_with(cg) == Poly_Con_Relation::is_included()) {
528  new_cgs.insert(cg);
529  }
530  }
531  x.widening_assign(y, tp);
532  x.add_recycled_congruences(new_cgs);
533  }
534  else {
535  // There are tokens, so widening will leave the grid the same.
536  x.widening_assign(y, tp);
537  }
538 
539  PPL_ASSERT(OK());
540 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void Parma_Polyhedra_Library::Grid::limited_generator_extrapolation_assign ( const Grid y,
const Congruence_System cgs,
unsigned *  tp = NULL 
)

Improves the result of the generator variant of the Grid widening computation by also enforcing those congruences in cgs that are satisfied by all the points of *this.

Parameters
yA grid that must be contained in *this;
cgsThe system of congruences used to improve the widened grid;
tpAn optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique).
Exceptions
std::invalid_argumentThrown if *this, y and cgs are dimension-incompatible.

Definition at line 369 of file Grid_widenings.cc.

References add_recycled_congruences(), generator_widening_assign(), generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), marked_empty(), Parma_Polyhedra_Library::Congruence_System::num_rows(), relation_with(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), and update_generators().

371  {
372  Grid& x = *this;
373 
374  // Check dimension compatibility.
375  if (x.space_dim != y.space_dim) {
376  throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)",
377  "y", y);
378  }
379  // `cgs' must be dimension-compatible with the two grids.
380  const dimension_type cgs_space_dim = cgs.space_dimension();
381  if (x.space_dim < cgs_space_dim) {
382  throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)",
383  "cgs", cgs);
384  }
385 
386  const dimension_type cgs_num_rows = cgs.num_rows();
387  // If `cgs' is empty (of rows), fall back to ordinary widening.
388  if (cgs_num_rows == 0) {
389  x.generator_widening_assign(y, tp);
390  return;
391  }
392 
393  // Assume `y' is contained in or equal to `x'.
394  PPL_EXPECT_HEAVY(copy_contains(x, y));
395 
396  if (y.marked_empty()) {
397  return;
398  }
399  if (x.marked_empty()) {
400  return;
401  }
402 
403  // The limited widening between two grids in a zero-dimensional
404  // space is also a grid in a zero-dimensional space.
405  if (x.space_dim == 0) {
406  return;
407  }
408 
409  // Update the generators of `x': these are used to select, from the
410  // congruences in `cgs', those that must be added to the widened
411  // grid.
412  if (!x.generators_are_up_to_date() && !x.update_generators()) {
413  // `x' is empty.
414  return;
415  }
416 
417  if (tp == NULL || *tp == 0) {
418  // Widening may change the grid, so add the congruences.
419  Congruence_System new_cgs;
420  // The congruences to be added need only be satisfied by all the
421  // generators of `x', as `y <= x'. Iterate upwards here, to keep
422  // the relative ordering of congruences (just for aesthetics).
423  for (dimension_type i = 0; i < cgs_num_rows; ++i) {
424  const Congruence& cg = cgs[i];
425  if (x.relation_with(cg) == Poly_Con_Relation::is_included()) {
426  new_cgs.insert(cg);
427  }
428  }
429  x.generator_widening_assign(y, tp);
430  x.add_recycled_congruences(new_cgs);
431  }
432  else {
433  // There are tokens, so widening will leave the grid the same.
434  x.generator_widening_assign(y, tp);
435  }
436 
437  PPL_ASSERT(OK());
438 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
bool Parma_Polyhedra_Library::Grid::lower_triangular ( const Congruence_System sys,
const Dimension_Kinds dim_kinds 
)
staticprivate

If sys is lower triangular return true, else return false.

Definition at line 37 of file Grid_conversion.cc.

References Parma_Polyhedra_Library::Linear_Expression::all_zeroes(), CON_VIRTUAL, Parma_Polyhedra_Library::Congruence::expr, Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Congruence_System::num_rows(), and Parma_Polyhedra_Library::Congruence_System::space_dimension().

Referenced by conversion().

38  {
39  const dimension_type num_columns = sys.space_dimension() + 1;
40 
41  // Check for easy square failure case.
42  if (sys.num_rows() > num_columns) {
43  return false;
44  }
45 
46  // Check triangularity.
47 
48  dimension_type row = 0;
49  for (dimension_type dim = num_columns; dim-- > 0; ) {
50  if (dim_kinds[dim] == CON_VIRTUAL) {
51  continue;
52  }
53  const Congruence& cg = sys[row];
54  ++row;
55  // Check diagonal.
56  if (cg.expr.get(dim) <= 0) {
57  return false;
58  }
59  if (!cg.expr.all_zeroes(dim + 1, num_columns)) {
60  return false;
61  }
62  }
63 
64  // Check squareness.
65  return row == sys.num_rows();
66 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void Parma_Polyhedra_Library::Grid::m_swap ( Grid y)
inline

Swaps *this with grid y. (*this and y can be dimension-incompatible.)

Definition at line 249 of file Grid_inlines.hh.

References con_sys, dim_kinds, gen_sys, space_dim, status, swap(), and Parma_Polyhedra_Library::swap().

Referenced by Parma_Polyhedra_Library::Affine_Space::Affine_Space(), congruence_widening_assign(), generator_widening_assign(), map_space_dimensions(), simplify_using_context_assign(), and swap().

249  {
250  using std::swap;
251  swap(con_sys, y.con_sys);
252  swap(gen_sys, y.gen_sys);
253  swap(status, y.status);
254  swap(space_dim, y.space_dim);
255  swap(dim_kinds, y.dim_kinds);
256 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void swap(CO_Tree &x, CO_Tree &y)
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void swap(Grid &x, Grid &y)
Swaps x with y.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
template<typename Partial_Function >
void Parma_Polyhedra_Library::Grid::map_space_dimensions ( const Partial_Function pfunc)

Remaps the dimensions of the vector space according to a partial function.

If pfunc maps only some of the dimensions of *this then the rest will be projected away.

If the highest dimension mapped to by pfunc is higher than the highest dimension in *this then the number of dimensions in this will be increased to the highest dimension mapped to by pfunc.

Parameters
pfuncThe partial function specifying the destiny of each space dimension.

The template type parameter Partial_Function must provide the following methods.

bool has_empty_codomain() const

returns true if and only if the represented partial function has an empty codomain (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

returns the maximum value that belongs to the codomain of the partial function. The max_in_codomain() method is called at most once.

bool maps(dimension_type i, dimension_type& j) const

Let $f$ be the represented function and $k$ be the value of i. If $f$ is defined in $k$, then $f(k)$ is assigned to j and true is returned. If $f$ is undefined in $k$, then false is returned. This method is called at most $n$ times, where $n$ is the dimension of the vector space enclosing the grid.

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 119 of file Grid_templates.hh.

References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::Expression_Adapter< T >::begin(), Parma_Polyhedra_Library::Grid_Generator_System::begin(), clear_congruences_minimized(), clear_generators_minimized(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::EMPTY, Parma_Polyhedra_Library::Expression_Hide_Last< T >::end(), Parma_Polyhedra_Library::Grid_Generator_System::end(), Parma_Polyhedra_Library::Grid_Generator::expression(), gen_sys, generators_are_up_to_date(), grid_generators(), Parma_Polyhedra_Library::Partial_Function::has_empty_codomain(), Parma_Polyhedra_Library::Grid_Generator_System::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Grid_Generator::is_point(), Parma_Polyhedra_Library::Grid_Generator::LINE, m_swap(), Parma_Polyhedra_Library::Partial_Function::maps(), marked_empty(), Parma_Polyhedra_Library::Partial_Function::max_in_codomain(), Parma_Polyhedra_Library::not_a_dimension(), OK(), Parma_Polyhedra_Library::Grid_Generator::PARAMETER, Parma_Polyhedra_Library::Congruence_System::permute_space_dimensions(), Parma_Polyhedra_Library::Grid_Generator_System::permute_space_dimensions(), Parma_Polyhedra_Library::Grid_Generator::POINT, set_empty(), Parma_Polyhedra_Library::Grid_Generator_System::set_sorted(), Parma_Polyhedra_Library::Linear_Expression::set_space_dimension(), set_zero_dim_univ(), space_dim, throw_invalid_argument(), Parma_Polyhedra_Library::Grid_Generator::type(), and update_generators().

119  {
120  if (space_dim == 0) {
121  return;
122  }
123 
124  if (pfunc.has_empty_codomain()) {
125  // All dimensions vanish: the grid becomes zero_dimensional.
126  if (marked_empty()
128  // Removing all dimensions from the empty grid.
129  space_dim = 0;
130  set_empty();
131  }
132  else {
133  // Removing all dimensions from a non-empty grid.
135  }
136 
137  PPL_ASSERT(OK());
138  return;
139  }
140 
141  dimension_type new_space_dimension = pfunc.max_in_codomain() + 1;
142 
143  if (new_space_dimension == space_dim) {
144  // The partial function `pfunc' is indeed total and thus specifies
145  // a permutation, that is, a renaming of the dimensions. For
146  // maximum efficiency, we will simply permute the columns of the
147  // constraint system and/or the generator system.
148 
149  std::vector<Variable> cycle;
150  cycle.reserve(space_dim);
151 
152  // Used to mark elements as soon as they are inserted in a cycle.
153  std::deque<bool> visited(space_dim);
154 
155  for (dimension_type i = space_dim; i-- > 0; ) {
156  if (!visited[i]) {
157  dimension_type j = i;
158  do {
159  visited[j] = true;
160  // The following initialization is only to make the compiler happy.
161  dimension_type k = 0;
162  if (!pfunc.maps(j, k)) {
163  throw_invalid_argument("map_space_dimensions(pfunc)",
164  " pfunc is inconsistent");
165  }
166  if (k == j) {
167  break;
168  }
169 
170  cycle.push_back(Variable(j));
171  // Go along the cycle.
172  j = k;
173  } while (!visited[j]);
174 
175  // End of cycle.
176 
177  // Avoid calling clear_*_minimized() if cycle.size() is less than 2,
178  // to improve efficiency.
179  if (cycle.size() >= 2) {
180  // Permute all that is up-to-date.
184  }
185 
189  }
190  }
191 
192  cycle.clear();
193  }
194  }
195 
196  PPL_ASSERT(OK());
197  return;
198  }
199 
200  // If control gets here, then `pfunc' is not a permutation and some
201  // dimensions must be projected away.
202 
203  const Grid_Generator_System& old_gensys = grid_generators();
204 
205  if (old_gensys.has_no_rows()) {
206  // The grid is empty.
207  Grid new_grid(new_space_dimension, EMPTY);
208  m_swap(new_grid);
209  PPL_ASSERT(OK());
210  return;
211  }
212 
213  // Make a local copy of the partial function.
214  std::vector<dimension_type> pfunc_maps(space_dim, not_a_dimension());
215  for (dimension_type j = space_dim; j-- > 0; ) {
216  dimension_type pfunc_j;
217  if (pfunc.maps(j, pfunc_j)) {
218  pfunc_maps[j] = pfunc_j;
219  }
220  }
221 
222  Grid_Generator_System new_gensys;
223  // Set sortedness, for the assertion met via gs::insert.
224  new_gensys.set_sorted(false);
225  // Get the divisor of the first point.
226  Grid_Generator_System::const_iterator i;
227  Grid_Generator_System::const_iterator old_gensys_end = old_gensys.end();
228  for (i = old_gensys.begin(); i != old_gensys_end; ++i) {
229  if (i->is_point()) {
230  break;
231  }
232  }
233  PPL_ASSERT(i != old_gensys_end);
234  const Coefficient& system_divisor = i->divisor();
235  for (i = old_gensys.begin(); i != old_gensys_end; ++i) {
236  const Grid_Generator& old_g = *i;
237  const Grid_Generator::expr_type old_g_e = old_g.expression();
238  Linear_Expression expr;
239  expr.set_space_dimension(new_space_dimension);
240  bool all_zeroes = true;
241  for (Grid_Generator::expr_type::const_iterator j = old_g_e.begin(),
242  j_end = old_g_e.end(); j != j_end; ++j) {
243  const dimension_type mapped_id = pfunc_maps[j.variable().id()];
244  if (mapped_id != not_a_dimension()) {
245  add_mul_assign(expr, *j, Variable(mapped_id));
246  all_zeroes = false;
247  }
248  }
249  switch (old_g.type()) {
251  if (!all_zeroes) {
252  new_gensys.insert(grid_line(expr));
253  }
254  break;
256  if (!all_zeroes) {
257  new_gensys.insert(parameter(expr, system_divisor));
258  }
259  break;
261  new_gensys.insert(grid_point(expr, old_g.divisor()));
262  break;
263  }
264  }
265 
266  Grid new_grid(new_gensys);
267  m_swap(new_grid);
268 
269  PPL_ASSERT(OK(true));
270 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
The empty element, i.e., the empty set.
void clear_congruences_minimized()
Sets status to express that congruences are no longer minimized.
Definition: Grid_inlines.hh:87
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void permute_space_dimensions(const std::vector< Variable > &cycle)
Permutes the space dimensions of the matrix.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
dimension_type not_a_dimension()
Returns a value that does not designate a valid dimension.
void add_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
Expression_Hide_Last< Expression_Hide_Inhomo< Linear_Expression > > expr_type
The type of the (adapted) internal expression.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
const Grid_Generator_System & grid_generators() const
Returns the system of generators.
Definition: Grid_public.cc:334
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
void permute_space_dimensions(const std::vector< Variable > &cycle)
Permutes the space dimensions of the system.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static void throw_invalid_argument(const char *method, const char *reason)
base_type::const_iterator const_iterator
The type of const iterators on coefficients.
void m_swap(Grid &y)
Swaps *this with grid y. (*this and y can be dimension-incompatible.)
bool update_generators() const
Updates and minimizes the generators from the congruences.
bool Parma_Polyhedra_Library::Grid::max_min ( const Linear_Expression expr,
const char *  method_call,
Coefficient ext_n,
Coefficient ext_d,
bool &  included,
Generator point = NULL 
) const
private

Maximizes or minimizes expr subject to *this.

Parameters
exprThe linear expression to be maximized or minimized subject to this;
method_callThe call description of the public parent method, for example "maximize(e)". Passed to throw_dimension_incompatible, as the first argument;
ext_nThe numerator of the extremum value;
ext_dThe denominator of the extremum value;
includedtrue if and only if the extremum of expr in this can actually be reached (which is always the case);
pointWhen maximization or minimization succeeds, will be assigned the point where expr reaches the extremum value.
Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

If *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 413 of file Grid_nonpublic.cc.

References dim_kinds, Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Grid_Generator::expression(), Parma_Polyhedra_Library::gcd_assign(), gen_sys, Parma_Polyhedra_Library::Scalar_Products::homogeneous_assign(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), Parma_Polyhedra_Library::Generator::point(), PPL_DIRTY_TEMP_COEFFICIENT, set_generators_minimized(), and simplify().

Referenced by maximize(), and minimize().

416  {
417  if (bounds(expr, method_call)) {
418  if (marked_empty()) {
419  return false;
420  }
421  if (space_dim == 0) {
422  ext_n = 0;
423  ext_d = 1;
424  included = true;
425  if (point != 0) {
426  *point = Generator::point();
427  }
428  return true;
429  }
430  // Grid::bounds above ensures the generators are up to date.
431  if (!generators_are_minimized()) {
432  // Minimize the generator system.
433  Grid& gr = const_cast<Grid&>(*this);
434  gr.simplify(gr.gen_sys, gr.dim_kinds);
435  gr.set_generators_minimized();
436  }
437 
438  const Grid_Generator& gen = gen_sys[0];
439  Scalar_Products::homogeneous_assign(ext_n, expr, gen);
440  ext_n += expr.inhomogeneous_term();
441  ext_d = gen.divisor();
442  // Reduce ext_n and ext_d.
444  gcd_assign(gcd, ext_n, ext_d);
445  exact_div_assign(ext_n, ext_n, gcd);
446  exact_div_assign(ext_d, ext_d, gcd);
447 
448  included = true;
449  if (point != 0) {
450  const Linear_Expression g_expr(gen.expression());
451  *point = Generator::point(g_expr, gen.divisor());
452  }
453  return true;
454  }
455  return false;
456 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
bool bounds(const Linear_Expression &expr, const char *method_call) const
Checks if and how expr is bounded in *this.
static Generator point(const Linear_Expression &e=Linear_Expression::zero(), Coefficient_traits::const_reference d=Coefficient_one(), Representation r=default_representation)
Returns the point at e / d.
Definition: Generator.cc:57
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static void homogeneous_assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the homogeneous scalar product of x and y, where the inhomogeneous terms are ignored...
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
dimension_type Parma_Polyhedra_Library::Grid::max_space_dimension ( )
inlinestatic

Returns the maximum space dimension all kinds of Grid can handle.

Definition at line 111 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Congruence_System::max_space_dimension(), and Parma_Polyhedra_Library::Grid_Generator_System::max_space_dimension().

Referenced by Grid(), Parma_Polyhedra_Library::max_space_dimension(), and Parma_Polyhedra_Library::Affine_Space::max_space_dimension().

111  {
112  // One dimension is reserved to have a value of type dimension_type
113  // that does not represent a legal dimension.
114  return std::min(std::numeric_limits<dimension_type>::max() - 1,
117  )
118  );
119 }
static dimension_type max_space_dimension()
Returns the maximum space dimension a Congruence_System can handle.
static dimension_type max_space_dimension()
Returns the maximum space dimension a Grid_Generator_System can handle.
bool Parma_Polyhedra_Library::Grid::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.

Parameters
exprThe linear expression to be maximized subject to *this;
sup_nThe numerator of the supremum value;
sup_dThe denominator of the supremum value;
maximumtrue if the supremum value can be reached in this. Always true when this bounds expr. Present for interface compatibility with class Polyhedron, where closure points can result in a value of false.
Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

If *this is empty or expr is not bounded by *this, false is returned and sup_n, sup_d and maximum are left untouched.

Definition at line 332 of file Grid_inlines.hh.

References max_min().

Referenced by Parma_Polyhedra_Library::Box< ITV >::Box(), and Parma_Polyhedra_Library::Affine_Space::maximize().

333  {
334  return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum);
335 }
bool max_min(const Linear_Expression &expr, const char *method_call, Coefficient &ext_n, Coefficient &ext_d, bool &included, Generator *point=NULL) const
Maximizes or minimizes expr subject to *this.
bool Parma_Polyhedra_Library::Grid::maximize ( const Linear_Expression expr,
Coefficient sup_n,
Coefficient sup_d,
bool &  maximum,
Generator point 
) 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.

Parameters
exprThe linear expression to be maximized subject to *this;
sup_nThe numerator of the supremum value;
sup_dThe denominator of the supremum value;
maximumtrue if the supremum value can be reached in this. Always true when this bounds expr. Present for interface compatibility with class Polyhedron, where closure points can result in a value of false;
pointWhen maximization succeeds, will be assigned a point where expr reaches its supremum value.
Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

If *this is empty or expr is not bounded by *this, false is returned and sup_n, sup_d, maximum and point are left untouched.

Definition at line 338 of file Grid_inlines.hh.

References max_min().

340  {
341  return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum, &point);
342 }
bool max_min(const Linear_Expression &expr, const char *method_call, Coefficient &ext_n, Coefficient &ext_d, bool &included, Generator *point=NULL) const
Maximizes or minimizes expr subject to *this.
bool Parma_Polyhedra_Library::Grid::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.

Parameters
exprThe linear expression to be minimized subject to *this;
inf_nThe numerator of the infimum value;
inf_dThe denominator of the infimum value;
minimumtrue if the is the infimum value can be reached in this. Always true when this bounds expr. Present for interface compatibility with class Polyhedron, where closure points can result in a value of false.
Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

If *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 345 of file Grid_inlines.hh.

References max_min().

Referenced by is_included_in(), Parma_Polyhedra_Library::Affine_Space::minimize(), and simplify_using_context_assign().

346  {
347  return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum);
348 }
bool max_min(const Linear_Expression &expr, const char *method_call, Coefficient &ext_n, Coefficient &ext_d, bool &included, Generator *point=NULL) const
Maximizes or minimizes expr subject to *this.
bool Parma_Polyhedra_Library::Grid::minimize ( const Linear_Expression expr,
Coefficient inf_n,
Coefficient inf_d,
bool &  minimum,
Generator point 
) 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.

Parameters
exprThe linear expression to be minimized subject to *this;
inf_nThe numerator of the infimum value;
inf_dThe denominator of the infimum value;
minimumtrue if the is the infimum value can be reached in this. Always true when this bounds expr. Present for interface compatibility with class Polyhedron, where closure points can result in a value of false;
pointWhen minimization succeeds, will be assigned a point where expr reaches its infimum value.
Exceptions
std::invalid_argumentThrown if expr and *this are dimension-incompatible.

If *this is empty or expr is not bounded from below, false is returned and inf_n, inf_d, minimum and point are left untouched.

Definition at line 351 of file Grid_inlines.hh.

References max_min().

353  {
354  return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum, &point);
355 }
bool max_min(const Linear_Expression &expr, const char *method_call, Coefficient &ext_n, Coefficient &ext_d, bool &included, Generator *point=NULL) const
Maximizes or minimizes expr subject to *this.
bool Parma_Polyhedra_Library::Grid::minimize ( ) const
private

Minimizes both the congruences and the generators.

Returns
false if and only if *this turns out to be an empty grid.

Minimization is performed on each system only if the minimized Status field is clear.

Definition at line 536 of file Grid_nonpublic.cc.

References con_sys, dim_kinds, Parma_Polyhedra_Library::Implementation::BD_Shapes::empty, gen_sys, set_congruences_minimized(), set_generators_minimized(), and simplify().

536  {
537  // 0-dimension and empty grids are already minimized.
538  if (marked_empty()) {
539  return false;
540  }
541  if (space_dim == 0) {
542  return true;
543  }
544  // Are both systems already minimized?
546  return true;
547  }
548  // Invoke update_generators, update_congruences or simplify,
549  // depending on the state of the systems.
552  Grid& gr = const_cast<Grid&>(*this);
553  // Only one of the systems can be minimized here.
555  // Minimize the generator system.
556  gr.simplify(gr.gen_sys, gr.dim_kinds);
557  gr.set_generators_minimized();
558  }
559  else {
560 #ifndef NDEBUG
561  // Both systems are up to date, and the empty case is handled
562  // above, so the grid should contain points.
563  bool empty = simplify(gr.con_sys, gr.dim_kinds);
564  PPL_ASSERT(!empty);
565 #else
566  simplify(gr.con_sys, gr.dim_kinds);
567 #endif
568  gr.set_congruences_minimized();
569  if (!generators_are_minimized()) {
570  // Minimize the generator system.
571  gr.simplify(gr.gen_sys, gr.dim_kinds);
572  gr.set_generators_minimized();
573  }
574  }
575  }
576  else {
577  // Updating the generators may reveal that `*this' is empty.
578  const bool ret = update_generators();
579  PPL_ASSERT(OK());
580  return ret;
581  }
582  }
583  else {
584  PPL_ASSERT(generators_are_up_to_date());
586  }
587  PPL_ASSERT(OK());
588  return true;
589 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
static bool simplify(Congruence_System &cgs, Dimension_Kinds &dim_kinds)
Converts cgs to upper triangular (i.e. minimized) form.
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
void update_congruences() const
Updates and minimizes the congruences from the generators.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool update_generators() const
Updates and minimizes the generators from the congruences.
const PPL::Congruence_System & Parma_Polyhedra_Library::Grid::minimized_congruences ( ) const

Returns the system of congruences in minimal form.

Definition at line 319 of file Grid_public.cc.

References con_sys, dim_kinds, set_congruences_minimized(), set_empty(), and simplify().

Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PSET >::approximate_partition(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::Partially_Reduced_Product< D1, D2, R >::minimized_congruences(), minimized_constraints(), Parma_Polyhedra_Library::Octagonal_Shape< T >::Octagonal_Shape(), and operator<<().

319  {
321  // Minimize the congruences.
322  Grid& gr = const_cast<Grid&>(*this);
323  if (gr.simplify(gr.con_sys, gr.dim_kinds)) {
324  gr.set_empty();
325  }
326  else {
327  gr.set_congruences_minimized();
328  }
329  }
330  return congruences();
331 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
const Congruence_System & congruences() const
Returns the system of congruences.
Definition: Grid_public.cc:300
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
Constraint_System Parma_Polyhedra_Library::Grid::minimized_constraints ( ) const
inline

Returns a minimal system of equality constraints satisfied by *this with the same affine dimension as *this.

Definition at line 244 of file Grid_inlines.hh.

References minimized_congruences().

Referenced by Parma_Polyhedra_Library::Affine_Space::minimized_constraints().

244  {
245  return Constraint_System(minimized_congruences());
246 }
const Congruence_System & minimized_congruences() const
Returns the system of congruences in minimal form.
Definition: Grid_public.cc:319
const PPL::Grid_Generator_System & Parma_Polyhedra_Library::Grid::minimized_grid_generators ( ) const

Returns the minimized system of generators.

Definition at line 356 of file Grid_public.cc.

References dim_kinds, gen_sys, set_empty(), set_generators_minimized(), and simplify().

356  {
357  if (space_dim == 0) {
358  PPL_ASSERT(gen_sys.space_dimension() == 0
359  && gen_sys.num_rows() == (marked_empty() ? 0U : 1U));
360  return gen_sys;
361  }
362 
363  if (marked_empty()) {
364  PPL_ASSERT(gen_sys.has_no_rows());
365  return gen_sys;
366  }
367 
369  if (!generators_are_minimized()) {
370  // Minimize the generators.
371  Grid& gr = const_cast<Grid&>(*this);
372  gr.simplify(gr.gen_sys, gr.dim_kinds);
373  gr.set_generators_minimized();
374  }
375  }
376  else if (!update_generators()) {
377  // Updating found the grid empty.
378  const_cast<Grid&>(*this).set_empty();
379  return gen_sys;
380  }
381 
382  return gen_sys;
383 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool update_generators() const
Updates and minimizes the generators from the congruences.
void Parma_Polyhedra_Library::Grid::multiply_grid ( const Coefficient multiplier,
Congruence cg,
Swapping_Vector< Congruence > &  dest,
dimension_type  num_rows 
)
staticprivate

Multiply the elements of dest by multiplier.

Definition at line 132 of file Grid_conversion.cc.

References Parma_Polyhedra_Library::Congruence::is_equality(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), and Parma_Polyhedra_Library::Congruence::scale().

Referenced by conversion().

134  {
135  if (multiplier == 1) {
136  return;
137  }
138 
139  if (cg.is_proper_congruence()) {
140  // Multiply every element of every congruence.
141  for (dimension_type index = num_rows; index-- > 0; ) {
142  Congruence& congruence = dest[index];
143  if (congruence.is_proper_congruence()) {
144  congruence.scale(multiplier);
145  }
146  }
147  }
148  else {
149  PPL_ASSERT(cg.is_equality());
150  // Multiply every element of the equality.
151  cg.scale(multiplier);
152  }
153 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void Parma_Polyhedra_Library::Grid::multiply_grid ( const Coefficient multiplier,
Grid_Generator gen,
Swapping_Vector< Grid_Generator > &  dest,
dimension_type  num_rows 
)
staticprivate

Multiply the elements of dest by multiplier.

Definition at line 107 of file Grid_conversion.cc.

References Parma_Polyhedra_Library::Grid_Generator::expr, Parma_Polyhedra_Library::Grid_Generator::is_line(), and Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point().

109  {
110  if (multiplier == 1) {
111  return;
112  }
113 
114  if (gen.is_line()) {
115  // Multiply every element of the line.
116  gen.expr *= multiplier;
117  }
118  else {
119  PPL_ASSERT(gen.is_parameter_or_point());
120  // Multiply every element of every parameter.
121 
122  for (dimension_type index = num_rows; index-- > 0; ) {
123  Grid_Generator& generator = dest_rows[index];
124  if (generator.is_parameter_or_point()) {
125  generator.expr *= multiplier;
126  }
127  }
128  }
129 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void Parma_Polyhedra_Library::Grid::normalize_divisors ( Grid_Generator_System sys,
Coefficient divisor,
const Grid_Generator first_point = NULL 
)
staticprivate

Normalizes the divisors in sys.

Converts sys to an equivalent system in which the divisors are of equal value.

Parameters
sysThe generator system to be normalized. It must have at least one row.
divisorA reference to the initial value of the divisor. The resulting value of this object is the new system divisor.
first_pointIf first_point has a value other than NULL then it is taken as the first point in sys, and it is assumed that any following points have the same divisor as first_point.

Definition at line 634 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), Parma_Polyhedra_Library::lcm_assign(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and Parma_Polyhedra_Library::Grid_Generator_System::sys.

Referenced by normalize_divisors().

636  {
637  PPL_ASSERT(divisor >= 0);
638  if (sys.space_dimension() > 0 && divisor > 0) {
639  const dimension_type num_rows = sys.num_rows();
640 
641  if (first_point != 0) {
642  lcm_assign(divisor, divisor, (*first_point).divisor());
643  }
644  else {
645  PPL_ASSERT(num_rows > 0);
646  // Move to the first point or parameter.
647  dimension_type row = 0;
648  while (sys[row].is_line()) {
649  if (++row == num_rows) {
650  // All rows are lines.
651  return;
652  }
653  }
654 
655  // Calculate the LCM of the given divisor and the divisor of
656  // every point or parameter.
657  while (row < num_rows) {
658  const Grid_Generator& g = sys[row];
659  if (g.is_parameter_or_point()) {
660  lcm_assign(divisor, divisor, g.divisor());
661  }
662  ++row;
663  }
664  }
665 
666  // Represent every point and every parameter using the newly
667  // calculated divisor.
668  for (dimension_type i = num_rows; i-- > 0; ) {
669  sys.sys.rows[i].scale_to_divisor(divisor);
670  }
671 
672  // Put the rows back into the linear system.
673  PPL_ASSERT(sys.sys.OK());
674  }
675 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void lcm_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void Parma_Polyhedra_Library::Grid::normalize_divisors ( Grid_Generator_System sys)
inlinestaticprivate

Normalizes the divisors in sys.

Converts sys to an equivalent system in which the divisors are of equal value.

Parameters
sysThe generator system to be normalized. It must have at least one row.

Definition at line 358 of file Grid_inlines.hh.

References normalize_divisors(), and PPL_DIRTY_TEMP_COEFFICIENT.

358  {
360  divisor = 1;
361  normalize_divisors(sys, divisor);
362 }
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void Parma_Polyhedra_Library::Grid::normalize_divisors ( Grid_Generator_System sys,
Grid_Generator_System gen_sys 
)
staticprivate

Normalize all the divisors in sys and gen_sys.

Modify sys and gen_sys to use the same single divisor value for all generators, leaving each system representing the grid it represented originally.

Parameters
sysThe first of the generator systems to be normalized.
gen_sysThe second of the generator systems to be normalized. This system must have at least one row and the divisors of the generators in this system must be equal.
Exceptions
std::runtime_errorThrown if all rows in gen_sys are lines and/or parameters.

Definition at line 592 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), and PPL_DIRTY_TEMP_COEFFICIENT.

593  {
594 #ifndef NDEBUG
595  const dimension_type num_rows = gen_sys.num_rows();
596 #endif
597  PPL_ASSERT(num_rows > 0);
598 
599  // Find the first point in gen_sys.
600  dimension_type row = 0;
601  while (gen_sys[row].is_line_or_parameter()) {
602  ++row;
603  // gen_sys should have at least one point.
604  PPL_ASSERT(row < num_rows);
605  }
606  const Grid_Generator& first_point = gen_sys[row];
607  const Coefficient& gen_sys_divisor = first_point.divisor();
608 
609 #ifndef NDEBUG
610  // Check that the divisors in gen_sys are equal.
611  for (dimension_type i = row + 1; i < num_rows; ++i) {
612  const Grid_Generator& g = gen_sys[i];
613  if (g.is_parameter_or_point()) {
614  PPL_ASSERT(gen_sys_divisor == g.divisor());
615  }
616  }
617 #endif // !defined(NDEBUG)
618 
620  divisor = gen_sys_divisor;
621  // Adjust sys to include the gen_sys divisor.
622  normalize_divisors(sys, divisor);
623  if (divisor != gen_sys_divisor) {
624  // Adjust gen_sys to use the new divisor.
625  //
626  // The points and parameters in gen_sys share a common divisor
627  // value, so the new divisor will be the LCM of this common
628  // divisor and `divisor', hence the third argument.
629  normalize_divisors(gen_sys, divisor, &first_point);
630  }
631 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
bool Parma_Polyhedra_Library::Grid::OK ( bool  check_not_empty = false) const

Checks if all the invariants are satisfied.

Returns
true if and only if *this satisfies all the invariants and either check_not_empty is false or *this is not empty.
Parameters
check_not_emptytrue if and only if, in addition to checking the invariants, *this must be checked to be not empty.

The check is performed so as to intrude as little as possible. If the library has been compiled with run-time assertions enabled, error messages are written on std::cerr in case invariants are violated. This is useful for the purpose of debugging the library.

Definition at line 958 of file Grid_public.cc.

References Parma_Polyhedra_Library::ascii_dump(), Parma_Polyhedra_Library::Congruence_System::ascii_dump(), Parma_Polyhedra_Library::Grid_Generator_System::ascii_dump(), Parma_Polyhedra_Library::Grid_Generator::ascii_dump(), clear_generators_up_to_date(), con_sys, gen_sys, Parma_Polyhedra_Library::Grid_Generator_System::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator::is_equal_to(), Parma_Polyhedra_Library::Grid_Generator_System::m_swap(), and update_generators().

Referenced by congruence_widening_assign(), construct(), conversion(), generator_widening_assign(), Grid(), intersection_assign(), is_included_in(), map_space_dimensions(), simplify_using_context_assign(), time_elapse_assign(), and upper_bound_assign().

958  {
959 #ifndef NDEBUG
960  using std::endl;
961  using std::cerr;
962 #endif
963 
964  // Check whether the status information is legal.
965  if (!status.OK()) {
966  goto fail;
967  }
968 
969  if (marked_empty()) {
970  if (check_not_empty) {
971  // The caller does not want the grid to be empty.
972 #ifndef NDEBUG
973  cerr << "Empty grid!" << endl;
974 #endif
975  goto fail;
976  }
977 
978  if (con_sys.space_dimension() != space_dim) {
979 #ifndef NDEBUG
980  cerr << "The grid is in a space of dimension " << space_dim
981  << " while the system of congruences is in a space of dimension "
983  << endl;
984 #endif
985  goto fail;
986  }
987  return true;
988  }
989 
990  // A zero-dimensional universe grid is legal only if the system of
991  // congruences `con_sys' is empty, and the generator system contains
992  // one point.
993  if (space_dim == 0) {
994  if (con_sys.has_no_rows()) {
995  if (gen_sys.num_rows() == 1 && gen_sys[0].is_point()) {
996  return true;
997  }
998  }
999 #ifndef NDEBUG
1000  cerr << "Zero-dimensional grid should have an empty congruence" << endl
1001  << "system and a generator system of a single point." << endl;
1002 #endif
1003  goto fail;
1004  }
1005 
1006  // A grid is defined by a system of congruences or a system of
1007  // generators. At least one of them must be up to date.
1009 #ifndef NDEBUG
1010  cerr << "Grid not empty, not zero-dimensional" << endl
1011  << "and with neither congruences nor generators up-to-date!"
1012  << endl;
1013 #endif
1014  goto fail;
1015  }
1016 
1017  {
1018  // The expected number of columns in the congruence and generator
1019  // systems, if they are not empty.
1020  const dimension_type num_columns = space_dim + 1;
1021 
1022  // Here we check if the size of the matrices is consistent.
1023  // Let us suppose that all the matrices are up-to-date; this means:
1024  // `con_sys' : number of congruences x poly_num_columns
1025  // `gen_sys' : number of generators x poly_num_columns
1027  if (con_sys.space_dimension() != space_dim) {
1028 #ifndef NDEBUG
1029  cerr << "Incompatible size! (con_sys and space_dim)"
1030  << endl;
1031 #endif
1032  goto fail;
1033  }
1034  }
1035  if (generators_are_up_to_date()) {
1036  if (gen_sys.space_dimension() != space_dim) {
1037 #ifndef NDEBUG
1038  cerr << "Incompatible size! (gen_sys and space_dim)"
1039  << endl;
1040 #endif
1041  goto fail;
1042  }
1043 
1044  // A non-empty system of generators describing a grid is valid
1045  // if and only if it contains a point.
1046  if (!gen_sys.has_no_rows() && !gen_sys.has_points()) {
1047 #ifndef NDEBUG
1048  cerr << "Non-empty generator system declared up-to-date "
1049  << "has no points!"
1050  << endl;
1051 #endif
1052  goto fail;
1053  }
1054 
1055  if (generators_are_minimized()) {
1056  Grid_Generator_System gs = gen_sys;
1057 
1058  if (dim_kinds.size() != num_columns) {
1059 #ifndef NDEBUG
1060  cerr << "Size of dim_kinds should equal the number of columns."
1061  << endl;
1062 #endif
1063  goto fail;
1064  }
1065 
1066  if (!upper_triangular(gs, dim_kinds)) {
1067 #ifndef NDEBUG
1068  cerr << "Reduced generators should be upper triangular."
1069  << endl;
1070 #endif
1071  goto fail;
1072  }
1073 
1074  // Check that dim_kinds corresponds to the row kinds in gen_sys.
1075  for (dimension_type dim = space_dim,
1076  row = gen_sys.num_rows(); dim > 0; --dim) {
1077  if (dim_kinds[dim] == GEN_VIRTUAL) {
1078  goto ok;
1079  }
1080  if (gen_sys[--row].is_parameter_or_point()
1081  && dim_kinds[dim] == PARAMETER) {
1082  goto ok;
1083  }
1084  PPL_ASSERT(gen_sys[row].is_line());
1085  if (dim_kinds[dim] == LINE) {
1086  goto ok;
1087  }
1088 #ifndef NDEBUG
1089  cerr << "Kinds in dim_kinds should match those in gen_sys."
1090  << endl;
1091 #endif
1092  goto fail;
1093  ok:
1094  PPL_ASSERT(row <= dim);
1095  }
1096 
1097  // A reduced generator system must be the same as a temporary
1098  // reduced copy.
1099  Dimension_Kinds dim_kinds_copy = dim_kinds;
1100  // `gs' is minimized and marked_empty returned false, so `gs'
1101  // should contain rows.
1102  PPL_ASSERT(!gs.has_no_rows());
1103  simplify(gs, dim_kinds_copy);
1104  // gs contained rows before being reduced, so it should
1105  // contain at least a single point afterward.
1106  PPL_ASSERT(!gs.has_no_rows());
1107  for (dimension_type row = gen_sys.num_rows(); row-- > 0; ) {
1108  const Grid_Generator& g = gs[row];
1109  const Grid_Generator& g_copy = gen_sys[row];
1110  if (g.is_equal_to(g_copy)) {
1111  continue;
1112  }
1113 #ifndef NDEBUG
1114  cerr << "Generators are declared minimized,"
1115  " but they change under reduction.\n"
1116  << "Here is the generator system:\n";
1117  gen_sys.ascii_dump(cerr);
1118  cerr << "and here is the minimized form of the temporary copy:\n";
1119  gs.ascii_dump(cerr);
1120 #endif
1121  goto fail;
1122  }
1123  }
1124 
1125  } // if (congruences_are_up_to_date())
1126  }
1127 
1129  // Check if the system of congruences is well-formed.
1130  if (!con_sys.OK()) {
1131  goto fail;
1132  }
1133 
1134  Grid tmp_gr = *this;
1135  // Make a copy here, before changing tmp_gr, to check later.
1136  const Congruence_System cs_copy = tmp_gr.con_sys;
1137 
1138  // Clear the generators in tmp_gr.
1139  Grid_Generator_System gs(space_dim);
1140  tmp_gr.gen_sys.m_swap(gs);
1141  tmp_gr.clear_generators_up_to_date();
1142 
1143  if (!tmp_gr.update_generators()) {
1144  if (check_not_empty) {
1145  // Want to know the satisfiability of the congruences.
1146 #ifndef NDEBUG
1147  cerr << "Unsatisfiable system of congruences!"
1148  << endl;
1149 #endif
1150  goto fail;
1151  }
1152  // The grid is empty, all checks are done.
1153  return true;
1154  }
1155 
1156  if (congruences_are_minimized()) {
1157  // A reduced congruence system must be lower triangular.
1159 #ifndef NDEBUG
1160  cerr << "Reduced congruences should be lower triangular." << endl;
1161 #endif
1162  goto fail;
1163  }
1164 
1165  // If the congruences are minimized, all the elements in the
1166  // congruence system must be the same as those in the temporary,
1167  // minimized system `cs_copy'.
1168  if (!con_sys.is_equal_to(cs_copy)) {
1169 #ifndef NDEBUG
1170  cerr << "Congruences are declared minimized, but they change under reduction!"
1171  << endl
1172  << "Here is the minimized form of the congruence system:"
1173  << endl;
1174  cs_copy.ascii_dump(cerr);
1175  cerr << endl;
1176 #endif
1177  goto fail;
1178  }
1179 
1180  if (dim_kinds.size() != con_sys.space_dimension() + 1 /* inhomogeneous term */) {
1181 #ifndef NDEBUG
1182  cerr << "Size of dim_kinds should equal the number of columns."
1183  << endl;
1184 #endif
1185  goto fail;
1186  }
1187 
1188  // Check that dim_kinds corresponds to the row kinds in con_sys.
1189  for (dimension_type dim = space_dim, row = 0; dim > 0; --dim) {
1190  if (dim_kinds[dim] == CON_VIRTUAL) {
1191  continue;
1192  }
1193  if (con_sys[row++].is_proper_congruence()
1194  && dim_kinds[dim] == PROPER_CONGRUENCE) {
1195  continue;
1196  }
1197  PPL_ASSERT(con_sys[row-1].is_equality());
1198  if (dim_kinds[dim] == EQUALITY) {
1199  continue;
1200  }
1201 #ifndef NDEBUG
1202  cerr << "Kinds in dim_kinds should match those in con_sys." << endl;
1203 #endif
1204  goto fail;
1205  }
1206  }
1207  }
1208 
1209  return true;
1210 
1211  fail:
1212 #ifndef NDEBUG
1213  cerr << "Here is the grid under check:" << endl;
1214  ascii_dump(cerr);
1215 #endif
1216  return false;
1217 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
bool OK() const
Checks if all the invariants are satisfied.
Definition: Grid_Status.cc:194
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool has_points() const
Returns true if and only if *this contains one or more points.
static bool simplify(Congruence_System &cgs, Dimension_Kinds &dim_kinds)
Converts cgs to upper triangular (i.e. minimized) form.
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
std::vector< Dimension_Kind > Dimension_Kinds
Definition: Grid_defs.hh:1994
bool OK() const
Checks if all the invariants are satisfied.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
static bool upper_triangular(const Grid_Generator_System &sys, const Dimension_Kinds &dim_kinds)
If sys is upper triangular return true, else return false.
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool is_equal_to(const Congruence_System &y) const
Returns true if and only if *this is exactly equal to y.
static bool lower_triangular(const Congruence_System &sys, const Dimension_Kinds &dim_kinds)
If sys is lower triangular return true, else return false.
bool has_no_rows() const
Returns true if num_rows()==0.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
PPL::Grid & Parma_Polyhedra_Library::Grid::operator= ( const Grid y)

The assignment operator. (*this and y can be dimension-incompatible.)

Definition at line 251 of file Grid_public.cc.

References con_sys, congruences_are_up_to_date(), dim_kinds, gen_sys, generators_are_up_to_date(), marked_empty(), space_dim, and status.

251  {
252  space_dim = y.space_dim;
253  dim_kinds = y.dim_kinds;
254  if (y.marked_empty()) {
255  set_empty();
256  }
257  else if (space_dim == 0) {
259  }
260  else {
261  status = y.status;
262  if (y.congruences_are_up_to_date()) {
263  con_sys = y.con_sys;
264  }
265  if (y.generators_are_up_to_date()) {
266  gen_sys = y.gen_sys;
267  }
268  }
269  return *this;
270 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void Parma_Polyhedra_Library::Grid::print ( ) const

Prints *this to std::cerr using operator<<.

PPL::Grid::Three_Valued_Boolean Parma_Polyhedra_Library::Grid::quick_equivalence_test ( const Grid y) const
private

Polynomial but incomplete equivalence test between grids.

Definition at line 182 of file Grid_nonpublic.cc.

References con_sys, congruences_are_minimized(), gen_sys, generators_are_minimized(), marked_empty(), Parma_Polyhedra_Library::Congruence_System::num_equalities(), Parma_Polyhedra_Library::Grid_Generator_System::num_lines(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), Parma_Polyhedra_Library::Congruence_System::num_rows(), space_dim, TVB_DONT_KNOW, TVB_FALSE, and TVB_TRUE.

Referenced by contains(), and operator==().

182  {
183  // Private method: the caller must ensure the following.
184  PPL_ASSERT(space_dim == y.space_dim);
185  PPL_ASSERT(!marked_empty() && !y.marked_empty() && space_dim > 0);
186 
187  const Grid& x = *this;
188 
189  bool css_normalized = false;
190 
191  if (x.congruences_are_minimized() && y.congruences_are_minimized()) {
192  // Equivalent minimized congruence systems have:
193  // - the same number of congruences; ...
194  if (x.con_sys.num_rows() != y.con_sys.num_rows()) {
195  return Grid::TVB_FALSE;
196  }
197  // - the same number of equalities; ...
198  const dimension_type x_num_equalities = x.con_sys.num_equalities();
199  if (x_num_equalities != y.con_sys.num_equalities()) {
200  return Grid::TVB_FALSE;
201  }
202  // - and if there are no equalities, the same congruences.
203  // Delay this test: try cheaper tests on generators first.
204  css_normalized = (x_num_equalities == 0);
205  }
206 
207  if (x.generators_are_minimized() && y.generators_are_minimized()) {
208  // Equivalent minimized generator systems have:
209  // - the same number of generators; ...
210  if (x.gen_sys.num_rows() != y.gen_sys.num_rows()) {
211  return Grid::TVB_FALSE;
212  }
213  // - the same number of lines; ...
214  const dimension_type x_num_lines = x.gen_sys.num_lines();
215  if (x_num_lines != y.gen_sys.num_lines()) {
216  return Grid::TVB_FALSE;
217  }
218  // - and if there are no lines, the same generators.
219  if (x_num_lines == 0) {
220  // Check for syntactic identity.
221 
222  if (x.gen_sys == y.gen_sys) {
223  return Grid::TVB_TRUE;
224  }
225  else {
226  return Grid::TVB_FALSE;
227  }
228  }
229  }
230 
231  // TODO: Consider minimizing the systems and re-performing these
232  // checks.
233 
234  if (css_normalized) {
235  if (x.con_sys == y.con_sys) {
236  return Grid::TVB_TRUE;
237  }
238  else {
239  return Grid::TVB_FALSE;
240  }
241  }
242 
243  return Grid::TVB_DONT_KNOW;
244 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void Parma_Polyhedra_Library::Grid::reduce_congruence_with_equality ( Congruence row,
const Congruence pivot,
dimension_type  column,
Swapping_Vector< Congruence > &  sys 
)
staticprivate

Reduce row using pivot.

Use the equality pivot to change the representation of the congruence row such that element at index column of row is zero.

Definition at line 190 of file Grid_simplify.cc.

References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Congruence::expr, Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::neg_assign(), PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Congruence::scale(), Parma_Polyhedra_Library::Swapping_Vector< T >::size(), and Parma_Polyhedra_Library::sub_mul_assign().

Referenced by simplify().

193  {
194  // Very similar to reduce_parameter_with_line above. Any change
195  // here may be needed there too.
196  PPL_ASSERT(row.modulus() > 0 && pivot.modulus() == 0);
197 
198  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
199  Coefficient_traits::const_reference row_column = row.expr.get(column);
200 
201  // If the elements at `column' in row and pivot are the same, then
202  // just subtract `pivot' from `row'.
203  if (row_column == pivot_column) {
204  row.expr -= pivot.expr;
205  return;
206  }
207 
208  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
209  // Use reduced_row_col temporarily to hold the gcd.
210  gcd_assign(reduced_row_col, pivot_column, row_column);
211  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
212  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
213  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
214  // Ensure that `reduced_pivot_col' is positive, so that the modulus
215  // remains positive when multiplying the proper congruences below.
216  // It's safe to swap the signs as row[column] will still come out 0.
217  if (reduced_pivot_col < 0) {
218  neg_assign(reduced_pivot_col);
219  neg_assign(reduced_row_col);
220  }
221  // Multiply `row', including the modulus, by reduced_pivot_col. To
222  // keep all the moduli the same this requires multiplying all the
223  // other proper congruences in the same way.
224  for (dimension_type index = sys.size(); index-- > 0; ) {
225  Congruence& cg = sys[index];
226  if (cg.is_proper_congruence()) {
227  cg.scale(reduced_pivot_col);
228  }
229  }
230  // Subtract from row a multiple of pivot such that the result in
231  // row[column] is zero.
232  sub_mul_assign(row.expr, reduced_row_col, pivot.expr);
233  PPL_ASSERT(row.expr.get(column) == 0);
234 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
void neg_assign(GMP_Integer &x)
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void sub_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void Parma_Polyhedra_Library::Grid::reduce_equality_with_equality ( Congruence row,
const Congruence pivot,
dimension_type  column 
)
staticprivate

Reduces the equality row using the equality pivot.

Uses the equality pivot to change the representation of the equality row so that the element at index column of row is zero.

Definition at line 58 of file Grid_simplify.cc.

References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Congruence::expr, Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Linear_Expression::linear_combine(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::Congruence::OK(), and PPL_DIRTY_TEMP_COEFFICIENT.

Referenced by simplify().

60  {
61  // Assume two equalities.
62  PPL_ASSERT(row.modulus() == 0 && pivot.modulus() == 0);
63 
64  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
65  Coefficient_traits::const_reference row_column = row.expr.get(column);
66  PPL_ASSERT(pivot_column != 0);
67  PPL_ASSERT(row_column != 0);
68 
69  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
70  // Use reduced_row_col temporarily to hold the gcd.
71  gcd_assign(reduced_row_col, pivot_column, row_column);
72  // Store the reduced ratio between pivot[column] and row[column].
73  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
74  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
75  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
76  // Multiply row, then subtract from it a multiple of pivot such that
77  // the result in row[column] is zero.
78  neg_assign(reduced_row_col);
79  row.expr.linear_combine(pivot.expr,
80  reduced_pivot_col, reduced_row_col,
81  0, column + 1);
82  PPL_ASSERT(row.OK());
83  PPL_ASSERT(row.expr.get(column) == 0);
84 }
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
void neg_assign(GMP_Integer &x)
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void Parma_Polyhedra_Library::Grid::reduce_line_with_line ( Grid_Generator row,
Grid_Generator pivot,
dimension_type  column 
)
staticprivate

Reduces the line row using the line pivot.

Uses the line pivot to change the representation of the line row so that the element at index column of row is zero.

Definition at line 31 of file Grid_simplify.cc.

References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Grid_Generator::expr, Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Linear_Expression::linear_combine(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::Grid_Generator::OK(), PPL_DIRTY_TEMP_COEFFICIENT, and Parma_Polyhedra_Library::Linear_Expression::space_dimension().

Referenced by simplify().

32  {
33  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
34  Coefficient_traits::const_reference row_column = row.expr.get(column);
35  PPL_ASSERT(pivot_column != 0);
36  PPL_ASSERT(row_column != 0);
37 
38  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
39  // Use reduced_row_col temporarily to hold the gcd.
40  gcd_assign(reduced_row_col, pivot_column, row_column);
41  // Store the reduced ratio between pivot[column] and row[column].
42  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
43  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
44  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
45  // Multiply row, then subtract from it a multiple of pivot such that
46  // the result in row[column] is zero.
47  neg_assign(reduced_row_col);
48  // pivot.space_dimension() is the index for the parameter divisor so we
49  // start reducing the line at index pivot.space_dimension() - 2.
50  row.expr.linear_combine(pivot.expr,
51  reduced_pivot_col, reduced_row_col,
52  column, pivot.expr.space_dimension());
53  PPL_ASSERT(row.OK());
54  PPL_ASSERT(row.expr.get(column) == 0);
55 }
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
void neg_assign(GMP_Integer &x)
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
void Parma_Polyhedra_Library::Grid::reduce_parameter_with_line ( Grid_Generator row,
const Grid_Generator pivot,
dimension_type  column,
Swapping_Vector< Grid_Generator > &  sys,
dimension_type  num_columns 
)
staticprivate

Reduce row using pivot.

Use the line pivot to change the representation of the parameter row such that the element at index column of row is zero.

Definition at line 129 of file Grid_simplify.cc.

References Parma_Polyhedra_Library::Coefficient_one(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::Grid_Generator::expr, Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), Parma_Polyhedra_Library::Linear_Expression::linear_combine(), Parma_Polyhedra_Library::Linear_Expression::mul_assign(), Parma_Polyhedra_Library::neg_assign(), PPL_DIRTY_TEMP_COEFFICIENT, and Parma_Polyhedra_Library::Swapping_Vector< T >::size().

Referenced by simplify().

133  {
134  // Very similar to reduce_congruence_with_equality below. Any
135  // change here may be needed there too.
136 
137  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
138  Coefficient_traits::const_reference row_column = row.expr.get(column);
139  PPL_ASSERT(pivot_column != 0);
140  PPL_ASSERT(row_column != 0);
141 
142  // Subtract one to allow for the parameter divisor column
143  const dimension_type num_columns = total_num_columns - 1;
144 
145  // If the elements at column in row and pivot are the same, then
146  // just subtract pivot from row.
147  if (row_column == pivot_column) {
148  row.expr.linear_combine(pivot.expr, 1, -1, 0, num_columns);
149  return;
150  }
151 
152  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
153  // Use reduced_row_col temporarily to hold the gcd.
154  gcd_assign(reduced_row_col, pivot_column, row_column);
155  // Store the reduced ratio between pivot[column] and row[column].
156  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
157  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
158  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
159 
160 
161  // Since we are reducing the system to "strong minimal form",
162  // ensure that the multiplier is positive, so that the preceding
163  // diagonals (including the divisor) remain positive. It's safe to
164  // swap the signs as row[column] will still come out 0.
165  if (reduced_pivot_col < 0) {
166  neg_assign(reduced_pivot_col);
167  neg_assign(reduced_row_col);
168  }
169 
170  // Multiply row such that a multiple of pivot can be subtracted from
171  // it below to render row[column] zero. This requires multiplying
172  // all other parameters to match.
173  for (dimension_type index = rows.size(); index-- > 0; ) {
174  Grid_Generator& gen = rows[index];
175  if (gen.is_parameter_or_point()) {
176  // Do not scale the last coefficient.
177  gen.expr.mul_assign(reduced_pivot_col, 0, num_columns);
178  }
179  }
180 
181  // Subtract from row a multiple of pivot such that the result in
182  // row[column] is zero.
183  row.expr.linear_combine(pivot.expr,
184  Coefficient_one(), -reduced_row_col,
185  column, num_columns);
186  PPL_ASSERT(row.expr.get(column) == 0);
187 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
void neg_assign(GMP_Integer &x)
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
template<typename R >
void Parma_Polyhedra_Library::Grid::reduce_pc_with_pc ( R &  row,
R &  pivot,
dimension_type  column,
dimension_type  start,
dimension_type  end 
)
staticprivate

Reduces row using pivot.

Uses the point, parameter or proper congruence at pivot to change the representation of the point, parameter or proper congruence at row so that the element at index column of row is zero. Only elements from index start to index end are modified (i.e. it is assumed that all other elements are zero). This means that col must be in [start,end).

NOTE: This may invalidate the rows, since it messes with the divisors. Client code has to fix that (if needed) and assert OK().

Definition at line 88 of file Grid_simplify.cc.

References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcdext_assign(), Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Linear_Expression::linear_combine(), Parma_Polyhedra_Library::Linear_Expression::linear_combine_lax(), and PPL_DIRTY_TEMP_COEFFICIENT.

Referenced by simplify().

91  {
92  PPL_ASSERT(start <= end);
93  PPL_ASSERT(start <= column);
94  PPL_ASSERT(column < end);
95 
96  Linear_Expression& row_e = row.expr;
97  Linear_Expression& pivot_e = pivot.expr;
98 
99  Coefficient_traits::const_reference pivot_column = pivot_e.get(column);
100  Coefficient_traits::const_reference row_column = row_e.get(column);
101  PPL_ASSERT(pivot_column != 0);
102  PPL_ASSERT(row_column != 0);
103 
106  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
108  gcdext_assign(gcd, s, t, pivot_column, row_column);
109  PPL_ASSERT(pivot_e.get(column) * s + row_e.get(column) * t == gcd);
110 
111  // Store the reduced ratio between pivot[column] and row[column].
112  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
113  exact_div_assign(reduced_pivot_col, pivot_column, gcd);
114  exact_div_assign(reduced_row_col, row_column, gcd);
115 
116  // Multiply row, then subtract from it a multiple of pivot such that
117  // the result in row[column] is zero. Afterward, multiply pivot,
118  // then add to it a (possibly negative) multiple of row such that
119  // the result in pivot[column] is the smallest possible positive
120  // integer.
121  const Linear_Expression old_pivot_e = pivot_e;
122  pivot_e.linear_combine_lax(row_e, s, t, start, end);
123  PPL_ASSERT(pivot_e.get(column) == gcd);
124  row_e.linear_combine(old_pivot_e, reduced_pivot_col, -reduced_row_col, start, end);
125  PPL_ASSERT(row_e.get(column) == 0);
126 }
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
void gcdext_assign(GMP_Integer &x, GMP_Integer &s, GMP_Integer &t, const GMP_Integer &y, const GMP_Integer &z)
template<typename M >
void Parma_Polyhedra_Library::Grid::reduce_reduced ( Swapping_Vector< typename M::row_type > &  sys,
dimension_type  dim,
dimension_type  pivot_index,
dimension_type  start,
dimension_type  end,
const Dimension_Kinds sys_dim_kinds,
bool  generators = true 
)
staticprivate

Reduce column dim in rows preceding pivot_index in sys.

Required when converting (or simplifying) a congruence or generator system to "strong minimal form"; informally, strong minimal form means that, not only is the system in minimal form (ie a triangular matrix), but also the absolute values of the coefficients of the proper congruences and parameters are minimal. As a simple example, the set of congruences $\{3x \equiv_3 0, 4x + y \equiv_3 1\}$, (which is in minimal form) is equivalent to the set $\{3x \equiv_3 0, x + y \equiv_3 1\}$ (which is in strong minimal form).

Parameters
sysThe generator or congruence system to be reduced to strong minimal form.
dimColumn to be reduced.
pivot_indexIndex of last row to be reduced.
startIndex of first column to be changed.
endIndex of last column to be changed.
sys_dim_kindsDimension kinds of the elements of sys.
generatorsFlag indicating whether sys is a congruence or generator system

Definition at line 276 of file Grid_templates.hh.

References Parma_Polyhedra_Library::Coefficient_one(), CON_VIRTUAL, EQUALITY, GEN_VIRTUAL, LINE, PARAMETER, PPL_DIRTY_TEMP_COEFFICIENT, and row_index.

282  {
283  // TODO: Remove this.
284  typedef typename M::row_type M_row_type;
285 
286  const M_row_type& pivot = rows[pivot_index];
287  const Coefficient& pivot_dim = pivot.expr.get(dim);
288 
289  if (pivot_dim == 0) {
290  return;
291  }
292 
293  PPL_DIRTY_TEMP_COEFFICIENT(pivot_dim_half);
294  pivot_dim_half = (pivot_dim + 1) / 2;
295  const Dimension_Kind row_kind = sys_dim_kinds[dim];
296  const bool row_is_line_or_equality
297  = (row_kind == (generators ? LINE : EQUALITY));
298 
299  PPL_DIRTY_TEMP_COEFFICIENT(num_rows_to_subtract);
300  PPL_DIRTY_TEMP_COEFFICIENT(row_dim_remainder);
301  for (dimension_type kinds_index = dim,
302  row_index = pivot_index; row_index-- > 0; ) {
303  if (generators) {
304  --kinds_index;
305  // Move over any virtual rows.
306  while (sys_dim_kinds[kinds_index] == GEN_VIRTUAL) {
307  --kinds_index;
308  }
309  }
310  else {
311  ++kinds_index;
312  // Move over any virtual rows.
313  while (sys_dim_kinds[kinds_index] == CON_VIRTUAL) {
314  ++kinds_index;
315  }
316  }
317 
318  // row_kind CONGRUENCE is included as PARAMETER
319  if (row_is_line_or_equality
320  || (row_kind == PARAMETER
321  && sys_dim_kinds[kinds_index] == PARAMETER)) {
322  M_row_type& row = rows[row_index];
323 
324  const Coefficient& row_dim = row.expr.get(dim);
325  // num_rows_to_subtract may be positive or negative.
326  num_rows_to_subtract = row_dim / pivot_dim;
327 
328  // Ensure that after subtracting num_rows_to_subtract * r_dim
329  // from row_dim, -pivot_dim_half < row_dim <= pivot_dim_half.
330  // E.g., if pivot[dim] = 9, then after this reduction
331  // -5 < row_dim <= 5.
332  row_dim_remainder = row_dim % pivot_dim;
333  if (row_dim_remainder < 0) {
334  if (row_dim_remainder <= -pivot_dim_half) {
335  --num_rows_to_subtract;
336  }
337  }
338  else if (row_dim_remainder > 0 && row_dim_remainder > pivot_dim_half) {
339  ++num_rows_to_subtract;
340  }
341  // Subtract num_rows_to_subtract copies of pivot from row i. Only the
342  // entries from dim need to be subtracted, as the preceding
343  // entries are all zero.
344  // If num_rows_to_subtract is negative, these copies of pivot are
345  // added to row i.
346  if (num_rows_to_subtract != 0) {
347  row.expr.linear_combine(pivot.expr,
348  Coefficient_one(), -num_rows_to_subtract,
349  start, end + 1);
350  }
351  }
352  }
353 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
dimension_type row_index
Definition: PIP_Tree.cc:615
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
void Parma_Polyhedra_Library::Grid::refine_no_check ( const Constraint c)
private

Uses the constraint c to refine *this.

Parameters
cThe constraint to be added. Non-trivial inequalities are ignored.
Warning
If c and *this are dimension-incompatible, the behavior is undefined.

Definition at line 729 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Constraint::is_inconsistent(), and Parma_Polyhedra_Library::Constraint::space_dimension().

729  {
730  PPL_ASSERT(!marked_empty());
731  PPL_ASSERT(space_dim >= c.space_dimension());
732 
733  if (c.is_equality()) {
734  const Congruence cg(c);
736  }
737  else if (c.is_inconsistent()) {
738  set_empty();
739  }
740 }
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
void add_congruence_no_check(const Congruence &cg)
Adds the congruence cg to *this.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
Coefficient c
Definition: PIP_Tree.cc:64
void Parma_Polyhedra_Library::Grid::refine_with_congruence ( const Congruence cg)
inline

Uses a copy of the congruence cg to refine *this.

Parameters
cgThe congruence used.
Exceptions
std::invalid_argumentThrown if *this and congruence cg are dimension-incompatible.

Definition at line 285 of file Grid_inlines.hh.

References add_congruence().

Referenced by Parma_Polyhedra_Library::Affine_Space::refine_with_congruence().

285  {
286  add_congruence(cg);
287 }
void add_congruence(const Congruence &cg)
Adds a copy of congruence cg to *this.
void Parma_Polyhedra_Library::Grid::refine_with_congruences ( const Congruence_System cgs)
inline

Uses a copy of the congruences in cgs to refine *this.

Parameters
cgsThe congruences used.
Exceptions
std::invalid_argumentThrown if *this and cgs are dimension-incompatible.

Definition at line 290 of file Grid_inlines.hh.

References add_congruences().

Referenced by Parma_Polyhedra_Library::Affine_Space::refine_with_congruences().

290  {
291  add_congruences(cgs);
292 }
void add_congruences(const Congruence_System &cgs)
Adds a copy of each congruence in cgs to *this.
void Parma_Polyhedra_Library::Grid::refine_with_constraint ( const Constraint c)

Uses a copy of the constraint c to refine *this.

Parameters
cThe constraint used. If it is not an equality, it will be ignored
Exceptions
std::invalid_argumentThrown if *this and c are dimension-incompatible.

Definition at line 1403 of file Grid_public.cc.

References Parma_Polyhedra_Library::Constraint::space_dimension().

1403  {
1404  // The dimension of `c' must be at most `space_dim'.
1405  if (space_dim < c.space_dimension()) {
1406  throw_dimension_incompatible("refine_with_constraint(c)", "c", c);
1407  }
1408  if (marked_empty()) {
1409  return;
1410  }
1411  refine_no_check(c);
1412 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void refine_no_check(const Constraint &c)
Uses the constraint c to refine *this.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
Coefficient c
Definition: PIP_Tree.cc:64
void Parma_Polyhedra_Library::Grid::refine_with_constraints ( const Constraint_System cs)

Uses a copy of the constraints in cs to refine *this.

Parameters
csThe constraints used. Constraints that are not equalities are ignored.
Exceptions
std::invalid_argumentThrown if *this and cs are dimension-incompatible.

Definition at line 1415 of file Grid_public.cc.

References Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Constraint_System::end(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

1415  {
1416  // The dimension of `cs' must be at most `space_dim'.
1417  if (space_dim < cs.space_dimension()) {
1418  throw_dimension_incompatible("refine_with_constraints(cs)", "cs", cs);
1419  }
1420 
1421  for (Constraint_System::const_iterator i = cs.begin(),
1422  cs_end = cs.end(); !marked_empty() && i != cs_end; ++i) {
1423  refine_no_check(*i);
1424  }
1425 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void refine_no_check(const Constraint &c)
Uses the constraint c to refine *this.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
Constraint_System_const_iterator const_iterator
PPL::Poly_Con_Relation Parma_Polyhedra_Library::Grid::relation_with ( const Congruence cg) const

Returns the relations holding between *this and cg.

Definition at line 386 of file Grid_public.cc.

References Parma_Polyhedra_Library::Scalar_Products::assign(), Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::gcd_assign(), 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::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::Grid_Generator::LINE, Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::Grid_Generator::PARAMETER, Parma_Polyhedra_Library::Grid_Generator::POINT, PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::Poly_Con_Relation::saturates(), Parma_Polyhedra_Library::Congruence::space_dimension(), Parma_Polyhedra_Library::Poly_Con_Relation::strictly_intersects(), and Parma_Polyhedra_Library::Grid_Generator::type().

Referenced by difference_assign(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), and simplify_using_context_assign().

386  {
387  // Dimension-compatibility check.
388  if (space_dim < cg.space_dimension()) {
389  throw_dimension_incompatible("relation_with(cg)", "cg", cg);
390  }
391 
392  if (marked_empty()) {
396  }
397 
398  if (space_dim == 0) {
399  if (cg.is_inconsistent()) {
401  }
402  else if (cg.is_equality()) {
405  }
406  else if (cg.inhomogeneous_term() % cg.modulus() == 0) {
409  }
410  }
411 
413  // Updating found the grid empty.
417  }
418 
419  // Return one of the relations
420  // 'strictly_intersects' a strict subset of the grid points satisfy cg
421  // 'is_included' every grid point satisfies cg
422  // 'is_disjoint' cg and the grid occupy separate spaces.
423  // There is always a point.
424  // Scalar product of the congruence and the first point that
425  // satisfies the congruence.
426  PPL_DIRTY_TEMP_COEFFICIENT(point_sp);
427  point_sp = 0;
428 
430  div = cg.modulus();
431 
433 
434  bool known_to_intersect = false;
435 
436  for (Grid_Generator_System::const_iterator i = gen_sys.begin(),
437  i_end = gen_sys.end(); i != i_end; ++i) {
438  const Grid_Generator& g = *i;
439  Scalar_Products::assign(sp, cg, g);
440 
441  switch (g.type()) {
442 
444  if (cg.is_proper_congruence()) {
445  sp %= div;
446  }
447  if (sp == 0) {
448  // The point satisfies the congruence.
449  if (point_sp == 0) {
450  // Any previous points satisfied the congruence.
451  known_to_intersect = true;
452  }
453  else {
455  }
456  }
457  else {
458  if (point_sp == 0) {
459  if (known_to_intersect) {
461  }
462  // Assign `sp' to `point_sp' as `sp' is the scalar product
463  // of cg and a point g and is non-zero.
464  point_sp = sp;
465  }
466  else {
467  // A previously considered point p failed to satisfy cg such that
468  // `point_sp' = `scalar_prod(p, cg)'
469  // so, if we consider the parameter g-p instead of g, we have
470  // scalar_prod(g-p, cg) = scalar_prod(g, cg) - scalar_prod(p, cg)
471  // = sp - point_sp
472  sp -= point_sp;
473 
474  if (sp != 0) {
475  // Find the GCD between sp and the previous GCD.
476  gcd_assign(div, div, sp);
477  if (point_sp % div == 0) {
478  // There is a point in the grid satisfying cg.
480  }
481  }
482  }
483  }
484  break;
485 
487  if (cg.is_proper_congruence()) {
488  sp %= (div * g.divisor());
489  }
490  if (sp == 0) {
491  // Parameter g satisfies the cg so the relation depends
492  // entirely on the other generators.
493  break;
494  }
495  if (known_to_intersect) {
496  // At least one point satisfies cg. However, the sum of such
497  // a point and the parameter g fails to satisfy cg (due to g).
499  }
500  // Find the GCD between sp and the previous GCD.
501  gcd_assign(div, div, sp);
502  if (point_sp != 0) {
503  // At least one of any previously encountered points fails to
504  // satisfy cg.
505  if (point_sp % div == 0) {
506  // There is also a grid point that satisfies cg.
508  }
509  }
510  break;
511 
513  if (sp == 0) {
514  // Line g satisfies the cg so the relation depends entirely on
515  // the other generators.
516  break;
517  }
518 
519  // Line g intersects the congruence.
520  //
521  // There is a point p in the grid. Suppose <p*cg> = p_sp. Then
522  // (-p_sp/sp)*g + p is a point that satisfies cg: <((-p_sp/sp)*g
523  // + p).cg> = -(p_sp/sp)*sp + p_sp) = 0. If p does not satisfy
524  // `cg' and hence is not in the grid defined by `cg', the grid
525  // `*this' strictly intersects the `cg' grid. On the other
526  // hand, if `p' is in the grid defined by `cg' so that p_sp = 0,
527  // then <p+g.cg> = p_sp + sp != 0; thus `p+g' is a point in
528  // *this that does not satisfy `cg' and hence `p+g' is a point
529  // in *this not in the grid defined by `cg'; therefore `*this'
530  // strictly intersects the `cg' grid.
532  }
533  }
534 
535  if (point_sp == 0) {
536  if (cg.is_equality()) {
537  // Every generator satisfied the cg.
540  }
541  else {
542  // Every generator satisfied the cg.
544  }
545  }
546 
547  PPL_ASSERT(!known_to_intersect);
549 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
static Poly_Con_Relation is_disjoint()
The polyhedron and the set of points satisfying the constraint are disjoint.
const_iterator end() const
Returns the past-the-end const_iterator.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
const_iterator begin() const
Returns the const_iterator pointing to the first generator, if this is not empty; otherwise...
static Poly_Con_Relation saturates()
The polyhedron is included in the set of points saturating the constraint.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static void assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the scalar product of x and y and assigns it to z.
static Poly_Con_Relation strictly_intersects()
The polyhedron intersects the set of points satisfying the constraint, but it is not included in it...
bool update_generators() const
Updates and minimizes the generators from the congruences.
PPL::Poly_Gen_Relation Parma_Polyhedra_Library::Grid::relation_with ( const Grid_Generator g) const

Returns the relations holding between *this and g.

Definition at line 552 of file Grid_public.cc.

References Parma_Polyhedra_Library::Poly_Gen_Relation::nothing(), Parma_Polyhedra_Library::Grid_Generator::space_dimension(), and Parma_Polyhedra_Library::Poly_Gen_Relation::subsumes().

552  {
553  // Dimension-compatibility check.
554  if (space_dim < g.space_dimension()) {
555  throw_dimension_incompatible("relation_with(g)", "g", g);
556  }
557 
558  // The empty grid cannot subsume a generator.
559  if (marked_empty()) {
561  }
562 
563  // A universe grid in a zero-dimensional space subsumes all the
564  // generators of a zero-dimensional space.
565  if (space_dim == 0) {
567  }
568 
571  }
572 
573  return
576  : Poly_Gen_Relation::nothing();
577 }
static Poly_Gen_Relation subsumes()
Adding the generator would not change the polyhedron.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool satisfies_all_congruences(const Grid_Generator &g) const
Returns true if g satisfies all the congruences.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void update_congruences() const
Updates and minimizes the congruences from the generators.
static Poly_Gen_Relation nothing()
The assertion that says nothing.
PPL::Poly_Gen_Relation Parma_Polyhedra_Library::Grid::relation_with ( const Generator g) const

Returns the relations holding between *this and g.

Definition at line 580 of file Grid_public.cc.

References Parma_Polyhedra_Library::Generator::divisor(), Parma_Polyhedra_Library::Generator::expression(), Parma_Polyhedra_Library::Generator::is_closure_point(), Parma_Polyhedra_Library::Generator::is_point(), Parma_Polyhedra_Library::Poly_Gen_Relation::nothing(), Parma_Polyhedra_Library::Generator::space_dimension(), and Parma_Polyhedra_Library::Poly_Gen_Relation::subsumes().

580  {
581  const dimension_type g_space_dim = g.space_dimension();
582 
583  // Dimension-compatibility check.
584  if (space_dim < g_space_dim) {
585  throw_dimension_incompatible("relation_with(g)", "g", g);
586  }
587 
588  // The empty grid cannot subsume a generator.
589  if (marked_empty()) {
591  }
592 
593  // A universe grid in a zero-dimensional space subsumes all the
594  // generators of a zero-dimensional space.
595  if (space_dim == 0) {
597  }
598 
601  }
602 
603  const Linear_Expression expr(g.expression());
604  Grid_Generator gg(grid_point());
605  if (g.is_point() || g.is_closure_point()) {
606  // Points and closure points are converted to grid points.
607  gg = grid_point(expr, g.divisor());
608  }
609  else {
610  // The generator is a ray or line.
611  // In both cases, we convert it to a grid line
612  gg = grid_line(expr);
613  }
614 
615  return
618  : Poly_Gen_Relation::nothing();
619 }
static Poly_Gen_Relation subsumes()
Adding the generator would not change the polyhedron.
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool satisfies_all_congruences(const Grid_Generator &g) const
Returns true if g satisfies all the congruences.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void update_congruences() const
Updates and minimizes the congruences from the generators.
static Poly_Gen_Relation nothing()
The assertion that says nothing.
PPL::Poly_Con_Relation Parma_Polyhedra_Library::Grid::relation_with ( const Constraint c) const

Returns the relations holding between *this and c.

Definition at line 622 of file Grid_public.cc.

References Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::Constraint::expr, Parma_Polyhedra_Library::Grid_Generator::expr, 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_inconsistent(), Parma_Polyhedra_Library::Constraint::is_strict_inequality(), Parma_Polyhedra_Library::Grid_Generator::LINE, Parma_Polyhedra_Library::Linear_Expression::linear_combine(), Parma_Polyhedra_Library::Grid_Generator::OK(), Parma_Polyhedra_Library::Grid_Generator::PARAMETER, Parma_Polyhedra_Library::Grid_Generator::POINT, Parma_Polyhedra_Library::Scalar_Products::reduced_sign(), Parma_Polyhedra_Library::Poly_Con_Relation::saturates(), Parma_Polyhedra_Library::Linear_Expression::set_inhomogeneous_term(), Parma_Polyhedra_Library::Grid_Generator::set_is_parameter(), Parma_Polyhedra_Library::Scalar_Products::sign(), Parma_Polyhedra_Library::Constraint::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::Poly_Con_Relation::strictly_intersects(), Parma_Polyhedra_Library::Grid_Generator::strong_normalize(), and Parma_Polyhedra_Library::Grid_Generator::type().

622  {
623  // Dimension-compatibility check.
624  if (space_dim < c.space_dimension()) {
625  throw_dimension_incompatible("relation_with(c)", "c", c);
626  }
627 
628  if (c.is_equality()) {
629  const Congruence cg(c);
630  return relation_with(cg);
631  }
632 
633  if (marked_empty()) {
637  }
638 
639  if (space_dim == 0) {
640  if (c.is_inconsistent()) {
641  if (c.is_strict_inequality() && c.inhomogeneous_term() == 0) {
642  // The constraint 0 > 0 implicitly defines the hyperplane 0 = 0;
643  // thus, the zero-dimensional point also saturates it.
646  }
647  else {
649  }
650  }
651  else if (c.inhomogeneous_term() == 0) {
654  }
655  else {
656  // The zero-dimensional point saturates
657  // neither the positivity constraint 1 >= 0,
658  // nor the strict positivity constraint 1 > 0.
660  }
661  }
662 
664  // Updating found the grid empty.
668  }
669 
670  // Return one of the relations
671  // 'strictly_intersects' a strict subset of the grid points satisfy c
672  // 'is_included' every grid point satisfies c
673  // 'is_disjoint' c and the grid occupy separate spaces.
674  // There is always a point.
675 
676  bool point_is_included = false;
677  bool point_saturates = false;
678  const Grid_Generator* first_point = 0;
679 
680  for (Grid_Generator_System::const_iterator i = gen_sys.begin(),
681  i_end = gen_sys.end(); i != i_end; ++i) {
682  const Grid_Generator& g = *i;
683  switch (g.type()) {
685  {
686  if (first_point == 0) {
687  first_point = &g;
688  const int sign = Scalar_Products::sign(c, g);
689  if (sign == 0) {
690  point_saturates = !c.is_strict_inequality();
691  }
692  else if (sign > 0) {
693  point_is_included = !c.is_equality();
694  }
695  break;
696  }
697  // Not the first point: convert `g' to be a parameter
698  // and fall through into the parameter case.
699  Grid_Generator& gen = const_cast<Grid_Generator&>(g);
700  const Grid_Generator& point = *first_point;
701  const Coefficient& p_div = point.divisor();
702  const Coefficient& g_div = gen.divisor();
703  gen.expr.linear_combine(point.expr, p_div, -g_div,
704  1, gen.expr.space_dimension());
705  gen.expr.set_inhomogeneous_term(g_div * p_div);
706  gen.strong_normalize();
707  gen.set_is_parameter();
708  PPL_ASSERT(gen.OK());
709  }
710  // Intentionally fall through.
711 
714  {
715  const int sign = c.is_strict_inequality()
716  ? Scalar_Products::reduced_sign(c.expr, g.expr)
717  : Scalar_Products::sign(c.expr, g.expr);
718  if (sign != 0) {
720  }
721  }
722  break;
723  } // switch
724  }
725 
726  // If this program point is reached, then all lines and parameters
727  // saturate the constraint. Hence, the result is determined by
728  // the previosly computed relation with the point.
729  if (point_saturates) {
732  }
733 
734  if (point_is_included) {
736  }
737 
739 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
static Poly_Con_Relation is_disjoint()
The polyhedron and the set of points satisfying the constraint are disjoint.
const_iterator end() const
Returns the past-the-end const_iterator.
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
const_iterator begin() const
Returns the const_iterator pointing to the first generator, if this is not empty; otherwise...
Poly_Con_Relation relation_with(const Congruence &cg) const
Returns the relations holding between *this and cg.
Definition: Grid_public.cc:386
static Poly_Con_Relation saturates()
The polyhedron is included in the set of points saturating the constraint.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
static int reduced_sign(const Linear_Expression &x, const Linear_Expression &y)
Returns the sign of the reduced scalar product of x and y, where the coefficient of x is ignored...
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
static int sign(const Linear_Expression &x, const Linear_Expression &y)
Returns the sign of the scalar product between x and y.
Coefficient c
Definition: PIP_Tree.cc:64
static Poly_Con_Relation strictly_intersects()
The polyhedron intersects the set of points satisfying the constraint, but it is not included in it...
bool update_generators() const
Updates and minimizes the generators from the congruences.
void Parma_Polyhedra_Library::Grid::remove_higher_space_dimensions ( dimension_type  new_dimension)

Removes the higher dimensions of the vector space so that the resulting space will have dimension new_dimension..

Exceptions
std::invalid_argumentThrown if new_dimensions is greater than the space dimension of *this.

Definition at line 318 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::Congruence_System::set_space_dimension(), Parma_Polyhedra_Library::swap(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().

318  {
319  // Dimension-compatibility check.
320  if (new_dimension > space_dim) {
321  throw_dimension_incompatible("remove_higher_space_dimensions(nd)",
322  new_dimension);
323  }
324  // The removal of no dimensions from any grid is a no-op.
325  // Note that this case also captures the only legal removal of
326  // dimensions from a grid in a 0-dim space.
327  if (new_dimension == space_dim) {
328  PPL_ASSERT(OK());
329  return;
330  }
331 
332  if (is_empty()) {
333  // Removing dimensions from the empty grid just updates the space
334  // dimension.
335  space_dim = new_dimension;
336  set_empty();
337  PPL_ASSERT(OK());
338  return;
339  }
340 
341  if (new_dimension == 0) {
342  // Removing all dimensions from a non-empty grid just returns the
343  // zero-dimensional universe grid.
345  return;
346  }
347 
348  // Favor the generators, as is done by is_empty().
350  gen_sys.set_space_dimension(new_dimension);
351  if (generators_are_minimized()) {
352  // Count the actual number of rows that are now redundant.
353  dimension_type num_redundant = 0;
354  const dimension_type num_old_gs = space_dim - new_dimension;
355  for (dimension_type row = 0; row < num_old_gs; ++row) {
356  if (dim_kinds[row] != GEN_VIRTUAL) {
357  ++num_redundant;
358  }
359  }
360  if (num_redundant > 0) {
361  // Chop zero rows from end of system, to keep minimal form.
362  gen_sys.remove_trailing_rows(num_redundant);
364  }
365  dim_kinds.resize(new_dimension + 1);
366  // TODO: Consider if it is worth also preserving the congruences
367  // if they are also in minimal form.
368  }
370  // Extend the zero dim false congruence system to the appropriate
371  // dimension and then swap it with `con_sys'.
372  Congruence_System cgs(Congruence::zero_dim_false());
373  // Extra 2 columns for inhomogeneous term and modulus.
374  cgs.set_space_dimension(new_dimension + 2);
375  swap(con_sys, cgs);
376  }
377  else {
378  PPL_ASSERT(congruences_are_minimized());
379  con_sys.set_space_dimension(new_dimension);
380  // Count the actual number of rows that are now redundant.
381  dimension_type num_redundant = 0;
382  for (dimension_type row = space_dim; row > new_dimension; --row) {
383  if (dim_kinds[row] != CON_VIRTUAL) {
384  ++num_redundant;
385  }
386  }
387 
388  con_sys.remove_rows(0, num_redundant, true);
389  dim_kinds.erase(dim_kinds.begin() + (new_dimension + 1),
390  dim_kinds.end());
391 
393  // Replace gen_sys with an empty system of the right dimension.
394  // Extra 2 columns for inhomogeneous term and modulus.
395  Grid_Generator_System gs(new_dimension + 2);
396  gen_sys.m_swap(gs);
397  }
398 
399  // Update the space dimension.
400  space_dim = new_dimension;
401 
402  PPL_ASSERT(OK(true));
403 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void clear_generators_up_to_date()
Sets status to express that generators are out of date.
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
size_t dimension_type
An unsigned integral type for representing space dimensions.
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
bool set_space_dimension(dimension_type new_space_dim)
Sets the number of space dimensions to new_space_dim.
void set_space_dimension(dimension_type space_dim)
Resizes the system to the specified space dimension.
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
void m_swap(Grid_Generator_System &y)
Swaps *this with y.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
void swap(Grid &x, Grid &y)
Swaps x with y.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
void unset_pending_rows()
Sets the index to indicate that the system has no pending rows.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
void remove_trailing_rows(dimension_type n)
Makes the system shrink by removing its n trailing rows.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
void remove_rows(dimension_type first, dimension_type last, bool keep_sorted)
Makes the system shrink by removing the rows in [first,last).
bool is_empty() const
Returns true if and only if *this is an empty grid.
Definition: Grid_public.cc:742
void Parma_Polyhedra_Library::Grid::remove_space_dimensions ( const Variables_Set vars)

Removes all the specified dimensions from the vector space.

Parameters
varsThe set of Variable objects corresponding to the space dimensions to be removed.
Exceptions
std::invalid_argumentThrown if *this is dimension-incompatible with one of the Variable objects contained in vars.

Definition at line 273 of file Grid_chdims.cc.

References Parma_Polyhedra_Library::Variables_Set::space_dimension().

273  {
274  // The removal of no dimensions from any grid is a no-op. This case
275  // also captures the only legal removal of dimensions from a grid in
276  // a 0-dim space.
277  if (vars.empty()) {
278  PPL_ASSERT(OK());
279  return;
280  }
281 
282  // Dimension-compatibility check.
283  const dimension_type min_space_dim = vars.space_dimension();
284  if (space_dim < min_space_dim) {
285  throw_dimension_incompatible("remove_space_dimensions(vs)", min_space_dim);
286  }
287 
288  const dimension_type new_space_dim = space_dim - vars.size();
289 
290  if (marked_empty()
292  // Update the space dimension.
293  space_dim = new_space_dim;
294  set_empty();
295  PPL_ASSERT(OK());
296  return;
297  }
298 
299  // Removing _all_ dimensions from a non-empty grid obtains the
300  // zero-dimensional universe grid.
301  if (new_space_dim == 0) {
303  return;
304  }
305 
307 
310 
311  // Update the space dimension.
312  space_dim = new_space_dim;
313 
314  PPL_ASSERT(OK(true));
315 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
void remove_space_dimensions(const Variables_Set &vars)
Removes all the specified dimensions from the generator system.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool update_generators() const
Updates and minimizes the generators from the congruences.
template<typename M , typename R >
bool Parma_Polyhedra_Library::Grid::rows_are_zero ( M &  system,
dimension_type  first,
dimension_type  last,
dimension_type  row_size 
)
staticprivate

Checks that trailing rows contain only zero terms.

If all columns contain zero in the rows of system from row index first to row index last then return true, else return false. row_size gives the number of columns in each row.

This method is only used in assertions in the simplify methods.

Definition at line 239 of file Grid_simplify.cc.

240  {
241  while (first <= last) {
242  const R& row = system[first++];
243  if (!row.expr.all_zeroes(0, row_size)) {
244  return false;
245  }
246  }
247  return true;
248 }
void Parma_Polyhedra_Library::Grid::select_wider_congruences ( const Grid y,
Congruence_System selected_cgs 
) const
private

Copies a widened selection of congruences from y to selected_cgs.

Definition at line 33 of file Grid_widenings.cc.

References con_sys, CON_VIRTUAL, congruences_are_minimized(), dim_kinds, EQUALITY, Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Congruence::is_equal_at_dimension(), marked_empty(), PROPER_CONGRUENCE, space_dim, and Parma_Polyhedra_Library::Congruence_System::space_dimension().

Referenced by congruence_widening_assign().

34  {
35  // Private method: the caller must ensure the following conditions
36  // (beside the inclusion `y <= x').
37  PPL_ASSERT(space_dim == y.space_dim);
38  PPL_ASSERT(!marked_empty());
39  PPL_ASSERT(!y.marked_empty());
40  PPL_ASSERT(congruences_are_minimized());
41  PPL_ASSERT(y.congruences_are_minimized());
42 
43  // Note: row counters start at 0, to preserve the original order in
44  // the selected congruences.
45  for (dimension_type dim = con_sys.space_dimension(), x_row = 0, y_row = 0;
46  dim > 0; --dim) {
47  PPL_ASSERT(dim_kinds[dim] == CON_VIRTUAL
48  || dim_kinds[dim] == y.dim_kinds[dim]);
49  switch (dim_kinds[dim]) {
50  case PROPER_CONGRUENCE:
51  {
52  const Congruence& cg = con_sys[x_row];
53  const Congruence& y_cg = y.con_sys[y_row];
54  if (cg.is_equal_at_dimension(Variable(dim - 1), y_cg)) {
55  // The leading diagonal entries are equal.
56  selected_cgs.insert(cg);
57  }
58  ++x_row;
59  ++y_row;
60  }
61  break;
62  case EQUALITY:
63  selected_cgs.insert(con_sys[x_row]);
64  ++x_row;
65  ++y_row;
66  break;
67  case CON_VIRTUAL:
68  if (y.dim_kinds[dim] != CON_VIRTUAL) {
69  ++y_row;
70  }
71  break;
72  }
73  }
74 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
void Parma_Polyhedra_Library::Grid::select_wider_generators ( const Grid y,
Grid_Generator_System widened_ggs 
) const
private

Copies widened generators from y to widened_ggs.

Definition at line 232 of file Grid_widenings.cc.

References dim_kinds, Parma_Polyhedra_Library::Grid_Generator::expression(), gen_sys, generators_are_minimized(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Grid_Generator::is_equal_at_dimension(), marked_empty(), and space_dim.

Referenced by generator_widening_assign().

233  {
234  // Private method: the caller must ensure the following conditions
235  // (beside the inclusion `y <= x').
236  PPL_ASSERT(space_dim == y.space_dim);
237  PPL_ASSERT(!marked_empty());
238  PPL_ASSERT(!y.marked_empty());
239  PPL_ASSERT(generators_are_minimized());
240  PPL_ASSERT(y.generators_are_minimized());
241 
242  // Note: row counters start at 0, to preserve the original order in
243  // the selected generators.
244  for (dimension_type dim = 0, x_row = 0, y_row = 0;
245  dim <= gen_sys.space_dimension(); ++dim) {
246  PPL_ASSERT(dim_kinds[dim] == LINE
247  || y.dim_kinds[dim] == GEN_VIRTUAL
248  || dim_kinds[dim] == y.dim_kinds[dim]);
249  switch (dim_kinds[dim]) {
250  case PARAMETER:
251  {
252  const Grid_Generator& gg = gen_sys[x_row];
253  const Grid_Generator& y_gg = y.gen_sys[y_row];
254  if (gg.is_equal_at_dimension(dim, y_gg)) {
255  // The leading diagonal entry is equal.
256  widened_ggs.insert(gg);
257  }
258  else {
259  const Linear_Expression expr(gg.expression());
260  Grid_Generator line = grid_line(expr);
261  widened_ggs.insert(line, Recycle_Input());
262  }
263  ++x_row;
264  ++y_row;
265  }
266  break;
267  case LINE:
268  widened_ggs.insert(gen_sys[x_row]);
269  ++x_row;
270  ++y_row;
271  break;
272  case GEN_VIRTUAL:
273  if (y.dim_kinds[dim] != GEN_VIRTUAL) {
274  ++y_row;
275  }
276  break;
277  }
278  }
279 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
void Parma_Polyhedra_Library::Grid::set_congruences_minimized ( )
inlineprivate

Sets status to express that congruences are minimized.

Definition at line 70 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Grid::Status::set_c_minimized(), set_congruences_up_to_date(), and status.

Referenced by congruence_widening_assign(), construct(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_empty(), minimize(), minimized_congruences(), and update_generators().

70  {
73 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void set_congruences_up_to_date()
Sets status to express that congruences are up-to-date.
Definition: Grid_inlines.hh:65
void Parma_Polyhedra_Library::Grid::set_congruences_up_to_date ( )
inlineprivate

Sets status to express that congruences are up-to-date.

Definition at line 65 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Grid::Status::set_c_up_to_date(), and status.

Referenced by Grid(), and set_congruences_minimized().

65  {
67 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void Parma_Polyhedra_Library::Grid::set_empty ( )
private

Sets status to express that the grid is empty, clearing all corresponding matrices.

Definition at line 468 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Congruence_System::set_space_dimension(), Parma_Polyhedra_Library::swap(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().

Referenced by congruence_widening_assign(), difference_assign(), Grid(), grid_generators(), intersection_assign(), is_empty(), map_space_dimensions(), minimized_congruences(), minimized_grid_generators(), time_elapse_assign(), and update_generators().

468  {
469  status.set_empty();
470 
471  // Replace gen_sys with an empty system of the right dimension.
472  Grid_Generator_System gs(space_dim);
473  gen_sys.m_swap(gs);
474 
475  // Extend the zero dim false congruence system to the appropriate
476  // dimension and then swap it with `con_sys'.
477  Congruence_System cgs(Congruence::zero_dim_false());
478  cgs.set_space_dimension(space_dim);
479  swap(con_sys, cgs);
480 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void m_swap(Grid_Generator_System &y)
Swaps *this with y.
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
void swap(Grid &x, Grid &y)
Swaps x with y.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void Parma_Polyhedra_Library::Grid::set_generators_minimized ( )
inlineprivate

Sets status to express that generators are minimized.

Definition at line 76 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Grid::Status::set_g_minimized(), set_generators_up_to_date(), and status.

Referenced by construct(), generator_widening_assign(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), max_min(), minimize(), minimized_grid_generators(), and update_generators().

76  {
79 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void set_generators_up_to_date()
Sets status to express that generators are up-to-date.
Definition: Grid_inlines.hh:60
void Parma_Polyhedra_Library::Grid::set_generators_up_to_date ( )
inlineprivate

Sets status to express that generators are up-to-date.

Definition at line 60 of file Grid_inlines.hh.

References Parma_Polyhedra_Library::Grid::Status::set_g_up_to_date(), and status.

Referenced by Grid(), and set_generators_minimized().

60  {
62 }
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
void Parma_Polyhedra_Library::Grid::set_zero_dim_univ ( )
private

Sets status to express that the grid is the universe 0-dimension vector space, clearing all corresponding matrices.

Definition at line 459 of file Grid_nonpublic.cc.

Referenced by construct(), Grid(), and map_space_dimensions().

459  {
461  space_dim = 0;
462  con_sys.clear();
463  gen_sys.clear();
464  gen_sys.insert(grid_point());
465 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Status status
The status flags to keep track of the grid's internal state.
Definition: Grid_defs.hh:1980
Congruence_System con_sys
The system of congruences.
Definition: Grid_defs.hh:1970
void clear()
Removes all the generators from the generator system and sets its space dimension to 0...
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
void clear()
Removes all the congruences and sets the space dimension to 0.
bool Parma_Polyhedra_Library::Grid::simplify ( Congruence_System cgs,
Dimension_Kinds dim_kinds 
)
staticprivate

Converts cgs to upper triangular (i.e. minimized) form.

Returns true if cgs represents the empty set, otherwise returns false.

Definition at line 389 of file Grid_simplify.cc.

References Parma_Polyhedra_Library::Coefficient_one(), Parma_Polyhedra_Library::Coefficient_zero(), CON_VIRTUAL, dim_kinds, EQUALITY, Parma_Polyhedra_Library::Congruence::expr, Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Congruence::inhomogeneous_term(), Parma_Polyhedra_Library::Congruence_System::insert_verbatim(), Parma_Polyhedra_Library::Congruence::is_equality(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::Linear_Expression::negate(), Parma_Polyhedra_Library::Congruence_System::normalize_moduli(), Parma_Polyhedra_Library::Congruence_System::num_rows(), Parma_Polyhedra_Library::Congruence_System::OK(), PROPER_CONGRUENCE, reduce_congruence_with_equality(), reduce_equality_with_equality(), reduce_pc_with_pc(), Parma_Polyhedra_Library::Congruence_System::remove_trailing_rows(), row_index, Parma_Polyhedra_Library::Congruence_System::rows, Parma_Polyhedra_Library::Linear_Expression::set_inhomogeneous_term(), Parma_Polyhedra_Library::Congruence::set_modulus(), Parma_Polyhedra_Library::Congruence::set_space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), swap(), and Parma_Polyhedra_Library::swap().

Referenced by Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_empty(), max_min(), minimize(), minimized_congruences(), minimized_grid_generators(), and update_congruences().

389  {
390  PPL_ASSERT(cgs.space_dimension() != 0);
391  // Changes here may also be required in the generator version above.
392 
393  // TODO: Consider normalizing the moduli only when congruences are
394  // added to con_sys.
395  cgs.normalize_moduli();
396 
397  // NOTE: add one for the inhomogeneous term (but not the modulus).
398  const dimension_type num_columns = cgs.space_dimension() + 1;
399 
400  if (dim_kinds.size() != num_columns) {
401  dim_kinds.resize(num_columns);
402  }
403 
404  const dimension_type num_rows = cgs.num_rows();
405 
406  // For each dimension `dim' move or construct a row into position
407  // `pivot_index' such that the row has a value of zero in all
408  // elements preceding column `dim' and some other value in column
409  // `dim'.
410  dimension_type pivot_index = 0;
411  for (dimension_type dim = num_columns; dim-- > 0; ) {
412  // Consider the pivot and following rows.
413  dimension_type row_index = pivot_index;
414 
415  // Move down over rows which have zero in column `dim'.
416  while (row_index < num_rows && cgs.rows[row_index].expr.get(dim) == 0) {
417  ++row_index;
418  }
419 
420  if (row_index == num_rows) {
421  // Element in column `dim' is zero in all rows from the pivot,
422  // or `cgs' is empty of rows.
423  dim_kinds[dim] = CON_VIRTUAL;
424  }
425  else {
426  // Here row_index != num_rows.
427  if (row_index != pivot_index) {
428  using std::swap;
429  swap(cgs.rows[row_index], cgs.rows[pivot_index]);
430  }
431 
432  Congruence& pivot = cgs.rows[pivot_index];
433  bool pivot_is_equality = pivot.is_equality();
434 
435  // Change the matrix so that the value at `dim' in every row
436  // following `pivot_index' is 0, leaving an equivalent grid.
437  while (row_index < num_rows - 1) {
438  ++row_index;
439  Congruence& row = cgs.rows[row_index];
440  if (row.expr.get(dim) == 0) {
441  continue;
442  }
443 
444  if (row.is_equality()) {
445  if (pivot_is_equality) {
446  reduce_equality_with_equality(row, pivot, dim);
447  }
448  else {
449  PPL_ASSERT(pivot.is_proper_congruence());
450  using std::swap;
451  swap(row, pivot);
452  pivot_is_equality = true;
453  reduce_congruence_with_equality(row, pivot, dim, cgs.rows);
454  }
455  }
456  else {
457  PPL_ASSERT(row.is_proper_congruence());
458  if (pivot_is_equality) {
459  reduce_congruence_with_equality(row, pivot, dim, cgs.rows);
460  }
461  else {
462  PPL_ASSERT(pivot.is_proper_congruence());
463  reduce_pc_with_pc(row, pivot, dim, 0, dim + 1);
464  }
465  }
466  }
467 
468  if (pivot_is_equality) {
469  dim_kinds[dim] = EQUALITY;
470  }
471  else {
472  PPL_ASSERT(pivot.is_proper_congruence());
474  }
475 
476  // Since we are reducing the system to "strong minimal form",
477  // ensure that a positive value follows the leading zeros.
478  if (pivot.expr.get(dim) < 0) {
479  pivot.expr.negate(0, dim + 1);
480  }
481 
482  // Factor this row out of the preceding ones.
483  reduce_reduced<Congruence_System>
484  (cgs.rows, dim, pivot_index, 0, dim, dim_kinds, false);
485 
486  PPL_ASSERT(cgs.OK());
487 
488  ++pivot_index;
489  }
490  }
491 
492  if (pivot_index > 0) {
493  // If the last row is false then make it the equality 1 = 0, and
494  // make it the only row.
495 
496 #ifndef NDEBUG
497  {
498  const bool ret = rows_are_zero<Congruence_System, Congruence>
499  (cgs,
500  // index of first
501  pivot_index,
502  // index of last
503  num_rows - 1,
504  // row size
505  num_columns);
506  PPL_ASSERT(ret == true);
507  }
508 #endif
509 
510  cgs.remove_trailing_rows(num_rows - pivot_index);
511  Congruence& last_row = cgs.rows.back();
512 
513  switch (dim_kinds[0]) {
514 
515  case PROPER_CONGRUENCE:
516  if (last_row.inhomogeneous_term() % last_row.modulus() == 0) {
517  break;
518  }
519  // The last row is a false proper congruence.
520  last_row.set_modulus(Coefficient_zero());
521  dim_kinds[0] = EQUALITY;
522  // Intentionally fall through.
523 
524  case EQUALITY:
525  // The last row is a false equality, as all the coefficient terms
526  // are zero while the inhomogeneous term (as a result of the
527  // reduced form) is some other value.
528  last_row.expr.set_inhomogeneous_term(Coefficient_one());
529  dim_kinds.resize(1);
530  using std::swap;
531  swap(cgs.rows[0], last_row);
532  cgs.remove_trailing_rows(cgs.num_rows() - 1);
533  PPL_ASSERT(cgs.OK());
534  return true;
535 
536  default:
537  break;
538  }
539  }
540  else {
541  // Either `cgs' is empty (it defines the universe) or every column
542  // before the modulus column contains only zeroes.
543 
544  if (num_rows > 0) {
545 #ifndef NDEBUG
546  const bool ret = rows_are_zero<Congruence_System, Congruence>
547  (cgs,
548  // index of first
549  0,
550  // index of last
551  num_rows - 1,
552  // row size
553  num_columns);
554  PPL_ASSERT(ret == true);
555 #endif
556  // Ensure that a single row will remain for the integrality congruence.
557  cgs.remove_trailing_rows(num_rows - 1);
558  }
559 
560  // Set up the integrality congruence.
562  if (num_rows == 0) {
563  Congruence cg;
564  cg.set_modulus(Coefficient_one());
565  cg.set_space_dimension(cgs.space_dimension());
566  cg.expr.set_inhomogeneous_term(Coefficient_one());
567  cgs.insert_verbatim(cg, Recycle_Input());
568 
569  PPL_ASSERT(cgs.OK());
570  return false;
571  }
572 
573  PPL_ASSERT(cgs.num_rows() == 1);
574  cgs.rows.back().set_modulus(Coefficient_one());
575  }
576 
577  // Ensure that the last row is the integrality congruence.
578  if (dim_kinds[0] == CON_VIRTUAL) {
579  // The last row is virtual, append the integrality congruence.
581  Congruence new_last_row;
582  new_last_row.set_space_dimension(cgs.space_dimension());
583  new_last_row.set_modulus(Coefficient_one());
584  // Try use an existing modulus.
585  dimension_type row_index = cgs.num_rows();
586  while (row_index-- > 0) {
587  const Congruence& row = cgs[row_index];
588  if (row.modulus() > 0) {
589  new_last_row.set_modulus(row.modulus());
590  break;
591  }
592  }
593  new_last_row.expr.set_inhomogeneous_term(new_last_row.modulus());
594  cgs.insert_verbatim(new_last_row, Recycle_Input());
595  }
596  else {
597  cgs.rows.back().expr.set_inhomogeneous_term(cgs.rows.back().modulus());
598  }
599 
600  // Since we are reducing the system to "strong minimal form",
601  // factor the modified integrality congruence out of the other rows;
602  reduce_reduced<Congruence_System>
603  (cgs.rows, 0, cgs.num_rows() - 1, 0, 0, dim_kinds, false);
604 
605  PPL_ASSERT(cgs.OK());
606  return false;
607 }
static void reduce_pc_with_pc(R &row, R &pivot, dimension_type column, dimension_type start, dimension_type end)
Reduces row using pivot.
void swap(CO_Tree &x, CO_Tree &y)
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type row_index
Definition: PIP_Tree.cc:615
void swap(Grid &x, Grid &y)
Swaps x with y.
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
static void reduce_equality_with_equality(Congruence &row, const Congruence &pivot, dimension_type column)
Reduces the equality row using the equality pivot.
static void reduce_congruence_with_equality(Congruence &row, const Congruence &pivot, dimension_type column, Swapping_Vector< Congruence > &sys)
Reduce row using pivot.
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
void Parma_Polyhedra_Library::Grid::simplify ( Grid_Generator_System ggs,
Dimension_Kinds dim_kinds 
)
staticprivate

Converts gs to lower triangular (i.e. minimized) form.

Expects gs to contain at least one point.

Definition at line 252 of file Grid_simplify.cc.

References dim_kinds, Parma_Polyhedra_Library::Grid_Generator::expr, GEN_VIRTUAL, Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Grid_Generator_System::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator::is_line(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), LINE, Parma_Polyhedra_Library::Linear_Expression::negate(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), PARAMETER, reduce_line_with_line(), reduce_parameter_with_line(), reduce_pc_with_pc(), row_index, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), swap(), Parma_Polyhedra_Library::swap(), Parma_Polyhedra_Library::Grid_Generator_System::sys, and Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows().

252  {
253  PPL_ASSERT(!ggs.has_no_rows());
254  // Changes here may also be required in the congruence version below.
255 
256  // Subtract one to allow for the parameter divisor column
257  const dimension_type num_columns = ggs.space_dimension() + 1;
258 
259  if (dim_kinds.size() != num_columns) {
260  dim_kinds.resize(num_columns);
261  }
262 
263  const dimension_type num_rows = ggs.num_rows();
264 
265  // For each dimension `dim' move or construct a row into position
266  // `pivot_index' such that the row has zero in all elements
267  // following column `dim' and a value other than zero in column
268  // `dim'.
269  dimension_type pivot_index = 0;
270  for (dimension_type dim = 0; dim < num_columns; ++dim) {
271  // Consider the pivot and following rows.
272  dimension_type row_index = pivot_index;
273 
274  // Move down over rows which have zero in column `dim'.
275  while (row_index < num_rows
276  && ggs.sys.rows[row_index].expr.get(dim) == 0) {
277  ++row_index;
278  }
279 
280  if (row_index == num_rows) {
281  // Element in column `dim' is zero in all rows from the pivot.
282  dim_kinds[dim] = GEN_VIRTUAL;
283  }
284  else {
285  if (row_index != pivot_index) {
286  using std::swap;
287  swap(ggs.sys.rows[row_index], ggs.sys.rows[pivot_index]);
288  }
289  Grid_Generator& pivot = ggs.sys.rows[pivot_index];
290  bool pivot_is_line = pivot.is_line();
291 
292  // Change the matrix so that the value at `dim' in every row
293  // following `pivot_index' is 0, leaving an equivalent grid.
294  while (row_index < num_rows - 1) {
295  ++row_index;
296  Grid_Generator& row = ggs.sys.rows[row_index];
297 
298  if (row.expr.get(dim) == 0) {
299  continue;
300  }
301 
302  if (row.is_line()) {
303  if (pivot_is_line) {
304  reduce_line_with_line(row, pivot, dim);
305  }
306  else {
307  PPL_ASSERT(pivot.is_parameter_or_point());
308  using std::swap;
309  swap(row, pivot);
310  pivot_is_line = true;
311  reduce_parameter_with_line(row, pivot, dim, ggs.sys.rows,
312  num_columns + 1);
313  }
314  }
315  else {
316  PPL_ASSERT(row.is_parameter_or_point());
317  if (pivot_is_line) {
318  reduce_parameter_with_line(row, pivot, dim, ggs.sys.rows,
319  num_columns + 1);
320  }
321  else {
322  PPL_ASSERT(pivot.is_parameter_or_point());
323  reduce_pc_with_pc(row, pivot, dim, dim, num_columns);
324  }
325  }
326  }
327 
328  if (pivot_is_line) {
329  dim_kinds[dim] = LINE;
330  }
331  else {
332  PPL_ASSERT(pivot.is_parameter_or_point());
333  dim_kinds[dim] = PARAMETER;
334  }
335 
336  // Since we are reducing the system to "strong minimal form",
337  // ensure that a positive value follows the leading zeros.
338  if (pivot.expr.get(dim) < 0) {
339  pivot.expr.negate(dim, num_columns);
340  }
341 
342  // Factor this row out of the preceding rows.
343  reduce_reduced<Grid_Generator_System>
344  (ggs.sys.rows, dim, pivot_index, dim, num_columns - 1, dim_kinds);
345 
346  ++pivot_index;
347  }
348  }
349 
350  // Clip any zero rows from the end of the matrix.
351  if (num_rows > pivot_index) {
352 #ifndef NDEBUG
353  const bool ret = rows_are_zero<Grid_Generator_System, Grid_Generator>
354  (ggs,
355  // index of first
356  pivot_index,
357  // index of last
358  ggs.num_rows() - 1,
359  // row size
360  ggs.space_dimension() + 1);
361  PPL_ASSERT(ret == true);
362 #endif
363  ggs.sys.rows.resize(pivot_index);
364  }
365 
366  // Ensure that the parameter divisors are the same as the system
367  // divisor.
368  const Coefficient& system_divisor = ggs.sys.rows[0].expr.inhomogeneous_term();
369  for (dimension_type i = ggs.sys.rows.size() - 1,
370  dim = num_columns - 1; dim > 0; --dim) {
371  switch (dim_kinds[dim]) {
372  case PARAMETER:
373  ggs.sys.rows[i].set_divisor(system_divisor);
374  // Intentionally fall through.
375  case LINE:
376  PPL_ASSERT(ggs.sys.rows[i].OK());
377  --i;
378  break;
379  case GEN_VIRTUAL:
380  break;
381  }
382  }
383 
384  ggs.unset_pending_rows();
385  PPL_ASSERT(ggs.sys.OK());
386 }
static void reduce_pc_with_pc(R &row, R &pivot, dimension_type column, dimension_type start, dimension_type end)
Reduces row using pivot.
void swap(CO_Tree &x, CO_Tree &y)
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type row_index
Definition: PIP_Tree.cc:615
void swap(Grid &x, Grid &y)
Swaps x with y.
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
static void reduce_parameter_with_line(Grid_Generator &row, const Grid_Generator &pivot, dimension_type column, Swapping_Vector< Grid_Generator > &sys, dimension_type num_columns)
Reduce row using pivot.
static void reduce_line_with_line(Grid_Generator &row, Grid_Generator &pivot, dimension_type column)
Reduces the line row using the line pivot.
bool Parma_Polyhedra_Library::Grid::simplify_using_context_assign ( const Grid y)

Assigns to *this a meet-preserving simplification of *this with respect to y. If false is returned, then the intersection is empty.

Exceptions
std::invalid_argumentThrown if *this and y are topology-incompatible or dimension-incompatible.

Definition at line 1691 of file Grid_public.cc.

References add_congruence(), add_congruences(), add_recycled_congruences(), add_space_dimensions_and_embed(), Parma_Polyhedra_Library::Scalar_Products::assign(), Parma_Polyhedra_Library::Grid_Generator_System::begin(), c, con_sys, congruences_are_minimized(), congruences_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::Grid_Generator_System::end(), Parma_Polyhedra_Library::Congruence::expression(), generators_are_minimized(), Parma_Polyhedra_Library::Poly_Con_Relation::implies(), Parma_Polyhedra_Library::Congruence_System::insert(), is_empty(), Parma_Polyhedra_Library::Congruence::is_equality(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), is_included_in(), Parma_Polyhedra_Library::Grid_Generator::is_parameter(), Parma_Polyhedra_Library::Grid_Generator::is_point(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::Congruence::is_tautological(), Parma_Polyhedra_Library::Boundary_NS::le(), m_swap(), minimize(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::Congruence_System::num_rows(), OK(), PPL_DIRTY_TEMP_COEFFICIENT, relation_with(), space_dim, and Parma_Polyhedra_Library::UNIVERSE.

1691  {
1692  Grid& x = *this;
1693  // Dimension-compatibility check.
1694  if (x.space_dim != y.space_dim) {
1695  throw_dimension_incompatible("simplify_using_context_assign(y)", "y", y);
1696  }
1697 
1698  // Filter away the zero-dimensional case.
1699  if (x.space_dim == 0) {
1700  if (y.is_empty()) {
1702  PPL_ASSERT(OK());
1703  return false;
1704  }
1705  else {
1706  return !x.is_empty();
1707  }
1708  }
1709 
1710  // If `y' is empty, the biggest enlargement for `x' is the universe.
1711  if (!y.minimize()) {
1712  Grid gr(x.space_dim, UNIVERSE);
1713  m_swap(gr);
1714  return false;
1715  }
1716 
1717  // If `x' is empty, the intersection is empty.
1718  if (!x.minimize()) {
1719  // Search for a congruence of `y' that is not a tautology.
1720  PPL_ASSERT(y.congruences_are_up_to_date());
1721  Grid gr(x.space_dim, UNIVERSE);
1722  for (dimension_type i = y.con_sys.num_rows(); i-- > 0; ) {
1723  const Congruence& y_con_sys_i = y.con_sys[i];
1724  if (!y_con_sys_i.is_tautological()) {
1725  // Found: we obtain a congruence `c' contradicting the one we
1726  // found, and assign to `x' the grid `gr' with `c' as
1727  // the only congruence.
1728  const Linear_Expression le(y_con_sys_i.expression());
1729  if (y_con_sys_i.is_equality()) {
1730  gr.refine_no_check(le == 1);
1731  break;
1732  }
1733  else {
1734  const Coefficient& y_modulus_i = y_con_sys_i.modulus();
1735  if (y_modulus_i > 1) {
1736  gr.refine_no_check(le == 1);
1737  }
1738  else {
1739  Linear_Expression le2 = le;
1740  le2 *= 2;
1741  gr.refine_no_check(le2 == y_modulus_i);
1742  }
1743  break;
1744  }
1745  }
1746  }
1747  m_swap(gr);
1748  PPL_ASSERT(OK());
1749  return false;
1750  }
1751 
1752  PPL_ASSERT(x.congruences_are_minimized()
1753  && y.generators_are_minimized());
1754 
1755  const Congruence_System& x_cs = x.con_sys;
1756  const dimension_type x_cs_num_rows = x_cs.num_rows();
1757 
1758  // Record into `redundant_by_y' the info about which congruences of
1759  // `x' are redundant in the context `y'. Count the number of
1760  // redundancies found.
1761  std::vector<bool> redundant_by_y(x_cs_num_rows, false);
1762  dimension_type num_redundant_by_y = 0;
1763  for (dimension_type i = 0; i < x_cs_num_rows; ++i) {
1764  if (y.relation_with(x_cs[i]).implies(Poly_Con_Relation::is_included())) {
1765  redundant_by_y[i] = true;
1766  ++num_redundant_by_y;
1767  }
1768  }
1769 
1770  if (num_redundant_by_y < x_cs_num_rows) {
1771 
1772  // Some congruences were not identified as redundant.
1773 
1774  Congruence_System result_cs;
1775  const Congruence_System& y_cs = y.con_sys;
1776  const dimension_type y_cs_num_rows = y_cs.num_rows();
1777  // Compute into `z' the intersection of `x' and `y'.
1778  const bool x_first = (x_cs_num_rows > y_cs_num_rows);
1779  Grid z(x_first ? x : y);
1780  if (x_first) {
1781  z.add_congruences(y_cs);
1782  }
1783  else {
1784  // Only copy (and then recycle) the non-redundant congruences.
1785  Congruence_System tmp_cs;
1786  for (dimension_type i = 0; i < x_cs_num_rows; ++i) {
1787  if (!redundant_by_y[i]) {
1788  tmp_cs.insert(x_cs[i]);
1789  }
1790  }
1791  z.add_recycled_congruences(tmp_cs);
1792  }
1793 
1794  // Congruences are added to `w' until it equals `z'.
1795  // We do not care about minimization or maximization, since
1796  // we are only interested in satisfiability.
1797  Grid w;
1798  w.add_space_dimensions_and_embed(x.space_dim);
1799  // First add the congruences for `y'.
1800  w.add_congruences(y_cs);
1801 
1802  // We apply the following heuristics here: congruences of `x' that
1803  // are not made redundant by `y' are added to `w' depending on
1804  // the number of generators of `y' they rule out (the more generators)
1805  // (they rule out, the sooner they are added). Of course, as soon
1806  // as `w' becomes empty, we stop adding.
1807  std::vector<Ruled_Out_Pair>
1808  ruled_out_vec(x_cs_num_rows - num_redundant_by_y);
1809 
1812 
1813  for (dimension_type i = 0, j = 0; i < x_cs_num_rows; ++i) {
1814  if (!redundant_by_y[i]) {
1815  const Congruence& c = x_cs[i];
1816  const Coefficient& modulus = c.modulus();
1817  div = modulus;
1818 
1819  const Grid_Generator_System& y_gs = y.gen_sys;
1820  dimension_type num_ruled_out_generators = 0;
1821  for (Grid_Generator_System::const_iterator k = y_gs.begin(),
1822  y_gs_end = y_gs.end(); k != y_gs_end; ++k) {
1823  const Grid_Generator& g = *k;
1824  // If the generator is not to be ruled out,
1825  // it must saturate the congruence.
1826  Scalar_Products::assign(sp, c, g);
1827  // If `c' is a proper congruence the scalar product must be
1828  // reduced modulo a (possibly scaled) modulus.
1829  if (c.is_proper_congruence()) {
1830  // If `g' is a parameter the congruence modulus must be scaled
1831  // up by the divisor of the generator.
1832  if (g.is_parameter()) {
1833  sp %= (div * g.divisor());
1834  }
1835  else {
1836  if (g.is_point()) {
1837  sp %= div;
1838  }
1839  }
1840  }
1841  if (sp == 0) {
1842  continue;
1843  }
1844  ++num_ruled_out_generators;
1845  }
1846  ruled_out_vec[j].congruence_index = i;
1847  ruled_out_vec[j].num_ruled_out = num_ruled_out_generators;
1848  ++j;
1849  }
1850  }
1851  std::sort(ruled_out_vec.begin(), ruled_out_vec.end(),
1852  Ruled_Out_Less_Than());
1853 
1854  const bool empty_intersection = (!z.minimize());
1855 
1856  // Add the congruences in the "ruled out" order to `w'
1857  // until the result is the intersection.
1858  for (std::vector<Ruled_Out_Pair>::const_iterator
1859  j = ruled_out_vec.begin(), ruled_out_vec_end = ruled_out_vec.end();
1860  j != ruled_out_vec_end;
1861  ++j) {
1862  const Congruence& c = x_cs[j->congruence_index];
1863  result_cs.insert(c);
1864  w.add_congruence(c);
1865  if ((empty_intersection && w.is_empty())
1866  || (!empty_intersection && w.is_included_in(z))) {
1867  Grid result_gr(x.space_dim, UNIVERSE);
1868  result_gr.add_congruences(result_cs);
1869  x.m_swap(result_gr);
1870  PPL_ASSERT(x.OK());
1871  return !empty_intersection;
1872  }
1873  }
1874  // Cannot exit from here.
1875  PPL_UNREACHABLE;
1876  }
1877 
1878  // All the congruences are redundant so that the simplified grid
1879  // is the universe.
1880  Grid result_gr(x.space_dim, UNIVERSE);
1881  x.m_swap(result_gr);
1882  PPL_ASSERT(x.OK());
1883  return true;
1884 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
The universe element, i.e., the whole vector space.
void set_zero_dim_univ()
Sets status to express that the grid is the universe 0-dimension vector space, clearing all correspon...
static void assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the scalar product of x and y and assigns it to z.
Coefficient c
Definition: PIP_Tree.cc:64
void m_swap(Grid &y)
Swaps *this with grid y. (*this and y can be dimension-incompatible.)
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
bool Parma_Polyhedra_Library::Grid::strictly_contains ( const Grid y) const
inline

Returns true if and only if *this strictly contains y.

Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 371 of file Grid_inlines.hh.

References contains().

Referenced by Parma_Polyhedra_Library::Affine_Space::strictly_contains().

371  {
372  const Grid& x = *this;
373  return x.contains(y) && !y.contains(x);
374 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  other_name,
dimension_type  other_dim 
) const
protected

Definition at line 751 of file Grid_nonpublic.cc.

Referenced by add_congruence(), add_congruences(), and add_constraint().

753  {
754  std::ostringstream s;
755  s << "PPL::Grid::" << method << ":\n"
756  << "this->space_dimension() == " << space_dimension() << ", "
757  << other_name << ".space_dimension() == " << other_dim << ".";
758  throw std::invalid_argument(s.str());
759 }
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  gr_name,
const Grid gr 
) const
protected

Definition at line 762 of file Grid_nonpublic.cc.

References space_dimension().

764  {
765  throw_dimension_incompatible(method, gr_name, gr.space_dimension());
766 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  le_name,
const Linear_Expression le 
) const
protected

Definition at line 769 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Linear_Expression::space_dimension().

771  {
772  throw_dimension_incompatible(method, le_name, le.space_dimension());
773 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  cg_name,
const Congruence cg 
) const
protected

Definition at line 776 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Congruence::space_dimension().

778  {
779  throw_dimension_incompatible(method, cg_name, cg.space_dimension());
780 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  c_name,
const Constraint c 
) const
protected

Definition at line 783 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Constraint::space_dimension().

785  {
786  throw_dimension_incompatible(method, c_name, c.space_dimension());
787 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
Coefficient c
Definition: PIP_Tree.cc:64
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  g_name,
const Grid_Generator g 
) const
protected

Definition at line 790 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Grid_Generator::space_dimension().

792  {
793  throw_dimension_incompatible(method, g_name, g.space_dimension());
794 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  g_name,
const Generator g 
) const
protected

Definition at line 797 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Generator::space_dimension().

799  {
800  throw_dimension_incompatible(method, g_name, g.space_dimension());
801 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  cgs_name,
const Congruence_System cgs 
) const
protected

Definition at line 804 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Congruence_System::space_dimension().

806  {
807  throw_dimension_incompatible(method, cgs_name, cgs.space_dimension());
808 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  cs_name,
const Constraint_System cs 
) const
protected

Definition at line 811 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Constraint_System::space_dimension().

813  {
814  throw_dimension_incompatible(method, cs_name, cs.space_dimension());
815 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  gs_name,
const Grid_Generator_System gs 
) const
protected

Definition at line 818 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().

820  {
821  throw_dimension_incompatible(method, gs_name, gs.space_dimension());
822 }
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
const char *  var_name,
Variable  var 
) const
protected

Definition at line 825 of file Grid_nonpublic.cc.

References Parma_Polyhedra_Library::Variable::space_dimension().

827  {
828  std::ostringstream s;
829  s << "PPL::Grid::" << method << ":" << std::endl
830  << "this->space_dimension() == " << space_dimension() << ", "
831  << var_name << ".space_dimension() == " << var.space_dimension() << ".";
832  throw std::invalid_argument(s.str());
833 }
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible ( const char *  method,
dimension_type  required_space_dim 
) const
protected

Definition at line 837 of file Grid_nonpublic.cc.

838  {
839  std::ostringstream s;
840  s << "PPL::Grid::" << method << ":" << std::endl
841  << "this->space_dimension() == " << space_dimension()
842  << ", required space dimension == " << required_space_dim << ".";
843  throw std::invalid_argument(s.str());
844 }
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void Parma_Polyhedra_Library::Grid::throw_invalid_argument ( const char *  method,
const char *  reason 
)
staticprotected

Definition at line 743 of file Grid_nonpublic.cc.

Referenced by map_space_dimensions().

743  {
744  std::ostringstream s;
745  s << "PPL::Grid::" << method << ":" << std::endl
746  << reason << ".";
747  throw std::invalid_argument(s.str());
748 }
void Parma_Polyhedra_Library::Grid::throw_invalid_constraint ( const char *  method,
const char *  c_name 
)
staticprotected

Definition at line 847 of file Grid_nonpublic.cc.

Referenced by Grid().

848  {
849  std::ostringstream s;
850  s << "PPL::Grid::" << method << ":" << std::endl
851  << c_name << " is not an equality constraint.";
852  throw std::invalid_argument(s.str());
853 }
void Parma_Polyhedra_Library::Grid::throw_invalid_constraints ( const char *  method,
const char *  cs_name 
)
staticprotected

Definition at line 856 of file Grid_nonpublic.cc.

Referenced by Grid().

857  {
858  std::ostringstream s;
859  s << "PPL::Grid::" << method << ":" << std::endl
860  << "the constraint system " << cs_name
861  << " contains inequalities.";
862  throw std::invalid_argument(s.str());
863 }
void Parma_Polyhedra_Library::Grid::throw_invalid_generator ( const char *  method,
const char *  g_name 
)
staticprotected

Definition at line 866 of file Grid_nonpublic.cc.

867  {
868  std::ostringstream s;
869  s << "PPL::Grid::" << method << ":" << std::endl
870  << "*this is an empty grid and "
871  << g_name << " is not a point.";
872  throw std::invalid_argument(s.str());
873 }
void Parma_Polyhedra_Library::Grid::throw_invalid_generators ( const char *  method,
const char *  gs_name 
)
staticprotected

Definition at line 876 of file Grid_nonpublic.cc.

877  {
878  std::ostringstream s;
879  s << "PPL::Grid::" << method << ":" << std::endl
880  << "*this is an empty grid and" << std::endl
881  << "the non-empty generator system " << gs_name << " contains no points.";
882  throw std::invalid_argument(s.str());
883 }
void Parma_Polyhedra_Library::Grid::time_elapse_assign ( const Grid y)

Assigns to *this the result of computing the time-elapse between *this and y.

Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 2641 of file Grid_public.cc.

References clear_congruences_up_to_date(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator::is_point(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), OK(), set_empty(), Parma_Polyhedra_Library::Grid_Generator::set_is_parameter(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::sys, and update_generators().

2641  {
2642  Grid& x = *this;
2643  // Check dimension-compatibility.
2644  if (x.space_dim != y.space_dim) {
2645  throw_dimension_incompatible("time_elapse_assign(y)", "y", y);
2646  }
2647 
2648  // Deal with the zero-dimensional case.
2649  if (x.space_dim == 0) {
2650  if (y.marked_empty()) {
2651  x.set_empty();
2652  }
2653  return;
2654  }
2655 
2656  // If either one of `x' or `y' is empty, the result is empty too.
2657  if (x.marked_empty()) {
2658  return;
2659  }
2660  if (y.marked_empty()
2661  || (!x.generators_are_up_to_date() && !x.update_generators())
2662  || (!y.generators_are_up_to_date() && !y.update_generators())) {
2663  x.set_empty();
2664  return;
2665  }
2666 
2667  // At this point both generator systems are up-to-date.
2668  Grid_Generator_System gs = y.gen_sys;
2669  const dimension_type gs_num_rows = gs.num_rows();
2670 
2672 
2673  for (dimension_type i = gs_num_rows; i-- > 0; ) {
2674  Grid_Generator& g = gs.sys.rows[i];
2675  if (g.is_point()) {
2676  // Transform the point into a parameter.
2677  g.set_is_parameter();
2678  }
2679  }
2680 
2681  PPL_ASSERT(gs.sys.OK());
2682 
2683  if (gs_num_rows == 0) {
2684  // `y' was the grid containing a single point at the origin, so
2685  // the result is `x'.
2686  return;
2687  }
2688 
2689  // Append `gs' to the generators of `x'.
2690 
2691  gen_sys.insert(gs, Recycle_Input());
2692 
2693  x.clear_congruences_up_to_date();
2694  x.clear_generators_minimized();
2695 
2696  PPL_ASSERT(x.OK(true) && y.OK(true));
2697 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
void Parma_Polyhedra_Library::Grid::topological_closure_assign ( )
inline

Assigns to *this its topological closure.

Definition at line 377 of file Grid_inlines.hh.

377  {
378 }
memory_size_type Parma_Polyhedra_Library::Grid::total_memory_in_bytes ( ) const
inline

Returns the total size in bytes of the memory occupied by *this.

Definition at line 229 of file Grid_inlines.hh.

References external_memory_in_bytes().

Referenced by Parma_Polyhedra_Library::Affine_Space::total_memory_in_bytes().

229  {
230  return sizeof(*this) + external_memory_in_bytes();
231 }
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
void Parma_Polyhedra_Library::Grid::unconstrain ( Variable  var)

Computes the cylindrification of *this with respect to space dimension var, assigning the result to *this.

Parameters
varThe space dimension that will be unconstrained.
Exceptions
std::invalid_argumentThrown if var is not a space dimension of *this.

Definition at line 1428 of file Grid_public.cc.

References Parma_Polyhedra_Library::Variable::space_dimension().

1428  {
1429  // Dimension-compatibility check.
1430  if (space_dim < var.space_dimension()) {
1431  throw_dimension_incompatible("unconstrain(var)", var.space_dimension());
1432  }
1433 
1434  // Do something only if the grid is non-empty.
1435  if (marked_empty()
1437  // Empty: do nothing.
1438  return;
1439  }
1440  PPL_ASSERT(generators_are_up_to_date());
1441  Grid_Generator l = grid_line(var);
1442  gen_sys.insert(l, Recycle_Input());
1443  // With the added generator, congruences are out of date.
1446  PPL_ASSERT(OK());
1447 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
bool update_generators() const
Updates and minimizes the generators from the congruences.
void Parma_Polyhedra_Library::Grid::unconstrain ( const Variables_Set vars)

Computes the cylindrification of *this with respect to the set of space dimensions vars, assigning the result to *this.

Parameters
varsThe set of space dimension that will be unconstrained.
Exceptions
std::invalid_argumentThrown if *this is dimension-incompatible with one of the Variable objects contained in vars.

Definition at line 1450 of file Grid_public.cc.

References Parma_Polyhedra_Library::Variables_Set::space_dimension().

1450  {
1451  // The cylindrification with respect to no dimensions is a no-op.
1452  // This case also captures the only legal cylindrification
1453  // of a grid in a 0-dim space.
1454  if (vars.empty()) {
1455  return;
1456  }
1457  // Dimension-compatibility check.
1458  const dimension_type min_space_dim = vars.space_dimension();
1459  if (space_dim < min_space_dim) {
1460  throw_dimension_incompatible("unconstrain(vs)", min_space_dim);
1461  }
1462 
1463  // Do something only if the grid is non-empty.
1464  if (marked_empty()
1466  // Empty: do nothing.
1467  return;
1468  }
1469 
1470  PPL_ASSERT(generators_are_up_to_date());
1471  // Since `gen_sys' is not empty, the space dimension of the inserted
1472  // generators are automatically adjusted.
1473  for (Variables_Set::const_iterator vsi = vars.begin(),
1474  vsi_end = vars.end(); vsi != vsi_end; ++vsi) {
1475  Grid_Generator l = grid_line(Variable(*vsi));
1476  gen_sys.insert(l, Recycle_Input());
1477  }
1478  // Constraints are no longer up-to-date.
1481  PPL_ASSERT(OK());
1482 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
size_t dimension_type
An unsigned integral type for representing space dimensions.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Definition: Grid_inlines.hh:92
void clear_congruences_up_to_date()
Sets status to express that congruences are out of date.
Definition: Grid_inlines.hh:97
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Definition: Grid_public.cc:958
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
bool update_generators() const
Updates and minimizes the generators from the congruences.
void Parma_Polyhedra_Library::Grid::update_congruences ( ) const
private

Updates and minimizes the congruences from the generators.

Definition at line 483 of file Grid_nonpublic.cc.

References simplify().

Referenced by congruence_widening_assign(), intersection_assign(), and is_included_in().

483  {
484  // The caller must ensure that the generators are up to date.
485  PPL_ASSERT(space_dim > 0);
486  PPL_ASSERT(!marked_empty());
487  PPL_ASSERT(!gen_sys.has_no_rows());
488  PPL_ASSERT(gen_sys.space_dimension() > 0);
489 
490  Grid& gr = const_cast<Grid&>(*this);
491 
492  if (!generators_are_minimized()) {
493  gr.simplify(gr.gen_sys, gr.dim_kinds);
494  }
495 
496  // `gen_sys' contained rows before being reduced, so it should
497  // contain at least a single point afterward.
498  PPL_ASSERT(!gen_sys.has_no_rows());
499 
500  // Populate `con_sys' with congruences characterizing the grid
501  // described by `gen_sys'.
502  gr.conversion(gr.gen_sys, gr.con_sys, gr.dim_kinds);
503 
504  // Both systems are minimized.
505  gr.set_congruences_minimized();
506  gr.set_generators_minimized();
507 }
Grid_Generator_System gen_sys
The system of generators.
Definition: Grid_defs.hh:1973
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool Parma_Polyhedra_Library::Grid::update_generators ( ) const
private

Updates and minimizes the generators from the congruences.

Returns
false if and only if *this turns out to be an empty grid.

It is illegal to call this method when the Status field already declares the grid to be empty.

Definition at line 510 of file Grid_nonpublic.cc.

References con_sys, dim_kinds, gen_sys, set_congruences_minimized(), set_empty(), and set_generators_minimized().

Referenced by Parma_Polyhedra_Library::Box< ITV >::Box(), generator_widening_assign(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), map_space_dimensions(), OK(), time_elapse_assign(), and upper_bound_assign().

510  {
511  PPL_ASSERT(space_dim > 0);
512  PPL_ASSERT(!marked_empty());
513  PPL_ASSERT(congruences_are_up_to_date());
514 
515  Grid& x = const_cast<Grid&>(*this);
516 
517  if (!congruences_are_minimized()) {
518  // Either the system of congruences is consistent, or the grid is
519  // empty.
520  if (simplify(x.con_sys, x.dim_kinds)) {
521  x.set_empty();
522  return false;
523  }
524  }
525  // Populate gen_sys with generators characterizing the grid
526  // described by con_sys.
527  conversion(x.con_sys, x.gen_sys, x.dim_kinds);
528 
529  // Both systems are minimized.
530  x.set_congruences_minimized();
531  x.set_generators_minimized();
532  return true;
533 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
static void conversion(Congruence_System &source, Grid_Generator_System &dest, Dimension_Kinds &dim_kinds)
Converts generator system dest to be equivalent to congruence system source.
static bool simplify(Congruence_System &cgs, Dimension_Kinds &dim_kinds)
Converts cgs to upper triangular (i.e. minimized) form.
bool congruences_are_up_to_date() const
Returns true if the system of congruences is up-to-date.
Definition: Grid_inlines.hh:40
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
bool congruences_are_minimized() const
Returns true if the system of congruences is minimized.
Definition: Grid_inlines.hh:50
void Parma_Polyhedra_Library::Grid::upper_bound_assign ( const Grid y)

Assigns to *this the least upper bound of *this and y.

Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 1526 of file Grid_public.cc.

References clear_congruences_up_to_date(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), marked_empty(), OK(), space_dim, and update_generators().

Referenced by difference_assign(), and upper_bound_assign_if_exact().

1526  {
1527  Grid& x = *this;
1528  // Dimension-compatibility check.
1529  if (x.space_dim != y.space_dim) {
1530  throw_dimension_incompatible("upper_bound_assign(y)", "y", y);
1531  }
1532  // The join of a grid `gr' with an empty grid is `gr'.
1533  if (y.marked_empty()) {
1534  return;
1535  }
1536  if (x.marked_empty()) {
1537  x = y;
1538  return;
1539  }
1540 
1541  // If both grids are zero-dimensional, then they are necessarily
1542  // universe grids, and so is their join.
1543  if (x.space_dim == 0) {
1544  return;
1545  }
1546 
1547  // The generators must be up-to-date.
1548  if (!x.generators_are_up_to_date() && !x.update_generators()) {
1549  // Discovered `x' empty when updating generators.
1550  x = y;
1551  return;
1552  }
1553  if (!y.generators_are_up_to_date() && !y.update_generators()) {
1554  // Discovered `y' empty when updating generators.
1555  return;
1556  }
1557  // Match the divisors of the x and y generator systems.
1558  Grid_Generator_System gs(y.gen_sys);
1559  normalize_divisors(x.gen_sys, gs);
1560  x.gen_sys.insert(gs, Recycle_Input());
1561  // Congruences may be out of date and generators may have lost
1562  // minimal form.
1563  x.clear_congruences_up_to_date();
1564  x.clear_generators_minimized();
1565 
1566  // At this point both `x' and `y' are not empty.
1567  PPL_ASSERT(x.OK(true) && y.OK(true));
1568 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
static void normalize_divisors(Grid_Generator_System &sys, Coefficient &divisor, const Grid_Generator *first_point=NULL)
Normalizes the divisors in sys.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool Parma_Polyhedra_Library::Grid::upper_bound_assign_if_exact ( const Grid y)

If the upper bound of *this and y is exact it is assigned to this and true is returned, otherwise false is returned.

Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 1571 of file Grid_public.cc.

References difference_assign(), is_included_in(), marked_empty(), space_dim, Parma_Polyhedra_Library::upper_bound_assign(), and upper_bound_assign().

1571  {
1572  const Grid& x = *this;
1573 
1574  // Dimension-compatibility check.
1575  if (x.space_dim != y.space_dim) {
1576  throw_dimension_incompatible("upper_bound_assign_if_exact(y)", "y", y);
1577  }
1578 
1579  if (x.marked_empty()
1580  || y.marked_empty()
1581  || x.space_dim == 0
1582  || x.is_included_in(y)
1583  || y.is_included_in(x)) {
1584  upper_bound_assign(y);
1585  return true;
1586  }
1587 
1588  // The above test 'x.is_included_in(y)' will ensure the generators of x
1589  // are up to date.
1590  PPL_ASSERT(generators_are_up_to_date());
1591 
1592  Grid x_copy = x;
1593  x_copy.upper_bound_assign(y);
1594  x_copy.difference_assign(y);
1595  if (x_copy.is_included_in(x)) {
1596  upper_bound_assign(y);
1597  return true;
1598  }
1599 
1600  return false;
1601 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Definition: Grid_inlines.hh:45
void upper_bound_assign(const Grid &y)
Assigns to *this the least upper bound of *this and y.
bool Parma_Polyhedra_Library::Grid::upper_triangular ( const Grid_Generator_System sys,
const Dimension_Kinds dim_kinds 
)
staticprivate

If sys is upper triangular return true, else return false.

Definition at line 75 of file Grid_conversion.cc.

References Parma_Polyhedra_Library::Linear_Expression::all_zeroes(), Parma_Polyhedra_Library::Grid_Generator::expr, GEN_VIRTUAL, Parma_Polyhedra_Library::Linear_Expression::get(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().

Referenced by conversion().

76  {
77  dimension_type num_columns = sys.space_dimension() + 1;
78  dimension_type row = sys.num_rows();
79 
80  // Check for easy square fail case.
81  if (row > num_columns) {
82  return false;
83  }
84 
85  // Check triangularity.
86  while (num_columns > 0) {
87  --num_columns;
88  if (dim_kinds[num_columns] == GEN_VIRTUAL) {
89  continue;
90  }
91  const Grid_Generator& gen = sys[--row];
92  // Check diagonal.
93  if (gen.expr.get(num_columns) <= 0) {
94  return false;
95  }
96  // Check elements preceding diagonal.
97  if (!gen.expr.all_zeroes(0, num_columns)) {
98  return false;
99  }
100  }
101 
102  // Check for squareness.
103  return num_columns == row;
104 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void Parma_Polyhedra_Library::Grid::widening_assign ( const Grid y,
unsigned *  tp = NULL 
)

Assigns to *this the result of computing the Grid widening between *this and y.

This widening uses either the congruence or generator systems depending on which of the systems describing x and y are up to date and minimized.

Parameters
yA grid that must be contained in *this;
tpAn optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique).
Exceptions
std::invalid_argumentThrown if *this and y are dimension-incompatible.

Definition at line 441 of file Grid_widenings.cc.

References congruence_widening_assign(), congruences_are_up_to_date(), generator_widening_assign(), generators_are_up_to_date(), and space_dim.

Referenced by limited_congruence_extrapolation_assign(), and limited_extrapolation_assign().

441  {
442  Grid& x = *this;
443 
444  // Dimension-compatibility check.
445  if (x.space_dim != y.space_dim) {
446  throw_dimension_incompatible("widening_assign(y)", "y", y);
447  }
448 
449  // Assume `y' is contained in or equal to `x'.
450  PPL_EXPECT_HEAVY(copy_contains(x, y));
451 
452  // If the `x' congruences are up to date and `y' congruences are up
453  // to date use the congruence widening.
454  if (x.congruences_are_up_to_date() && y.congruences_are_up_to_date()) {
455  x.congruence_widening_assign(y, tp);
456  return;
457  }
458 
459  // If the `x' generators are up to date and `y' generators are up to
460  // date use the generator widening.
461  if (x.generators_are_up_to_date() && y.generators_are_up_to_date()) {
462  x.generator_widening_assign(y, tp);
463  return;
464  }
465 
466  x.congruence_widening_assign(y, tp);
467 }
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void Parma_Polyhedra_Library::Grid::wrap_assign ( const Variables_Set vars,
Bounded_Integer_Type_Width  w,
Bounded_Integer_Type_Representation  r,
Bounded_Integer_Type_Overflow  o,
const Constraint_System cs_p = 0,
unsigned  complexity_threshold = 16,
bool  wrap_individually = true 
)

Wraps the specified dimensions of the vector space.

Parameters
varsThe set of Variable objects corresponding to the space dimensions to be wrapped.
wThe width of the bounded integer type corresponding to all the dimensions to be wrapped.
rThe representation of the bounded integer type corresponding to all the dimensions to be wrapped.
oThe overflow behavior of the bounded integer type corresponding to all the dimensions to be wrapped.
cs_pPossibly null pointer to a constraint system. This argument is for compatibility with wrap_assign() for the other domains and only checked for dimension-compatibility.
complexity_thresholdA precision parameter of the wrapping operator. This argument is for compatibility with wrap_assign() for the other domains and is ignored.
wrap_individuallytrue if the dimensions should be wrapped individually. As wrapping dimensions collectively does not improve the precision, this argument is ignored.
Exceptions
std::invalid_argumentThrown if *this is dimension-incompatible with one of the Variable objects contained in vars or with *cs_p.
Warning
It is assumed that variables in Vars represent integers. Thus, where the extra cost is negligible, the integrality of these variables is enforced; possibly causing a non-integral grid to become empty.

Definition at line 2923 of file Grid_public.cc.

References bounds_no_check(), Parma_Polyhedra_Library::Grid_Generator::coefficient(), Parma_Polyhedra_Library::Coefficient_one(), Parma_Polyhedra_Library::Grid_Generator::divisor(), frequency_no_check(), gen_sys, Parma_Polyhedra_Library::mul_2exp_assign(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::OVERFLOW_IMPOSSIBLE, Parma_Polyhedra_Library::OVERFLOW_UNDEFINED, Parma_Polyhedra_Library::OVERFLOW_WRAPS, PPL_DIRTY_TEMP_COEFFICIENT, Parma_Polyhedra_Library::SIGNED_2_COMPLEMENT, Parma_Polyhedra_Library::Variables_Set::space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and Parma_Polyhedra_Library::UNSIGNED.

2929  {
2930 
2931  // Dimension-compatibility check of `*cs_p', if any.
2932  if (cs_p != 0) {
2933  const dimension_type cs_p_space_dim = cs_p->space_dimension();
2934  if (cs_p->space_dimension() > space_dim) {
2935  throw_dimension_incompatible("wrap_assign(vs, ...)", cs_p_space_dim);
2936  }
2937  }
2938 
2939  // Wrapping no variable is a no-op.
2940  if (vars.empty()) {
2941  return;
2942  }
2943 
2944  // Dimension-compatibility check of `vars'.
2945  const dimension_type min_space_dim = vars.space_dimension();
2946  if (space_dim < min_space_dim) {
2947  throw_dimension_incompatible("wrap_assign(vs, ...)", min_space_dim);
2948  }
2949 
2950  // Wrapping an empty grid is a no-op.
2951  if (marked_empty()) {
2952  return;
2953  }
2954  if (!generators_are_minimized() && !minimize()) {
2955  // Minimizing found `this' empty.
2956  return;
2957  }
2958 
2959  // Set the wrap frequency for variables of width `w'.
2960  // This is independent of the signedness `s'.
2961  PPL_DIRTY_TEMP_COEFFICIENT(wrap_frequency);
2962  mul_2exp_assign(wrap_frequency, Coefficient_one(), w);
2963  // Set `min_value' and `max_value' to the minimum and maximum values
2964  // a variable of width `w' and signedness `s' can take.
2965  PPL_DIRTY_TEMP_COEFFICIENT(min_value);
2966  PPL_DIRTY_TEMP_COEFFICIENT(max_value);
2967  if (r == UNSIGNED) {
2968  min_value = 0;
2969  mul_2exp_assign(max_value, Coefficient_one(), w);
2970  --max_value;
2971  }
2972  else {
2973  PPL_ASSERT(r == SIGNED_2_COMPLEMENT);
2974  mul_2exp_assign(max_value, Coefficient_one(), w-1);
2975  neg_assign(min_value, max_value);
2976  --max_value;
2977  }
2978 
2979  // Generators are up-to-date and minimized.
2980  const Grid gr = *this;
2981 
2982  // Overflow is impossible or wraps.
2983  if (o == OVERFLOW_IMPOSSIBLE || o == OVERFLOW_WRAPS) {
2988  for (Variables_Set::const_iterator i = vars.begin(),
2989  vars_end = vars.end(); i != vars_end; ++i) {
2990  const Variable x(*i);
2991  // Find the frequency and a value for `x' in `gr'.
2992  if (!gr.frequency_no_check(x, f_n, f_d, v_n, v_d)) {
2993  continue;
2994  }
2995  if (f_n == 0) {
2996 
2997  // `x' is a constant in `gr'.
2998  if (v_d != 1) {
2999  // The value for `x' is not integral (`frequency_no_check()'
3000  // ensures that `v_n' and `v_d' have no common divisors).
3001  set_empty();
3002  return;
3003  }
3004 
3005  // `x' is a constant and has an integral value.
3006  if ((v_n > max_value) || (v_n < min_value)) {
3007  // The value is outside the range of the bounded integer type.
3008  if (o == OVERFLOW_IMPOSSIBLE) {
3009  // Then `x' has no possible value and hence set empty.
3010  set_empty();
3011  return;
3012  }
3013  PPL_ASSERT(o == OVERFLOW_WRAPS);
3014  // The value v_n for `x' is wrapped modulo the 'wrap_frequency'.
3015  v_n %= wrap_frequency;
3016  // `v_n' is the value closest to 0 and may be negative.
3017  if (r == UNSIGNED && v_n < 0) {
3018  v_n += wrap_frequency;
3019  }
3020  unconstrain(x);
3021  add_constraint(x == v_n);
3022  }
3023  continue;
3024  }
3025 
3026  // `x' is not a constant in `gr'.
3027  PPL_ASSERT(f_n != 0);
3028 
3029  if (f_d % v_d != 0) {
3030  // Then `x' has no integral value and hence `gr' is set empty.
3031  set_empty();
3032  return;
3033  }
3034  if (f_d != 1) {
3035  // `x' has non-integral values, so add the integrality
3036  // congruence for `x'.
3037  add_congruence((x %= 0) / 1);
3038  }
3039  if (o == OVERFLOW_WRAPS && f_n != wrap_frequency) {
3040  // We know that `x' is not a constant, so, if overflow wraps,
3041  // `x' may wrap to a value modulo the `wrap_frequency'.
3042  add_grid_generator(parameter(wrap_frequency * x));
3043  }
3044  else if ((o == OVERFLOW_IMPOSSIBLE && 2*f_n >= wrap_frequency)
3045  || (f_n == wrap_frequency)) {
3046  // In these cases, `x' can only take a unique (ie constant)
3047  // value.
3048  if (r == UNSIGNED && v_n < 0) {
3049  // `v_n' is the value closest to 0 and may be negative.
3050  v_n += f_n;
3051  }
3052  unconstrain(x);
3053  add_constraint(x == v_n);
3054  }
3055  else {
3056  // If overflow is impossible but the grid frequency is less than
3057  // half the wrap frequency, then there is more than one possible
3058  // value for `x' in the range of the bounded integer type,
3059  // so the grid is unchanged.
3060  PPL_ASSERT(o == OVERFLOW_IMPOSSIBLE && 2*f_n < wrap_frequency);
3061  }
3062  }
3063  return;
3064  }
3065 
3066  PPL_ASSERT(o == OVERFLOW_UNDEFINED);
3067  // If overflow is undefined, then all we know is that the variable
3068  // may take any integer within the range of the bounded integer type.
3069  const Grid_Generator& point = gr.gen_sys[0];
3070  const Coefficient& div = point.divisor();
3071  max_value *= div;
3072  min_value *= div;
3073  for (Variables_Set::const_iterator i = vars.begin(),
3074  vars_end = vars.end(); i != vars_end; ++i) {
3075  const Variable x(*i);
3076  if (!gr.bounds_no_check(x)) {
3077  // `x' is not a constant in `gr'.
3078  // We know that `x' is not a constant, so `x' may wrap to any
3079  // value `x + z' where z is an integer.
3080  if (point.coefficient(x) % div != 0) {
3081  // We know that `x' can take non-integral values, so enforce
3082  // integrality.
3083  unconstrain(x);
3084  add_congruence(x %= 0);
3085  }
3086  else {
3087  // `x' has at least one integral value.
3088  // `x' may also take other non-integral values,
3089  // but checking could be costly so we ignore this.
3090  add_grid_generator(parameter(x));
3091  }
3092  }
3093  else {
3094  // `x' is a constant `v' in `gr'.
3095  const Coefficient& coeff_x = point.coefficient(x);
3096  // `x' should be integral.
3097  if (coeff_x % div != 0) {
3098  set_empty();
3099  return;
3100  }
3101  // If the value `v' for `x' is not within the range for the
3102  // bounded integer type, then `x' may wrap to any value `v + z'
3103  // where `z' is an integer; otherwise `x' is unchanged.
3104  if (coeff_x > max_value || coeff_x < min_value) {
3105  add_grid_generator(parameter(x));
3106  }
3107  }
3108  }
3109 }
void set_empty()
Sets status to express that the grid is empty, clearing all corresponding matrices.
Grid(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a grid having the specified properties.
size_t dimension_type
An unsigned integral type for representing space dimensions.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
On overflow, wrapping takes place.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
On overflow, the result is undefined.
void add_grid_generator(const Grid_Generator &g)
Adds a copy of grid generator g to the system of generators of *this.
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
void unconstrain(Variable var)
Computes the cylindrification of *this with respect to space dimension var, assigning the result to *...
void mul_2exp_assign(GMP_Integer &x, const GMP_Integer &y, unsigned int exp)
dimension_type space_dim
The number of dimensions of the enclosing vector space.
Definition: Grid_defs.hh:1983
void neg_assign(GMP_Integer &x)
Signed binary where negative values are represented by the two's complement of the absolute value...
bool marked_empty() const
Returns true if the grid is known to be empty.
Definition: Grid_inlines.hh:35
void add_congruence(const Congruence &cg)
Adds a copy of congruence cg to *this.
void add_constraint(const Constraint &c)
Adds to *this a congruence equivalent to constraint c.
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
Definition: Grid_inlines.hh:55
bool minimize() const
Minimizes both the congruences and the generators.

Friends And Related Function Documentation

bool operator!= ( const Grid x,
const Grid y 
)
related

Returns true if and only if x and y are different grids.

Note that x and y may be dimension-incompatible grids: in those cases, the value true is returned.

bool operator!= ( const Grid x,
const Grid y 
)
related

Definition at line 366 of file Grid_inlines.hh.

366  {
367  return !(x == y);
368 }
std::ostream & operator<< ( std::ostream &  s,
const Grid gr 
)
related

Output operator.

Writes a textual representation of gr on s: false is written if gr is an empty grid; true is written if gr is a universe grid; a minimized system of congruences defining gr is written otherwise, all congruences in one row separated by ", "s.

std::ostream & operator<< ( std::ostream &  s,
const Grid gr 
)
related

Definition at line 3157 of file Grid_public.cc.

References is_empty(), is_universe(), and minimized_congruences().

3157  {
3158  if (gr.is_empty()) {
3159  s << "false";
3160  }
3161  else if (gr.is_universe()) {
3162  s << "true";
3163  }
3164  else {
3165  s << gr.minimized_congruences();
3166  }
3167  return s;
3168 }
bool operator== ( const Grid x,
const Grid y 
)
related

Returns true if and only if x and y are the same grid.

Note that x and y may be dimension-incompatible grids: in those cases, the value false is returned.

bool operator== ( const Grid x,
const Grid y 
)
friend
bool operator== ( const Grid x,
const Grid y 
)
related

Definition at line 2730 of file Grid_public.cc.

References is_empty(), is_included_in(), marked_empty(), quick_equivalence_test(), space_dim, TVB_FALSE, and TVB_TRUE.

2730  {
2731  if (x.space_dim != y.space_dim) {
2732  return false;
2733  }
2734  if (x.marked_empty()) {
2735  return y.is_empty();
2736  }
2737  if (y.marked_empty()) {
2738  return x.is_empty();
2739  }
2740  if (x.space_dim == 0) {
2741  return true;
2742  }
2743 
2744  switch (x.quick_equivalence_test(y)) {
2745  case Grid::TVB_TRUE:
2746  return true;
2747 
2748  case Grid::TVB_FALSE:
2749  return false;
2750 
2751  default:
2752  if (x.is_included_in(y)) {
2753  if (x.marked_empty()) {
2754  return y.is_empty();
2755  }
2756  return y.is_included_in(x);
2757  }
2758  return false;
2759  }
2760 }
template<typename Interval >
friend class Parma_Polyhedra_Library::Box
friend

Definition at line 1928 of file Grid_defs.hh.

Definition at line 1926 of file Grid_defs.hh.

void swap ( Grid x,
Grid y 
)
related

Swaps x with y.

Referenced by construct(), m_swap(), and simplify().

void swap ( Grid x,
Grid y 
)
related

Definition at line 382 of file Grid_inlines.hh.

References m_swap().

382  {
383  x.m_swap(y);
384 }

Member Data Documentation


The documentation for this class was generated from the following files: