#include <Grid.defs.hh>
Exception Throwers | |
void | throw_runtime_error (const char *method) const |
void | throw_invalid_argument (const char *method, const char *reason) const |
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 *e_name, const Linear_Expression &e) 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 |
void | throw_invalid_constraint (const char *method, const char *c_name) const |
void | throw_invalid_constraints (const char *method, const char *cs_name) const |
void | throw_invalid_generator (const char *method, const char *g_name) const |
void | throw_invalid_generators (const char *method, const char *gs_name) const |
static void | throw_space_dimension_overflow (const char *method, const char *reason) |
Public Types | |
typedef Coefficient | coefficient_type |
The numeric type of coefficients. | |
Public Member Functions | |
Grid (dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE) | |
Builds a grid having the specified properties. | |
Grid (const Congruence_System &cgs) | |
Builds a grid, copying a system of congruences. | |
Grid (Congruence_System &cgs, Recycle_Input dummy) | |
Builds a grid, recycling a system of congruences. | |
Grid (const Constraint_System &cs) | |
Builds a grid, copying a system of constraints. | |
Grid (Constraint_System &cs, Recycle_Input dummy) | |
Builds a grid, recycling a system of constraints. | |
Grid (const Grid_Generator_System &const_gs) | |
Builds a grid, copying a system of grid generators. | |
Grid (Grid_Generator_System &gs, Recycle_Input dummy) | |
Builds a grid, recycling a system of grid generators. | |
template<typename Interval> | |
Grid (const Box< Interval > &box, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a grid out of a box. | |
template<typename U> | |
Grid (const BD_Shape< U > &bd, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a grid out of a bounded-difference shape. | |
template<typename U> | |
Grid (const Octagonal_Shape< U > &os, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a grid out of an octagonal shape. | |
template<typename Box> | |
Grid (const Box &box, From_Covering_Box dummy) | |
Builds a grid out of a generic, interval-based covering box. | |
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 . | |
Grid (const Grid &y, Complexity_Class complexity=ANY_COMPLEXITY) | |
Ordinary copy-constructor. | |
Grid & | operator= (const Grid &y) |
The assignment operator. (*this and y can be dimension-incompatible.). | |
Member Functions that Do Not Modify the Grid | |
dimension_type | space_dimension () const |
Returns the dimension of the vector space enclosing *this . | |
dimension_type | affine_dimension () const |
Returns ![]() *this is empty; otherwise, returns the affine dimension of *this . | |
Constraint_System | constraints () const |
Returns a system of equality constraints satisfied by *this with the same affine dimension as *this . | |
Constraint_System | minimized_constraints () const |
Returns a minimal system of equality constraints satisfied by *this with the same affine dimension as *this . | |
const Congruence_System & | congruences () const |
Returns the system of congruences. | |
const Congruence_System & | minimized_congruences () const |
Returns the system of congruences in minimal form. | |
const Grid_Generator_System & | grid_generators () const |
Returns the system of generators. | |
const Grid_Generator_System & | minimized_grid_generators () const |
Returns the minimized system of generators. | |
Poly_Con_Relation | relation_with (const Congruence &cg) const |
Returns the relations holding between *this and cg . | |
Poly_Gen_Relation | relation_with (const Grid_Generator &g) const |
Returns the relations holding between *this and g . | |
Poly_Gen_Relation | relation_with (const Generator &g) const |
Returns the relations holding between *this and g . | |
Poly_Con_Relation | relation_with (const Constraint &c) const |
Returns the relations holding between *this and c . | |
bool | is_empty () const |
Returns true if and only if *this is an empty grid. | |
bool | is_universe () const |
Returns true if and only if *this is a universe grid. | |
bool | is_topologically_closed () const |
Returns true if and only if *this is a topologically closed subset of the vector space. | |
bool | is_disjoint_from (const Grid &y) const |
Returns true if and only if *this and y are disjoint. | |
bool | is_discrete () const |
Returns true if and only if *this is discrete. | |
bool | is_bounded () const |
Returns true if and only if *this is bounded. | |
bool | contains_integer_point () const |
Returns true if and only if *this contains at least one integer point. | |
bool | constrains (Variable var) const |
Returns true if and only if var is constrained in *this . | |
bool | bounds_from_above (const Linear_Expression &expr) const |
Returns true if and only if expr is bounded in *this . | |
bool | bounds_from_below (const Linear_Expression &expr) const |
Returns true if and only if expr is bounded in *this . | |
bool | maximize (const Linear_Expression &expr, Coefficient &sup_n, Coefficient &sup_d, bool &maximum) const |
Returns true if and only if *this is not empty and expr is bounded from above in *this , in which case the supremum value is computed. | |
bool | maximize (const Linear_Expression &expr, Coefficient &sup_n, Coefficient &sup_d, bool &maximum, Generator &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. | |
bool | minimize (const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum) const |
Returns true if and only if *this is not empty and expr is bounded from below in *this , in which case the infimum value is computed. | |
bool | minimize (const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum, Generator &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. | |
bool | contains (const Grid &y) const |
Returns true if and only if *this contains y . | |
bool | strictly_contains (const Grid &y) const |
Returns true if and only if *this strictly contains y . | |
template<typename Interval> | |
void | get_covering_box (Box< Interval > &box) const |
Writes the covering box for *this into box . | |
bool | OK (bool check_not_empty=false) const |
Checks if all the invariants are satisfied. | |
Space Dimension Preserving Member Functions that May Modify the Grid | |
void | add_congruence (const Congruence &cg) |
Adds a copy of congruence cg to *this . | |
bool | add_congruence_and_minimize (const Congruence &c) |
Adds a copy of congruence cg to the system of congruences of this , reducing the result. | |
void | add_grid_generator (const Grid_Generator &g) |
Adds a copy of grid generator g to the system of generators of *this . | |
bool | add_grid_generator_and_minimize (const Grid_Generator &g) |
Adds a copy of grid generator g to the system of generators of *this , reducing the result. | |
void | add_congruences (const Congruence_System &cgs) |
Adds a copy of each congruence in cgs to *this . | |
void | add_recycled_congruences (Congruence_System &cgs) |
Adds the congruences in cgs to *this. | |
bool | add_congruences_and_minimize (const Congruence_System &cgs) |
Adds a copy of the congruences in cgs to the system of congruences of *this , reducing the result. | |
bool | add_recycled_congruences_and_minimize (Congruence_System &cgs) |
Adds the congruences in cgs to the system of congruences of this , reducing the result. | |
void | add_constraint (const Constraint &c) |
If the constraint c is an equality, it is added to *this . | |
bool | add_constraint_and_minimize (const Constraint &c) |
If the constraint c is an equality, it is added to *this , reducing the result. | |
void | add_constraints (const Constraint_System &cs) |
If all constraints in cs are equality constraints, then copies are added to *this . | |
bool | add_constraints_and_minimize (const Constraint_System &cs) |
If all the constraints in cs are equality constraints, then copies are added to *this , reducing the result. | |
void | add_recycled_constraints (Constraint_System &cs) |
If all the constraints in cs are equality constraints, then they are added to *this . | |
bool | add_recycled_constraints_and_minimize (Constraint_System &cs) |
If all the constraints in cs are equality constraints, then they are added to *this , reducing the result. | |
void | refine_with_congruence (const Congruence &cg) |
Uses a copy of the congruence cg to refine *this . | |
void | refine_with_congruences (const Congruence_System &cgs) |
Uses a copy of the congruences in cgs to refine *this . | |
void | refine_with_constraint (const Constraint &c) |
Uses a copy of the constraint c to refine *this . | |
void | refine_with_constraints (const Constraint_System &cs) |
Uses a copy of the constraints in cs to refine *this . | |
void | add_grid_generators (const Grid_Generator_System &gs) |
Adds a copy of the generators in gs to the system of generators of *this . | |
void | add_recycled_grid_generators (Grid_Generator_System &gs) |
Adds the generators in gs to the system of generators of this . | |
bool | add_grid_generators_and_minimize (const Grid_Generator_System &gs) |
Adds a copy of the generators in gs to the system of generators of *this , reducing the result. | |
bool | add_recycled_grid_generators_and_minimize (Grid_Generator_System &gs) |
Adds the generators in gs to the system of generators of this , reducing the result. | |
void | unconstrain (Variable var) |
Computes the cylindrification of *this with respect to space dimension var , assigning the result to *this . | |
void | unconstrain (const Variables_Set &to_be_unconstrained) |
Computes the cylindrification of *this with respect to the set of space dimensions to_be_unconstrained , assigning the result to *this . | |
void | intersection_assign (const Grid &y) |
Assigns to *this the intersection of *this and y . | |
bool | intersection_assign_and_minimize (const Grid &y) |
Assigns to *this the intersection of *this and y , reducing the result. | |
void | upper_bound_assign (const Grid &y) |
Assigns to *this the least upper bound of *this and y . | |
bool | upper_bound_assign_and_minimize (const Grid &y) |
Assigns to *this the least upper bound of *this and y , reducing the result. | |
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. | |
void | difference_assign (const Grid &y) |
Assigns to *this the grid-difference of *this and y . | |
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. | |
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 . | |
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 . | |
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 ![]() | |
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 ![]() | |
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 ![]() | |
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 ![]() | |
void | bounded_affine_image (Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the image of *this with respect to the bounded affine relation ![]() | |
void | bounded_affine_preimage (Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the preimage of *this with respect to the bounded affine relation ![]() | |
void | time_elapse_assign (const Grid &y) |
Assigns to *this the result of computing the time-elapse between *this and y . | |
void | topological_closure_assign () |
Assigns to *this its topological closure. | |
void | 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. | |
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. | |
void | widening_assign (const Grid &y, unsigned *tp=NULL) |
Assigns to *this the result of computing the Grid widening between *this and y . | |
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 . | |
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 . | |
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 . | |
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. | |
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. | |
void | concatenate_assign (const Grid &y) |
Assigns to *this the concatenation of *this and y , taken in this order. | |
void | remove_space_dimensions (const Variables_Set &to_be_removed) |
Removes all the specified dimensions from the vector space. | |
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 . | |
template<typename Partial_Function> | |
void | map_space_dimensions (const Partial_Function &pfunc) |
Remaps the dimensions of the vector space according to a partial function. | |
void | expand_space_dimension (Variable var, dimension_type m) |
Creates m copies of the space dimension corresponding to var . | |
void | fold_space_dimensions (const Variables_Set &to_be_folded, Variable var) |
Folds the space dimensions in to_be_folded into var . | |
Miscellaneous Member Functions | |
~Grid () | |
Destructor. | |
void | swap (Grid &y) |
Swaps *this with grid y . (*this and y can be dimension-incompatible.). | |
void | ascii_dump () const |
Writes to std::cerr an ASCII representation of *this . | |
void | ascii_dump (std::ostream &s) const |
Writes to s an ASCII representation of *this . | |
void | print () const |
Prints *this to std::cerr using operator<< . | |
bool | ascii_load (std::istream &s) |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise. | |
memory_size_type | total_memory_in_bytes () const |
Returns the total size in bytes of the memory occupied by *this . | |
memory_size_type | external_memory_in_bytes () const |
Returns the size in bytes of the memory managed by *this . | |
int32_t | hash_code () const |
Returns a 32-bit hash code for *this . | |
Static Public Member Functions | |
static dimension_type | max_space_dimension () |
Returns the maximum space dimension all kinds of Grid can handle. | |
static bool | can_recycle_congruence_systems () |
Returns true indicating that this domain has methods that can recycle congruences. | |
static bool | can_recycle_constraint_systems () |
Returns true indicating that this domain has methods that can recycle constraints. | |
Private Types | |
enum | Dimension_Kind { PARAMETER, LINE, GEN_VIRTUAL, PROPER_CONGRUENCE = PARAMETER, CON_VIRTUAL = LINE, EQUALITY = GEN_VIRTUAL } |
enum | Three_Valued_Boolean { TVB_TRUE, TVB_FALSE, TVB_DONT_KNOW } |
typedef std::vector < Dimension_Kind > | Dimension_Kinds |
Private Member Functions | |
void | construct (dimension_type num_dimensions, Degenerate_Element kind) |
Builds a grid universe or empty grid. | |
void | construct (Congruence_System &cgs) |
Builds a grid from a system of congruences. | |
void | construct (Grid_Generator_System &ggs) |
Builds a grid from a system of grid generators. | |
Three_Valued_Boolean | quick_equivalence_test (const Grid &y) const |
Polynomial but incomplete equivalence test between grids. | |
bool | is_included_in (const Grid &y) const |
Returns true if and only if *this is included in y . | |
bool | bounds (const Linear_Expression &expr, const char *method_call) const |
Checks if and how expr is bounded in *this . | |
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 . | |
void | add_congruence_no_check (const Congruence &cg) |
Adds the congruence cg to *this . | |
void | add_constraint_no_check (const Constraint &c) |
Uses the constraint c to refine *this . | |
void | refine_no_check (const Constraint &c) |
Uses the constraint c to refine *this . | |
void | add_space_dimensions (Congruence_System &cgs, Grid_Generator_System &gs, dimension_type dims) |
Adds new space dimensions to the given systems. | |
void | add_space_dimensions (Grid_Generator_System &gs, Congruence_System &cgs, dimension_type dims) |
Adds new space dimensions to the given systems. | |
Private Verifiers: Verify if Individual Flags are Set | |
bool | marked_empty () const |
Returns true if the grid is known to be empty. | |
bool | congruences_are_up_to_date () const |
Returns true if the system of congruences is up-to-date. | |
bool | generators_are_up_to_date () const |
Returns true if the system of generators is up-to-date. | |
bool | congruences_are_minimized () const |
Returns true if the system of congruences is minimized. | |
bool | generators_are_minimized () const |
Returns true if the system of generators is minimized. | |
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. | |
void | set_empty () |
Sets status to express that the grid is empty, clearing all corresponding matrices. | |
void | set_congruences_up_to_date () |
Sets status to express that congruences are up-to-date. | |
void | set_generators_up_to_date () |
Sets status to express that generators are up-to-date. | |
void | set_congruences_minimized () |
Sets status to express that congruences are minimized. | |
void | set_generators_minimized () |
Sets status to express that generators are minimized. | |
State Flag Cleaners: Clear Only the Specified Flag | |
void | clear_empty () |
Clears the status flag indicating that the grid is empty. | |
void | clear_congruences_up_to_date () |
Sets status to express that congruences are out of date. | |
void | clear_generators_up_to_date () |
Sets status to express that generators are out of date. | |
void | clear_congruences_minimized () |
Sets status to express that congruences are no longer minimized. | |
void | clear_generators_minimized () |
Sets status to express that generators are no longer minimized. | |
Updating Matrices | |
void | update_congruences () const |
Updates and minimizes the congruences from the generators. | |
bool | update_generators () const |
Updates and minimizes the generators from the congruences. | |
Minimization of Descriptions | |
bool | minimize () const |
Minimizes both the congruences and the generators. | |
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 . | |
void | select_wider_generators (const Grid &y, Grid_Generator_System &widened_ggs) const |
Copies widened generators from y to widened_ggs . | |
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 . | |
static void | normalize_divisors (Grid_Generator_System &sys) |
Normalizes the divisors in sys . | |
static void | normalize_divisors (Grid_Generator_System &sys, Grid_Generator_System &gen_sys) |
Normalize all the divisors in sys and gen_sys . | |
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 void | conversion (Grid_Generator_System &source, Congruence_System &dest, Dimension_Kinds &dim_kinds) |
Converts congruence system dest to be equivalent to generator system source . | |
static bool | simplify (Congruence_System &cgs, Dimension_Kinds &dim_kinds) |
Converts cgs to upper triangular (i.e. minimized) form. | |
static void | simplify (Grid_Generator_System &gs, Dimension_Kinds &dim_kinds) |
Converts gs to lower triangular (i.e. minimized) form. | |
static void | reduce_line_with_line (Grid_Generator &row, Grid_Generator &pivot, dimension_type col) |
Reduces the line row using the line pivot . | |
static void | reduce_equality_with_equality (Congruence &row, const Congruence &pivot, dimension_type col) |
Reduces the equality row using the equality pivot . | |
template<typename R> | |
static void | reduce_pc_with_pc (R &row, R &pivot, dimension_type col, dimension_type start, dimension_type end) |
Reduces row using pivot . | |
static void | reduce_parameter_with_line (Grid_Generator &row, const Grid_Generator &pivot, dimension_type col, Grid_Generator_System &sys) |
Reduce row using pivot . | |
static void | reduce_congruence_with_equality (Congruence &row, const Congruence &pivot, dimension_type col, Congruence_System &sys) |
Reduce row using pivot . | |
template<typename M, typename R> | |
static void | reduce_reduced (M &sys, dimension_type dim, dimension_type pivot_index, dimension_type start, dimension_type end, const Dimension_Kinds &dim_kinds, bool generators=true) |
Reduce column dim in rows preceding pivot_index in sys . | |
static void | multiply_grid (const Coefficient &multiplier, Congruence &cg, Congruence_System &dest, dimension_type num_rows, dimension_type num_dims) |
Multiply the elements of dest by multiplier . | |
static void | multiply_grid (const Coefficient &multiplier, Grid_Generator &gen, Grid_Generator_System &dest, dimension_type num_rows, dimension_type num_dims) |
Multiply the elements of dest by multiplier . | |
static bool | lower_triangular (const Congruence_System &sys, const Dimension_Kinds &dim_kinds) |
If sys is lower triangular return true , else return false . | |
static bool | upper_triangular (const Grid_Generator_System &sys, const Dimension_Kinds &dim_kinds) |
If sys is upper triangular return true , else return false . | |
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. | |
Private Attributes | |
Congruence_System | con_sys |
The system of congruences. | |
Grid_Generator_System | gen_sys |
The system of generators. | |
Status | status |
The status flags to keep track of the grid's internal state. | |
dimension_type | space_dim |
The number of dimensions of the enclosing vector space. | |
Dimension_Kinds | dim_kinds |
Friends | |
class | Parma_Polyhedra_Library::Grid_Certificate |
class | Parma_Polyhedra_Library::Box |
bool | operator== (const Grid &x, const Grid &y) |
Returns true if and only if x and y are the same grid. | |
Related Functions | |
(Note that these are not member functions.) | |
std::ostream & | operator<< (std::ostream &s, const Grid &gr) |
Output operator. | |
bool | operator!= (const Grid &x, const Grid &y) |
Returns true if and only if x and y are different grids. | |
void | swap (Parma_Polyhedra_Library::Grid &x, Parma_Polyhedra_Library::Grid &y) |
Specializes std::swap . | |
Classes | |
class | Status |
A conjunctive assertion about a grid. More... |
An object of the class Grid represents a rational grid.
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 of the enclosing vector space):
Note that two different grids can be defined on the zero-dimension space: the empty grid and the universe grid .
x
and y
are defined (where they are used) as follows: Variable x(0); Variable y(1);
Congruence_System cgs; cgs.insert((x %= 0) / 2); cgs.insert((y %= 0) / 2); Grid gr(cgs);
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);
Congruence_System cgs; cgs.insert(x - y == 0); Grid gr(cgs);
Grid_Generator_System gs; gs.insert(grid_point(0*x + 0*y)); gs.insert(grid_line(x + y)); Grid gr(gs);
Congruence_System cgs; cgs.insert(x - y == 0); cgs.insert(x %= 0); Grid gr(cgs);
Grid_Generator_System gs; gs.insert(grid_point(0*x + 0*y)); gs.insert(parameter(x + y)); Grid gr(gs);
Grid gr(2);
add_space_dimensions_and_embed
: Grid gr(1); gr.add_congruence(x == 2); gr.add_space_dimensions_and_embed(1);
add_space_dimensions_and_project
: Grid gr(1); gr.add_congruence(x == 2); gr.add_space_dimensions_and_project(1);
add_space_dimensions_and_embed
. After the last line of code, the resulting grid is the singleton set 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);
x
is instead Linear_Expression expr = x + y;
Linear_Expression expr = y;
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);
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
is Linear_Expression expr = x + y;
x
, for example, the affine expression Linear_Expression expr = y;
Variable z(2); Variable w(3);
remove_space_dimensions
: Grid_Generator_System gs; gs.insert(grid_point(3*x + y +0*z + 2*w)); Grid gr(gs); Variables_Set to_be_removed; to_be_removed.insert(y); to_be_removed.insert(z); gr.remove_space_dimensions(to_be_removed);
remove_space_dimensions
operator, unexpected results can be obtained. For instance, by using the following code we would obtain a different result: set<Variable> to_be_removed1; to_be_removed1.insert(y); gr.remove_space_dimensions(to_be_removed1); set<Variable> to_be_removed2; to_be_removed2.insert(z); gr.remove_space_dimensions(to_be_removed2);
to_be_removed2
we are actually removing variable 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 352 of file Grid.defs.hh.
typedef std::vector<Dimension_Kind> Parma_Polyhedra_Library::Grid::Dimension_Kinds [private] |
Definition at line 2339 of file Grid.defs.hh.
enum Parma_Polyhedra_Library::Grid::Dimension_Kind [private] |
Definition at line 2330 of file Grid.defs.hh.
enum Parma_Polyhedra_Library::Grid::Three_Valued_Boolean [private] |
Parma_Polyhedra_Library::Grid::Grid | ( | dimension_type | num_dimensions = 0 , |
|
Degenerate_Element | kind = UNIVERSE | |||
) | [inline, explicit] |
Builds a grid having the specified properties.
num_dimensions | The number of dimensions of the vector space enclosing the grid; | |
kind | Specifies whether the universe or the empty grid has to be built. |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 121 of file Grid.inlines.hh.
References construct(), and OK().
00123 : con_sys(), 00124 gen_sys(num_dimensions > max_space_dimension() 00125 ? (throw_space_dimension_overflow("Grid(n, k)", 00126 "n exceeds the maximum " 00127 "allowed space dimension"), 00128 0) 00129 : num_dimensions) { 00130 construct(num_dimensions, kind); 00131 assert(OK()); 00132 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Congruence_System & | cgs | ) | [inline, explicit] |
Builds a grid, copying a system of congruences.
The grid inherits the space dimension of the congruence system.
cgs | The system of congruences defining the grid. |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 135 of file Grid.inlines.hh.
References construct().
00136 : con_sys(cgs.space_dimension() > max_space_dimension() 00137 ? throw_space_dimension_overflow("Grid(cgs)", 00138 "the space dimension of cgs " 00139 "exceeds the maximum allowed " 00140 "space dimension"), 0 00141 : cgs.space_dimension()), 00142 gen_sys(cgs.space_dimension()) { 00143 Congruence_System cgs_copy(cgs); 00144 construct(cgs_copy); 00145 }
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.
cgs | The system of congruences defining the grid. Its data-structures may be recycled to build the grid. | |
dummy | A dummy tag to syntactically differentiate this one from the other constructors. |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 148 of file Grid.inlines.hh.
References construct().
00149 : con_sys(cgs.space_dimension() > max_space_dimension() 00150 ? throw_space_dimension_overflow("Grid(cgs, recycle)", 00151 "the space dimension of cgs " 00152 "exceeds the maximum allowed " 00153 "space dimension"), 0 00154 : cgs.space_dimension()), 00155 gen_sys(cgs.space_dimension()) { 00156 construct(cgs); 00157 }
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.
cs | The system of constraints defining the grid. |
std::invalid_argument | Thrown if the constraint system cs contains inequality constraints. | |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 59 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().
00060 : con_sys(cs.space_dimension() > max_space_dimension() 00061 ? throw_space_dimension_overflow("Grid(cs)", 00062 "the space dimension of cs " 00063 "exceeds the maximum allowed " 00064 "space dimension"), 0 00065 : cs.space_dimension()), 00066 gen_sys(cs.space_dimension()) { 00067 space_dim = cs.space_dimension(); 00068 00069 if (space_dim == 0) { 00070 // See if an inconsistent constraint has been passed. 00071 for (Constraint_System::const_iterator i = cs.begin(), 00072 cs_end = cs.end(); i != cs_end; ++i) 00073 if (i->is_inconsistent()) { 00074 // Inconsistent constraint found: the grid is empty. 00075 status.set_empty(); 00076 // Insert the zero dim false congruence system into `con_sys'. 00077 // `gen_sys' is already in empty form. 00078 con_sys.insert(Congruence::zero_dim_false()); 00079 assert(OK()); 00080 return; 00081 } 00082 set_zero_dim_univ(); 00083 assert(OK()); 00084 return; 00085 } 00086 00087 Congruence_System cgs; 00088 cgs.insert(0*Variable(space_dim - 1) %= 1); 00089 for (Constraint_System::const_iterator i = cs.begin(), 00090 cs_end = cs.end(); i != cs_end; ++i) 00091 if (i->is_equality()) 00092 cgs.insert(*i); 00093 else 00094 throw_invalid_constraints("Grid(cs)", "cs"); 00095 construct(cgs); 00096 }
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.
cs | The system of constraints defining the grid. Its data-structures may be recycled to build the grid. | |
dummy | A dummy tag to syntactically differentiate this one from the other constructors. |
std::invalid_argument | Thrown if the constraint system cs contains inequality constraints. | |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 98 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().
00099 : con_sys(cs.space_dimension() > max_space_dimension() 00100 ? throw_space_dimension_overflow("Grid(cs, recycle)", 00101 "the space dimension of cs " 00102 "exceeds the maximum allowed " 00103 "space dimension"), 0 00104 : cs.space_dimension()), 00105 gen_sys(cs.space_dimension()) { 00106 space_dim = cs.space_dimension(); 00107 00108 if (space_dim == 0) { 00109 // See if an inconsistent constraint has been passed. 00110 for (Constraint_System::const_iterator i = cs.begin(), 00111 cs_end = cs.end(); i != cs_end; ++i) 00112 if (i->is_inconsistent()) { 00113 // Inconsistent constraint found: the grid is empty. 00114 status.set_empty(); 00115 // Insert the zero dim false congruence system into `con_sys'. 00116 // `gen_sys' is already in empty form. 00117 con_sys.insert(Congruence::zero_dim_false()); 00118 assert(OK()); 00119 return; 00120 } 00121 set_zero_dim_univ(); 00122 assert(OK()); 00123 return; 00124 } 00125 00126 Congruence_System cgs; 00127 cgs.insert(0*Variable(space_dim - 1) %= 1); 00128 for (Constraint_System::const_iterator i = cs.begin(), 00129 cs_end = cs.end(); i != cs_end; ++i) 00130 if (i->is_equality()) 00131 cgs.insert(*i); 00132 else 00133 throw_invalid_constraint("Grid(cs)", "cs"); 00134 construct(cgs); 00135 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Grid_Generator_System & | const_gs | ) | [inline, explicit] |
Builds a grid, copying a system of grid generators.
The grid inherits the space dimension of the generator system.
const_gs | The system of generators defining the grid. |
std::invalid_argument | Thrown if the system of generators is not empty but has no points. | |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 160 of file Grid.inlines.hh.
References construct().
00161 : con_sys(ggs.space_dimension() > max_space_dimension() 00162 ? throw_space_dimension_overflow("Grid(ggs)", 00163 "the space dimension of ggs " 00164 "exceeds the maximum allowed " 00165 "space dimension"), 0 00166 : ggs.space_dimension()), 00167 gen_sys(ggs.space_dimension()) { 00168 Grid_Generator_System ggs_copy(ggs); 00169 construct(ggs_copy); 00170 }
Parma_Polyhedra_Library::Grid::Grid | ( | Grid_Generator_System & | gs, | |
Recycle_Input | dummy | |||
) | [inline] |
Builds a grid, recycling a system of grid generators.
The grid inherits the space dimension of the generator system.
gs | The system of generators defining the grid. Its data-structures may be recycled to build the grid. | |
dummy | A dummy tag to syntactically differentiate this one from the other constructors. |
std::invalid_argument | Thrown if the system of generators is not empty but has no points. | |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 173 of file Grid.inlines.hh.
References construct().
00174 : con_sys(ggs.space_dimension() > max_space_dimension() 00175 ? throw_space_dimension_overflow("Grid(ggs, recycle)", 00176 "the space dimension of ggs " 00177 "exceeds the maximum allowed " 00178 "space dimension"), 0 00179 : ggs.space_dimension()), 00180 gen_sys(ggs.space_dimension()) { 00181 construct(ggs); 00182 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Box< Interval > & | box, | |
Complexity_Class | complexity = ANY_COMPLEXITY | |||
) | [inline, 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.
box | The box representing the grid to be built. | |
complexity | This argument is ignored as the algorithm used has polynomial complexity. |
std::length_error | Thrown if the space dimension of box exceeds the maximum allowed space dimension. |
Definition at line 35 of file Grid.templates.hh.
References con_sys, Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), gen_sys, Parma_Polyhedra_Library::Box< ITV >::get_lower_bound(), Parma_Polyhedra_Library::Box< ITV >::get_upper_bound(), Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), 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(), OK(), Parma_Polyhedra_Library::Grid_Generator::scale_to_divisor(), set_congruences_up_to_date(), set_empty(), set_generators_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::set_sorted(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Box< ITV >::space_dimension(), TEMP_INTEGER, throw_space_dimension_overflow(), and Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows().
00037 : con_sys(), 00038 gen_sys() { 00039 if (box.space_dimension() > max_space_dimension()) 00040 throw_space_dimension_overflow("Grid(box, from_bounding_box)", 00041 "the space dimension of box " 00042 "exceeds the maximum allowed " 00043 "space dimension"); 00044 00045 space_dim = box.space_dimension(); 00046 00047 if (box.is_empty()) { 00048 // Empty grid. 00049 set_empty(); 00050 assert(OK()); 00051 return; 00052 } 00053 00054 if (space_dim == 0) 00055 set_zero_dim_univ(); 00056 else { 00057 // Initialize the space dimension as indicated by the box. 00058 con_sys.increase_space_dimension(space_dim); 00059 // Add congruences and generators according to `box'. 00060 TEMP_INTEGER(l_n); 00061 TEMP_INTEGER(l_d); 00062 TEMP_INTEGER(u_n); 00063 TEMP_INTEGER(u_d); 00064 gen_sys.insert(grid_point(0*Variable(space_dim-1))); 00065 Grid_Generator& point = gen_sys[0]; 00066 for (dimension_type k = space_dim; k-- > 0; ) { 00067 bool closed = false; 00068 // TODO: Consider producing the system(s) in minimized form. 00069 if (box.get_lower_bound(k, closed, l_n, l_d)) { 00070 if (box.get_upper_bound(k, closed, u_n, u_d)) 00071 if (l_n * u_d == u_n * l_d) { 00072 // A point interval sets dimension k of every point to a 00073 // single value. 00074 con_sys.insert(l_d * Variable(k) == l_n); 00075 00076 // Scale the point to use as divisor the lcm of the 00077 // divisors of the existing point and the lower bound. 00078 const Coefficient& point_divisor = point.divisor(); 00079 gcd_assign(u_n, l_d, point_divisor); 00080 // `u_n' now holds the gcd. 00081 exact_div_assign(u_n, point_divisor, u_n); 00082 if (l_d < 0) 00083 neg_assign(u_n); 00084 // l_d * u_n == abs(l_d * (point_divisor / gcd(l_d, point_divisor))) 00085 point.scale_to_divisor(l_d * u_n); 00086 // Set dimension k of the point to the lower bound. 00087 if (l_d < 0) 00088 neg_assign(u_n); 00089 // point[k + 1] = l_n * point_divisor / gcd(l_d, point_divisor) 00090 point[k + 1] = l_n * u_n; 00091 00092 continue; 00093 } 00094 } 00095 // A universe interval allows any value in dimension k. 00096 gen_sys.insert(grid_line(Variable(k))); 00097 } 00098 set_congruences_up_to_date(); 00099 set_generators_up_to_date(); 00100 gen_sys.unset_pending_rows(); 00101 gen_sys.set_sorted(false); 00102 } 00103 00104 assert(OK()); 00105 }
Parma_Polyhedra_Library::Grid::Grid | ( | const BD_Shape< U > & | bd, | |
Complexity_Class | complexity = ANY_COMPLEXITY | |||
) | [inline, explicit] |
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.
bd | The BDS representing the grid to be built. | |
complexity | This argument is ignored as the algorithm used has polynomial complexity. |
std::length_error | Thrown if the space dimension of bd exceeds the maximum allowed space dimension. |
Definition at line 186 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::BD_Shape< T >::congruences(), and construct().
00188 : con_sys(bd.space_dimension() > max_space_dimension() 00189 ? throw_space_dimension_overflow("Grid(bd)", 00190 "the space dimension of bd " 00191 "exceeds the maximum allowed " 00192 "space dimension"), 0 00193 : bd.space_dimension()), 00194 gen_sys(bd.space_dimension()) { 00195 Congruence_System cgs = bd.congruences(); 00196 construct(cgs); 00197 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Octagonal_Shape< U > & | os, | |
Complexity_Class | complexity = ANY_COMPLEXITY | |||
) | [inline, explicit] |
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.
os | The octagonal shape representing the grid to be built. | |
complexity | This argument is ignored as the algorithm used has polynomial complexity. |
std::length_error | Thrown if the space dimension of os exceeds the maximum allowed space dimension. |
Definition at line 201 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Octagonal_Shape< T >::congruences(), and construct().
00203 : con_sys(os.space_dimension() > max_space_dimension() 00204 ? throw_space_dimension_overflow("Grid(os)", 00205 "the space dimension of os " 00206 "exceeds the maximum allowed " 00207 "space dimension"), 0 00208 : os.space_dimension()), 00209 gen_sys(os.space_dimension()) { 00210 Congruence_System cgs = os.congruences(); 00211 construct(cgs); 00212 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Box & | box, | |
From_Covering_Box | dummy | |||
) | [inline] |
Builds a grid out of a generic, interval-based covering box.
The covering box is a set of upper and lower values for each dimension. When a covering box is tiled onto empty space the corners of the tiles form a rectilinear grid.
A box interval with only one bound fixes the values of all grid points in the dimension associated with the box to the value of the bound. A box interval which has upper and lower bounds of equal value allows all grid points with any value in the dimension associated with the interval. The presence of a universe interval results in the empty grid. The empty box produces the empty grid of the same dimension as the box.
box | The covering box representing the grid to be built; | |
dummy | A dummy tag to make this constructor syntactically unique. |
std::length_error | Thrown if the space dimension of box exceeds the maximum allowed space dimension. | |
std::invalid_argument | Thrown if box contains any topologically open bounds. |
dimension_type space_dimension() const
bool is_empty() const
true
if and only if the covering box describes the empty set. bool get_lower_bound(dimension_type k, bool& closed, Coefficient& n, Coefficient& d) const
k
-th space dimension. If false
. Otherwise, set closed
, n
and d
as follows: closed
is set to true
if the lower boundary of false
otherwise; n
and d
are assigned the integers bool get_upper_bound(dimension_type k, bool& closed, Coefficient& n, Coefficient& d) const
k
-th space dimension. If false
. Otherwise, set closed
, n
and d
as follows: closed
is set to true
if the upper boundary of false
otherwise; n
and d
are assigned the integers Definition at line 108 of file Grid.templates.hh.
References con_sys, Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), gen_sys, Parma_Polyhedra_Library::Box< ITV >::get_lower_bound(), Parma_Polyhedra_Library::Box< ITV >::get_upper_bound(), Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Box< ITV >::is_empty(), max_space_dimension(), normalize_divisors(), OK(), Parma_Polyhedra_Library::Grid_Generator::scale_to_divisor(), set_congruences_up_to_date(), set_empty(), set_generators_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::set_sorted(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Box< ITV >::space_dimension(), TEMP_INTEGER, throw_invalid_argument(), throw_space_dimension_overflow(), and Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows().
00109 : con_sys(), 00110 gen_sys() { 00111 00112 if (box.space_dimension() > max_space_dimension()) 00113 throw_space_dimension_overflow("Grid(box, from_covering_box)", 00114 "the space dimension of box " 00115 "exceeds the maximum allowed " 00116 "space dimension"); 00117 00118 space_dim = box.space_dimension(); 00119 00120 TEMP_INTEGER(l_n); 00121 TEMP_INTEGER(l_d); 00122 00123 // Check that all bounds are closed. This check must be done before 00124 // the empty test below, as an open bound might mean an empty box. 00125 for (dimension_type k = space_dim; k-- > 0; ) { 00126 bool closed = false; 00127 // FIXME: Perhaps introduce box::is_bounded_and_closed. 00128 if (box.get_lower_bound(k, closed, l_n, l_d) && !closed) 00129 throw_invalid_argument("Grid(box, from_covering_box)", "box"); 00130 if (box.get_upper_bound(k, closed, l_n, l_d) && !closed) 00131 throw_invalid_argument("Grid(box, from_covering_box)", "box"); 00132 } 00133 00134 if (box.is_empty()) { 00135 // Empty grid. 00136 set_empty(); 00137 assert(OK()); 00138 return; 00139 } 00140 00141 if (space_dim == 0) 00142 set_zero_dim_univ(); 00143 else { 00144 // Initialize the space dimension as indicated by the box. 00145 con_sys.increase_space_dimension(space_dim); 00146 // Add congruences according to `box'. 00147 TEMP_INTEGER(u_n); 00148 TEMP_INTEGER(u_d); 00149 TEMP_INTEGER(d); 00150 gen_sys.insert(grid_point(0*Variable(space_dim-1))); 00151 Grid_Generator& point = gen_sys[0]; 00152 for (dimension_type k = space_dim; k-- > 0; ) { 00153 bool closed = false; 00154 // TODO: Consider producing the system(s) in minimized form. 00155 if (box.get_lower_bound(k, closed, l_n, l_d)) { 00156 00157 const Coefficient& point_divisor = point.divisor(); 00158 assert(l_d > 0); 00159 assert(point_divisor > 0); 00160 // Use `d' to hold the gcd. 00161 gcd_assign(d, l_d, point_divisor); 00162 // Scale the point to use as divisor the lcm of the existing 00163 // point divisor and the divisor of the lower bound. 00164 exact_div_assign(d, point_divisor, d); 00165 // l_d * d == abs(l_d) * (point_divisor / gcd(l_d, point_divisor)) 00166 point.scale_to_divisor(l_d * d); 00167 // Set dimension k of the point to the lower bound. 00168 // point[k + 1] = l_n * (point_divisor / gcd(l_d, point_divisor)) 00169 point[k + 1] = l_n * d; 00170 00171 if (box.get_upper_bound(k, closed, u_n, u_d)) { 00172 if (l_n * u_d == u_n * l_d) { 00173 // A point interval allows any point along the dimension 00174 // k axis. 00175 gen_sys.insert(grid_line(Variable(k))); 00176 continue; 00177 } 00178 assert(l_d > 0); 00179 assert(u_d > 0); 00180 gcd_assign(d, l_d, u_d); 00181 // `d' is the gcd of the divisors. 00182 exact_div_assign(l_d, l_d, d); 00183 exact_div_assign(d, u_d, d); 00184 l_n *= d; 00185 // `l_d' is now the smallest integer expression of the size of 00186 // the original l_d relative to u_d. 00187 u_n = (u_n * l_d) - l_n; 00188 // `u_n' is now the distance between u_n and l_n (given a 00189 // divisor of lcm of l_d and u_d. 00190 l_d *= u_d; 00191 // `l_d' is now the lcm of the divisors. 00192 con_sys.insert((l_d * Variable(k) %= l_n) / u_n); 00193 gen_sys.insert(parameter(u_n * Variable(k), l_d)); 00194 } 00195 else 00196 // An interval bounded only from below produces an 00197 // equality. 00198 con_sys.insert(l_d * Variable(k) == l_n); 00199 } 00200 else 00201 if (box.get_upper_bound(k, closed, u_n, u_d)) { 00202 const Coefficient& point_divisor = point.divisor(); 00203 assert(u_d > 0); 00204 assert(point_divisor > 0); 00205 // Use `d' to hold the gcd. 00206 gcd_assign(d, u_d, point_divisor); 00207 // Scale the point to use as divisor the lcm of the existing 00208 // point divisor and the divisor of the lower bound. 00209 exact_div_assign(d, point_divisor, d); 00210 // u_d * d == abs(u_d) * (point_divisor / gcd(u_d, point_divisor)) 00211 point.scale_to_divisor(u_d * d); 00212 // Set dimension k of the point to the lower bound. 00213 // point[k + 1] = u_n * (point_divisor / gcd(u_d, point_divisor)) 00214 point[k + 1] = u_n * d; 00215 00216 // An interval bounded only from above produces an equality. 00217 con_sys.insert(u_d * Variable(k) == u_n); 00218 } 00219 else { 00220 // Any universe interval produces an empty grid. 00221 set_empty(); 00222 assert(OK()); 00223 return; 00224 } 00225 } 00226 normalize_divisors(gen_sys); 00227 set_congruences_up_to_date(); 00228 set_generators_up_to_date(); 00229 gen_sys.set_sorted(false); 00230 gen_sys.unset_pending_rows(); 00231 } 00232 00233 assert(OK()); 00234 }
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.
ph | The polyhedron. | |
complexity | The complexity class. |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 137 of file Grid_public.cc.
References Parma_Polyhedra_Library::Linear_Row::all_homogeneous_terms_are_zero(), Parma_Polyhedra_Library::ANY_COMPLEXITY, Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::Polyhedron::constraints(), Parma_Polyhedra_Library::Polyhedron::constraints_are_minimized(), Parma_Polyhedra_Library::Polyhedron::constraints_are_up_to_date(), construct(), gen_sys, Parma_Polyhedra_Library::Polyhedron::generators(), Parma_Polyhedra_Library::Polyhedron::generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Polyhedron::is_empty(), Parma_Polyhedra_Library::Polyhedron::marked_empty(), Parma_Polyhedra_Library::Polyhedron::minimize(), OK(), set_empty(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Polyhedron::space_dimension(), and TEMP_INTEGER.
00139 : con_sys(ph.space_dimension() > max_space_dimension() 00140 ? throw_space_dimension_overflow("Grid(ph)", 00141 "the space dimension of ph " 00142 "exceeds the maximum allowed " 00143 "space dimension"), 0 00144 : ph.space_dimension()), 00145 gen_sys(ph.space_dimension()) { 00146 space_dim = ph.space_dimension(); 00147 00148 // A zero-dim polyhedron causes no complexity problems. 00149 if (space_dim == 0) { 00150 if (ph.is_empty()) 00151 set_empty(); 00152 else 00153 set_zero_dim_univ(); 00154 return; 00155 } 00156 00157 // A polyhedron known to be empty causes no complexity problems. 00158 if (ph.marked_empty()) { 00159 set_empty(); 00160 return; 00161 } 00162 00163 bool use_constraints = ph.constraints_are_minimized() 00164 || !ph.generators_are_up_to_date(); 00165 00166 // Minimize the constraint description if it is needed and 00167 // the complexity allows it. 00168 if (use_constraints && complexity == ANY_COMPLEXITY) 00169 if (!ph.minimize()) { 00170 set_empty(); 00171 return; 00172 } 00173 00174 if (use_constraints) { 00175 // Only the equality constraints need be used. 00176 assert(ph.constraints_are_up_to_date()); 00177 const Constraint_System& cs = ph.constraints(); 00178 Congruence_System cgs; 00179 cgs.insert(0*Variable(space_dim - 1) %= 1); 00180 for (Constraint_System::const_iterator i = cs.begin(), 00181 cs_end = cs.end(); i != cs_end; ++i) 00182 if (i->is_equality()) 00183 cgs.insert(*i); 00184 construct(cgs); 00185 } 00186 else { 00187 gen_sys = Grid_Generator_System(space_dim); 00188 // First find a point or closure point and convert it to a 00189 // grid point and add to the (initially empty) set of grid generators. 00190 assert(ph.generators_are_up_to_date()); 00191 const Generator_System& gs = ph.generators(); 00192 Grid_Generator_System ggs(space_dim); 00193 Linear_Expression point_expr; 00194 Coefficient point_divisor; 00195 for (Generator_System::const_iterator g = gs.begin(), 00196 gs_end = gs.end(); g != gs_end; ++g) { 00197 if (g->is_point() || g->is_closure_point()) { 00198 for (dimension_type i = space_dim; i-- > 0; ) { 00199 const Variable v(i); 00200 point_expr += g->coefficient(v) * v; 00201 point_divisor = g->divisor(); 00202 } 00203 ggs.insert(grid_point(point_expr, point_divisor)); 00204 break; 00205 } 00206 } 00207 // Add grid lines for all the other generators. 00208 // If the polyhedron's generator is a (closure) point, the grid line must 00209 // have the direction given by a line that joins the grid point already 00210 // inserted and the new point. 00211 TEMP_INTEGER(coeff); 00212 for (Generator_System::const_iterator g = gs.begin(), 00213 gs_end = gs.end(); g != gs_end; ++g) { 00214 Linear_Expression e; 00215 if (g->is_point() || g->is_closure_point()) { 00216 Coefficient g_divisor = g->divisor(); 00217 for (dimension_type i = space_dim; i-- > 0; ) { 00218 const Variable v(i); 00219 coeff = point_expr.coefficient(v) * g_divisor; 00220 coeff -= g->coefficient(v) * point_divisor; 00221 e += coeff * v; 00222 } 00223 if (e.all_homogeneous_terms_are_zero()) 00224 continue; 00225 } 00226 else 00227 for (dimension_type i = space_dim; i-- > 0; ) { 00228 const Variable v(i); 00229 e += g->coefficient(v) * v; 00230 } 00231 ggs.insert(grid_line(e)); 00232 } 00233 construct(ggs); 00234 } 00235 assert(OK()); 00236 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Grid & | y, | |
Complexity_Class | complexity = ANY_COMPLEXITY | |||
) |
Ordinary copy-constructor.
The complexity argument is ignored.
Definition at line 37 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::increase_space_dimension(), and space_dim.
00038 : con_sys(), 00039 gen_sys(), 00040 status(y.status), 00041 space_dim(y.space_dim), 00042 dim_kinds(y.dim_kinds) { 00043 if (space_dim == 0) { 00044 con_sys = y.con_sys; 00045 gen_sys = y.gen_sys; 00046 } 00047 else { 00048 if (y.congruences_are_up_to_date()) 00049 con_sys = y.con_sys; 00050 else 00051 con_sys.increase_space_dimension(space_dim); 00052 if (y.generators_are_up_to_date()) 00053 gen_sys = y.gen_sys; 00054 else 00055 gen_sys = Grid_Generator_System(y.space_dim); 00056 } 00057 }
Parma_Polyhedra_Library::Grid::~Grid | ( | ) | [inline] |
dimension_type Parma_Polyhedra_Library::Grid::max_space_dimension | ( | ) | [inline, static] |
Returns the maximum space dimension all kinds of Grid can handle.
Definition at line 110 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid_Generator_System::max_space_dimension(), and Parma_Polyhedra_Library::Congruence_System::max_space_dimension().
Referenced by add_space_dimensions_and_embed(), add_space_dimensions_and_project(), concatenate_assign(), construct(), expand_space_dimension(), and Grid().
00110 { 00111 // One dimension is reserved to have a value of type dimension_type 00112 // that does not represent a legal dimension. 00113 return std::min(std::numeric_limits<dimension_type>::max() - 1, 00114 std::min(Congruence_System::max_space_dimension(), 00115 Grid_Generator_System::max_space_dimension() 00116 ) 00117 ); 00118 }
bool Parma_Polyhedra_Library::Grid::can_recycle_congruence_systems | ( | ) | [inline, static] |
Returns true indicating that this domain has methods that can recycle congruences.
Definition at line 297 of file Grid.inlines.hh.
bool Parma_Polyhedra_Library::Grid::can_recycle_constraint_systems | ( | ) | [inline, static] |
Returns true indicating that this domain has methods that can recycle constraints.
Definition at line 292 of file Grid.inlines.hh.
The assignment operator. (*this
and y
can be dimension-incompatible.).
Definition at line 239 of file Grid_public.cc.
References con_sys, congruences_are_up_to_date(), dim_kinds, gen_sys, generators_are_up_to_date(), marked_empty(), set_empty(), set_zero_dim_univ(), space_dim, and status.
00239 { 00240 space_dim = y.space_dim; 00241 dim_kinds = y.dim_kinds; 00242 if (y.marked_empty()) 00243 set_empty(); 00244 else if (space_dim == 0) 00245 set_zero_dim_univ(); 00246 else { 00247 status = y.status; 00248 if (y.congruences_are_up_to_date()) 00249 con_sys = y.con_sys; 00250 if (y.generators_are_up_to_date()) 00251 gen_sys = y.gen_sys; 00252 } 00253 return *this; 00254 }
dimension_type Parma_Polyhedra_Library::Grid::space_dimension | ( | ) | const [inline] |
Returns the dimension of the vector space enclosing *this
.
Definition at line 219 of file Grid.inlines.hh.
References space_dim.
Referenced by add_space_dimensions_and_embed(), add_space_dimensions_and_project(), Parma_Polyhedra_Library::Pointset_Powerset< PS >::approximate_partition(), Parma_Polyhedra_Library::BD_Shape< T >::BD_Shape(), Parma_Polyhedra_Library::Box< ITV >::Box(), Parma_Polyhedra_Library::Pointset_Powerset< PS >::check_containment(), concatenate_assign(), expand_space_dimension(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), hash_code(), Parma_Polyhedra_Library::Octagonal_Shape< T >::Octagonal_Shape(), and throw_dimension_incompatible().
00219 { 00220 return space_dim; 00221 }
PPL::dimension_type Parma_Polyhedra_Library::Grid::affine_dimension | ( | ) | const |
Returns , if
*this
is empty; otherwise, returns the affine dimension of *this
.
Definition at line 257 of file Grid_public.cc.
References con_sys, congruences_are_minimized(), congruences_are_up_to_date(), gen_sys, generators_are_minimized(), generators_are_up_to_date(), is_empty(), minimized_congruences(), minimized_grid_generators(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), and space_dim.
00257 { 00258 if (space_dim == 0 || is_empty()) 00259 return 0; 00260 00261 if (generators_are_up_to_date()) { 00262 if (generators_are_minimized()) 00263 return gen_sys.num_rows() - 1; 00264 if (!(congruences_are_up_to_date() && congruences_are_minimized())) 00265 return minimized_grid_generators().num_rows() - 1; 00266 } 00267 else 00268 minimized_congruences(); 00269 assert(congruences_are_minimized()); 00270 dimension_type d = space_dim; 00271 for (dimension_type i = con_sys.num_rows(); i-- > 0; ) 00272 if (con_sys[i].is_equality()) 00273 --d; 00274 return d; 00275 }
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 234 of file Grid.inlines.hh.
References congruences().
Referenced by Parma_Polyhedra_Library::C_Polyhedron::C_Polyhedron(), and Parma_Polyhedra_Library::NNC_Polyhedron::NNC_Polyhedron().
00234 { 00235 return Constraint_System(congruences());; 00236 }
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 239 of file Grid.inlines.hh.
References minimized_congruences().
00239 { 00240 return Constraint_System(minimized_congruences());; 00241 }
const PPL::Congruence_System & Parma_Polyhedra_Library::Grid::congruences | ( | ) | const |
Returns the system of congruences.
Definition at line 278 of file Grid_public.cc.
References con_sys, congruences_are_up_to_date(), marked_empty(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Matrix::num_rows(), space_dim, and update_congruences().
Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PS >::approximate_partition(), Parma_Polyhedra_Library::Pointset_Powerset< PS >::approximate_partition_aux(), concatenate_assign(), constraints(), difference_assign(), expand_space_dimension(), and minimized_congruences().
00278 { 00279 if (marked_empty()) 00280 return con_sys; 00281 00282 if (space_dim == 0) { 00283 // Zero-dimensional universe. 00284 assert(con_sys.num_rows() == 0 && con_sys.num_columns() == 2); 00285 return con_sys; 00286 } 00287 00288 if (!congruences_are_up_to_date()) 00289 update_congruences(); 00290 00291 return con_sys; 00292 }
const PPL::Congruence_System & Parma_Polyhedra_Library::Grid::minimized_congruences | ( | ) | const |
Returns the system of congruences in minimal form.
Definition at line 295 of file Grid_public.cc.
References con_sys, congruences(), congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, set_congruences_minimized(), set_empty(), and simplify().
Referenced by affine_dimension(), Parma_Polyhedra_Library::Pointset_Powerset< PS >::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<<().
00295 { 00296 if (congruences_are_up_to_date() && !congruences_are_minimized()) { 00297 // Minimize the congruences. 00298 Grid& gr = const_cast<Grid&>(*this); 00299 if (gr.simplify(gr.con_sys, gr.dim_kinds)) 00300 gr.set_empty(); 00301 else 00302 gr.set_congruences_minimized(); 00303 } 00304 return congruences(); 00305 }
const PPL::Grid_Generator_System & Parma_Polyhedra_Library::Grid::grid_generators | ( | ) | const |
Returns the system of generators.
Definition at line 308 of file Grid_public.cc.
References gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Matrix::has_no_rows(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and update_generators().
Referenced by fold_space_dimensions(), and map_space_dimensions().
00308 { 00309 if (space_dim == 0) { 00310 assert(gen_sys.space_dimension() == 0 00311 && gen_sys.num_rows() == (marked_empty() ? 0 : 1)); 00312 return gen_sys; 00313 } 00314 00315 if (marked_empty()) { 00316 assert(gen_sys.has_no_rows()); 00317 return gen_sys; 00318 } 00319 00320 if (!generators_are_up_to_date() && !update_generators()) { 00321 // Updating found the grid empty. 00322 const_cast<Grid&>(*this).set_empty(); 00323 return gen_sys; 00324 } 00325 00326 return gen_sys; 00327 }
const PPL::Grid_Generator_System & Parma_Polyhedra_Library::Grid::minimized_grid_generators | ( | ) | const |
Returns the minimized system of generators.
Definition at line 330 of file Grid_public.cc.
References dim_kinds, gen_sys, generators_are_minimized(), generators_are_up_to_date(), Parma_Polyhedra_Library::Matrix::has_no_rows(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), set_generators_minimized(), simplify(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and update_generators().
Referenced by affine_dimension().
00330 { 00331 if (space_dim == 0) { 00332 assert(gen_sys.space_dimension() == 0 00333 && gen_sys.num_rows() == (marked_empty() ? 0 : 1)); 00334 return gen_sys; 00335 } 00336 00337 if (marked_empty()) { 00338 assert(gen_sys.has_no_rows()); 00339 return gen_sys; 00340 } 00341 00342 if (generators_are_up_to_date()) { 00343 if (!generators_are_minimized()) { 00344 // Minimize the generators. 00345 Grid& gr = const_cast<Grid&>(*this); 00346 gr.simplify(gr.gen_sys, gr.dim_kinds); 00347 gr.set_generators_minimized(); 00348 } 00349 } 00350 else if (!update_generators()) { 00351 // Updating found the grid empty. 00352 const_cast<Grid&>(*this).set_empty(); 00353 return gen_sys; 00354 } 00355 00356 return gen_sys; 00357 }
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 360 of file Grid_public.cc.
References assign(), Parma_Polyhedra_Library::Grid_Generator_System::begin(), Parma_Polyhedra_Library::Grid_Generator_System::end(), Parma_Polyhedra_Library::gcd_assign(), gen_sys, generators_are_up_to_date(), 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, marked_empty(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::Grid_Generator::PARAMETER, Parma_Polyhedra_Library::Grid_Generator::POINT, Parma_Polyhedra_Library::Poly_Con_Relation::saturates(), space_dim, Parma_Polyhedra_Library::Congruence::space_dimension(), Parma_Polyhedra_Library::Poly_Con_Relation::strictly_intersects(), TEMP_INTEGER, throw_dimension_incompatible(), and update_generators().
Referenced by difference_assign(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), and relation_with().
00360 { 00361 // Dimension-compatibility check. 00362 if (space_dim < cg.space_dimension()) 00363 throw_dimension_incompatible("relation_with(cg)", "cg", cg); 00364 00365 if (marked_empty()) 00366 return Poly_Con_Relation::saturates() 00367 && Poly_Con_Relation::is_included() 00368 && Poly_Con_Relation::is_disjoint(); 00369 00370 if (space_dim == 0) { 00371 if (cg.is_inconsistent()) 00372 return Poly_Con_Relation::is_disjoint(); 00373 else if (cg.is_equality()) 00374 return Poly_Con_Relation::saturates() 00375 && Poly_Con_Relation::is_included(); 00376 else if (cg.inhomogeneous_term() % cg.modulus() == 0) 00377 return Poly_Con_Relation::saturates() 00378 && Poly_Con_Relation::is_included(); 00379 } 00380 00381 if (!generators_are_up_to_date() && !update_generators()) 00382 // Updating found the grid empty. 00383 return Poly_Con_Relation::saturates() 00384 && Poly_Con_Relation::is_included() 00385 && Poly_Con_Relation::is_disjoint(); 00386 00387 // Return one of the relations 00388 // 'strictly_intersects' a strict subset of the grid points satisfy cg 00389 // 'is_included' every grid point satisfies cg 00390 // 'is_disjoint' cg and the grid occupy separate spaces. 00391 00392 // There is always a point. 00393 00394 // Scalar product of the congruence and the first point that 00395 // satisfies the congruence. 00396 TEMP_INTEGER(point_sp); 00397 point_sp = 0; 00398 00399 const Coefficient& modulus = cg.modulus(); 00400 00401 TEMP_INTEGER(div); 00402 div = modulus; 00403 00404 TEMP_INTEGER(sp); 00405 00406 bool known_to_intersect = false; 00407 00408 for (Grid_Generator_System::const_iterator g = gen_sys.begin(), 00409 gen_sys_end = gen_sys.end(); g != gen_sys_end; ++g) { 00410 Scalar_Products::assign(sp, cg, *g); 00411 00412 switch (g->type()) { 00413 00414 case Grid_Generator::POINT: 00415 if (cg.is_proper_congruence()) 00416 sp %= div; 00417 if (sp == 0) 00418 // The point satisfies the congruence. 00419 if (point_sp == 0) 00420 // Any previous points satisfied the congruence. 00421 known_to_intersect = true; 00422 else 00423 return Poly_Con_Relation::strictly_intersects(); 00424 else 00425 if (point_sp == 0) { 00426 if (known_to_intersect) 00427 return Poly_Con_Relation::strictly_intersects(); 00428 // Assign `sp' to `point_sp' as `sp' is the scalar product 00429 // of cg and a point g and is non-zero. 00430 point_sp = sp; 00431 } 00432 else { 00433 // A previously considered point p failed to satisfy cg such that 00434 // `point_sp' = `scalar_prod(p, cg)' 00435 // so, if we consider the parameter g-p instead of g, we have 00436 // scalar_prod(g-p, cg) = scalar_prod(g, cg) - scalar_prod(p, cg) 00437 // = sp - point_sp 00438 sp -= point_sp; 00439 00440 if (sp != 0) { 00441 // Find the GCD between sp and the previous GCD. 00442 gcd_assign(div, div, sp); 00443 if (point_sp % div == 0) 00444 // There is a point in the grid satisfying cg. 00445 return Poly_Con_Relation::strictly_intersects(); 00446 } 00447 } 00448 break; 00449 00450 case Grid_Generator::PARAMETER: 00451 if (cg.is_proper_congruence()) 00452 sp %= (div * g->divisor()); 00453 if (sp == 0) 00454 // Parameter g satisfies the cg so the relation depends 00455 // entirely on the other generators. 00456 break; 00457 00458 if (known_to_intersect) 00459 // At least one point satisfies cg. However, the sum of such 00460 // a point and the parameter g fails to satisfy cg (due to g). 00461 return Poly_Con_Relation::strictly_intersects(); 00462 00463 // Find the GCD between sp and the previous GCD. 00464 gcd_assign(div, div, sp); 00465 if (point_sp != 0) 00466 // At least one of any previously encountered points fails to 00467 // satisfy cg. 00468 if (point_sp % div == 0) 00470 // There is also a grid point that satisfies cg. 00471 return Poly_Con_Relation::strictly_intersects(); 00472 00473 break; 00474 00475 case Grid_Generator::LINE: 00476 if (sp == 0) 00477 // Line g satisfies the cg so the relation depends entirely on 00478 // the other generators. 00479 break; 00480 00481 // Line g intersects the congruence. 00482 // 00483 // There is a point p in the grid. Suppose <p*cg> = p_sp. Then 00484 // (-p_sp/sp)*g + p is a point that satisfies cg: <((-p_sp/sp)*g 00485 // + p).cg> = -(p_sp/sp)*sp + p_sp) = 0. If p does not satisfy 00486 // `cg' and hence is not in the grid defined by `cg', the grid 00487 // `*this' strictly intersects the `cg' grid. On the other 00488 // hand, if `p' is in the grid defined by `cg' so that p_sp = 0, 00489 // then <p+g.cg> = p_sp + sp != 0; thus `p+g' is a point in 00490 // *this that does not satisfy `cg' and hence `p+g' is a point 00491 // in *this not in the grid defined by `cg'; therefore `*this' 00492 // strictly intersects the `cg' grid. 00493 00494 return Poly_Con_Relation::strictly_intersects(); 00495 } 00496 } 00497 00498 if (point_sp == 0) { 00499 if (cg.is_equality()) 00500 // Every generator satisfied the cg. 00501 return Poly_Con_Relation::is_included() 00502 && Poly_Con_Relation::saturates(); 00503 else 00504 // Every generator satisfied the cg. 00505 return Poly_Con_Relation::is_included(); 00506 } 00507 00508 assert(!known_to_intersect); 00509 return Poly_Con_Relation::is_disjoint(); 00510 }
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 513 of file Grid_public.cc.
References con_sys, congruences_are_up_to_date(), marked_empty(), Parma_Polyhedra_Library::Poly_Gen_Relation::nothing(), Parma_Polyhedra_Library::Congruence_System::satisfies_all_congruences(), space_dim, Parma_Polyhedra_Library::Grid_Generator::space_dimension(), Parma_Polyhedra_Library::Poly_Gen_Relation::subsumes(), throw_dimension_incompatible(), and update_congruences().
00513 { 00514 // Dimension-compatibility check. 00515 if (space_dim < g.space_dimension()) 00516 throw_dimension_incompatible("relation_with(g)", "g", g); 00517 00518 // The empty grid cannot subsume a generator. 00519 if (marked_empty()) 00520 return Poly_Gen_Relation::nothing(); 00521 00522 // A universe grid in a zero-dimensional space subsumes all the 00523 // generators of a zero-dimensional space. 00524 if (space_dim == 0) 00525 return Poly_Gen_Relation::subsumes(); 00526 00527 if (!congruences_are_up_to_date()) 00528 update_congruences(); 00529 00530 return 00531 con_sys.satisfies_all_congruences(g) 00532 ? Poly_Gen_Relation::subsumes() 00533 : Poly_Gen_Relation::nothing(); 00534 }
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 537 of file Grid_public.cc.
References Parma_Polyhedra_Library::Generator::coefficient(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Generator::divisor(), Parma_Polyhedra_Library::Generator::is_closure_point(), Parma_Polyhedra_Library::Generator::is_point(), marked_empty(), Parma_Polyhedra_Library::Poly_Gen_Relation::nothing(), Parma_Polyhedra_Library::Congruence_System::satisfies_all_congruences(), space_dim, Parma_Polyhedra_Library::Generator::space_dimension(), Parma_Polyhedra_Library::Poly_Gen_Relation::subsumes(), throw_dimension_incompatible(), and update_congruences().
00537 { 00538 dimension_type g_space_dim = g.space_dimension(); 00539 00540 // Dimension-compatibility check. 00541 if (space_dim < g_space_dim) 00542 throw_dimension_incompatible("relation_with(g)", "g", g); 00543 00544 // The empty grid cannot subsume a generator. 00545 if (marked_empty()) 00546 return Poly_Gen_Relation::nothing(); 00547 00548 // A universe grid in a zero-dimensional space subsumes all the 00549 // generators of a zero-dimensional space. 00550 if (space_dim == 0) 00551 return Poly_Gen_Relation::subsumes(); 00552 00553 if (!congruences_are_up_to_date()) 00554 update_congruences(); 00555 00556 Linear_Expression expr; 00557 for (dimension_type i = g_space_dim; i-- > 0; ) { 00558 const Variable v(i); 00559 expr += g.coefficient(v) * v; 00560 } 00561 Grid_Generator gg(grid_point()); 00562 if (g.is_point() || g.is_closure_point()) 00563 // Points and closure points are converted to grid points. 00564 gg = grid_point(expr, g.divisor()); 00565 else 00566 // The generator is a ray or line. 00567 // In both cases, we convert it to a grid line 00568 gg = grid_line(expr); 00569 00570 return 00571 con_sys.satisfies_all_congruences(gg) 00572 ? Poly_Gen_Relation::subsumes() 00573 : Poly_Gen_Relation::nothing(); 00574 }
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 577 of file Grid_public.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::begin(), Parma_Polyhedra_Library::Grid_Generator::coefficient(), Parma_Polyhedra_Library::Constraint::coefficient(), Parma_Polyhedra_Library::Grid_Generator_System::end(), gen_sys, generators_are_up_to_date(), 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::Grid_Generator::is_line_or_parameter(), Parma_Polyhedra_Library::Constraint::is_strict_inequality(), Parma_Polyhedra_Library::Grid_Generator::LINE, marked_empty(), Parma_Polyhedra_Library::Constraint::NONSTRICT_INEQUALITY, Parma_Polyhedra_Library::Grid_Generator::PARAMETER, Parma_Polyhedra_Library::Grid_Generator::POINT, relation_with(), Parma_Polyhedra_Library::Poly_Con_Relation::saturates(), Parma_Polyhedra_Library::Grid_Generator::set_is_parameter(), Parma_Polyhedra_Library::Scalar_Products::sign(), Parma_Polyhedra_Library::Grid_Generator::size(), space_dim, Parma_Polyhedra_Library::Constraint::space_dimension(), Parma_Polyhedra_Library::Poly_Con_Relation::strictly_intersects(), throw_dimension_incompatible(), Parma_Polyhedra_Library::Constraint::type(), and update_generators().
00577 { 00578 // Dimension-compatibility check. 00579 if (space_dim < c.space_dimension()) 00580 throw_dimension_incompatible("relation_with(c)", "c", c); 00581 00582 if (c.is_equality()) { 00583 Congruence cg(c); 00584 return relation_with(cg); 00585 } 00586 00587 if (marked_empty()) 00588 return Poly_Con_Relation::saturates() 00589 && Poly_Con_Relation::is_included() 00590 && Poly_Con_Relation::is_disjoint(); 00591 00592 if (space_dim == 0) { 00593 if (c.is_inconsistent()) 00594 if (c.is_strict_inequality() && c.inhomogeneous_term() == 0) 00595 // The constraint 0 > 0 implicitly defines the hyperplane 0 = 0; 00596 // thus, the zero-dimensional point also saturates it. 00597 return Poly_Con_Relation::saturates() 00598 && Poly_Con_Relation::is_disjoint(); 00599 else 00600 return Poly_Con_Relation::is_disjoint(); 00601 else if (c.inhomogeneous_term() == 0) 00602 return Poly_Con_Relation::saturates() 00603 && Poly_Con_Relation::is_included(); 00604 else 00605 // The zero-dimensional point saturates 00606 // neither the positivity constraint 1 >= 0, 00607 // nor the strict positivity constraint 1 > 0. 00608 return Poly_Con_Relation::is_included(); 00609 } 00610 00611 if (!generators_are_up_to_date() && !update_generators()) 00612 // Updating found the grid empty. 00613 return Poly_Con_Relation::saturates() 00614 && Poly_Con_Relation::is_included() 00615 && Poly_Con_Relation::is_disjoint(); 00616 00617 // Return one of the relations 00618 // 'strictly_intersects' a strict subset of the grid points satisfy c 00619 // 'is_included' every grid point satisfies c 00620 // 'is_disjoint' c and the grid occupy separate spaces. 00621 00622 // There is always a point. 00623 00624 bool point_is_included = false; 00625 bool point_saturates = false; 00626 const Grid_Generator* first_point = NULL; 00627 00628 for (Grid_Generator_System::const_iterator g = gen_sys.begin(), 00629 gen_sys_end = gen_sys.end(); g != gen_sys_end; ++g) 00630 switch (g->type()) { 00631 00632 case Grid_Generator::POINT: 00633 { 00634 Grid_Generator& gen = const_cast<Grid_Generator&>(*g); 00635 if (first_point == NULL) { 00636 first_point = &gen; 00637 const int sign = Scalar_Products::sign(c, gen); 00638 Constraint::Type type = c.type(); 00639 if ((type == Constraint::NONSTRICT_INEQUALITY && sign == 0)) { 00640 point_saturates = true; 00641 } 00642 else if (sign > 0) 00643 point_is_included = true; 00644 break; 00645 } 00646 // Else convert g to a parameter, and continue into the 00647 // parameter case. 00648 gen.set_is_parameter(); 00649 const Grid_Generator& first = *first_point; 00650 for (dimension_type i = gen.size() - 1; i-- > 0; ) 00651 gen[i] -= first[i]; 00652 } 00653 00654 case Grid_Generator::PARAMETER: 00655 case Grid_Generator::LINE: 00656 Grid_Generator& gen = const_cast<Grid_Generator&>(*g); 00657 if (gen.is_line_or_parameter()) 00658 for (dimension_type i = c.space_dimension(); i-- > 0; ) { 00659 Variable v(i); 00660 if (c.coefficient(v) != 0 && gen.coefficient(v) != 0) 00661 return Poly_Con_Relation::strictly_intersects(); 00662 } 00663 break; 00664 } 00665 00666 if (point_saturates) 00667 // Any parameters and lines are also included. 00668 return Poly_Con_Relation::saturates() 00669 && Poly_Con_Relation::is_included(); 00670 if (point_is_included) 00671 // Any parameters and lines are also included. 00672 return Poly_Con_Relation::is_included(); 00673 return Poly_Con_Relation::is_disjoint(); 00674 }
bool Parma_Polyhedra_Library::Grid::is_empty | ( | ) | const |
Returns true
if and only if *this
is an empty grid.
Definition at line 677 of file Grid_public.cc.
References con_sys, congruences_are_minimized(), dim_kinds, generators_are_up_to_date(), marked_empty(), set_congruences_minimized(), set_empty(), simplify(), and space_dim.
Referenced by affine_dimension(), Parma_Polyhedra_Library::Pointset_Powerset< PS >::approximate_partition_aux(), Parma_Polyhedra_Library::Pointset_Powerset< PS >::check_containment(), contains(), contains_integer_point(), generalized_affine_image(), generalized_affine_preimage(), is_disjoint_from(), operator<<(), Parma_Polyhedra_Library::Pointset_Powerset< PS >::Pointset_Powerset(), and remove_higher_space_dimensions().
00677 { 00678 if (marked_empty()) 00679 return true; 00680 // Try a fast-fail test: if generators are up-to-date then the 00681 // generator system (since it is well formed) contains a point. 00682 if (generators_are_up_to_date()) 00683 return false; 00684 if (space_dim == 0) 00685 return false; 00686 if (congruences_are_minimized()) 00687 // If the grid was empty it would be marked empty. 00688 return false; 00689 // Minimize the congruences to check if the grid is empty. 00690 Grid& gr = const_cast<Grid&>(*this); 00691 if (gr.simplify(gr.con_sys, gr.dim_kinds)) { 00692 gr.set_empty(); 00693 return true; 00694 } 00695 gr.set_congruences_minimized(); 00696 return false; 00697 }
bool Parma_Polyhedra_Library::Grid::is_universe | ( | ) | const |
Returns true
if and only if *this
is a universe grid.
Definition at line 700 of file Grid_public.cc.
References con_sys, congruences_are_minimized(), congruences_are_up_to_date(), marked_empty(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Congruence_System::satisfies_all_congruences(), space_dim, and update_congruences().
Referenced by operator<<().
00700 { 00701 if (marked_empty()) 00702 return false; 00703 00704 if (space_dim == 0) 00705 return true; 00706 00707 if (congruences_are_up_to_date()) { 00708 if (congruences_are_minimized()) 00709 // The minimized universe congruence system has only one row, 00710 // the integrality congruence. 00711 return con_sys.num_rows() == 1 && con_sys[0].is_tautological(); 00712 } 00713 else { 00714 update_congruences(); 00715 return con_sys.num_rows() == 1 && con_sys[0].is_tautological(); 00716 } 00717 00718 // Test con_sys's inclusion in a universe generator system. 00719 00720 // The zero dimension cases are handled above. 00721 Variable var(space_dim - 1); 00722 for (dimension_type i = space_dim; i-- > 0; ) 00723 if (!con_sys.satisfies_all_congruences(grid_line(Variable(i) + var))) 00724 return false; 00725 assert(con_sys.satisfies_all_congruences(grid_point(0*var))); 00726 return true; 00727 }
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 772 of file Grid_public.cc.
bool Parma_Polyhedra_Library::Grid::is_disjoint_from | ( | const Grid & | y | ) | const |
Returns true
if and only if *this
and y
are disjoint.
std::invalid_argument | Thrown if x and y are dimension-incompatible. |
Definition at line 2458 of file Grid_public.cc.
References intersection_assign(), is_empty(), space_dim, and throw_dimension_incompatible().
Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PS >::check_containment().
02458 { 02459 // Dimension-compatibility check. 02460 if (space_dim != y.space_dim) 02461 throw_dimension_incompatible("is_disjoint_from(y)", "y", y); 02462 Grid z = *this; 02463 z.intersection_assign(y); 02464 return z.is_empty(); 02465 }
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 754 of file Grid_public.cc.
References gen_sys, generators_are_up_to_date(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), space_dim, and update_generators().
00754 { 00755 // A zero-dimensional or empty grid is discrete. 00756 if (space_dim == 0 00757 || marked_empty() 00758 || (!generators_are_up_to_date() && !update_generators())) 00759 return true; 00760 00761 // Search for lines in the generator system. 00762 for (dimension_type row = gen_sys.num_rows(); row-- > 1; ) 00763 if (gen_sys[row].is_line()) 00764 return false; 00765 00766 // The system of generators is composed only by 00767 // points and parameters: the polyhedron is discrete. 00768 return true; 00769 }
bool Parma_Polyhedra_Library::Grid::is_bounded | ( | ) | const |
Returns true
if and only if *this
is bounded.
Definition at line 730 of file Grid_public.cc.
References gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator::is_line_or_parameter(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), space_dim, and update_generators().
00730 { 00731 // A zero-dimensional or empty grid is bounded. 00732 if (space_dim == 0 00733 || marked_empty() 00734 || (!generators_are_up_to_date() && !update_generators())) 00735 return true; 00736 00737 // TODO: Consider using con_sys when gen_sys is out of date. 00738 00739 if (gen_sys.num_rows() > 1) { 00740 // Check if all generators are the same point. 00741 const Grid_Generator& first_point = gen_sys[0]; 00742 if (first_point.is_line_or_parameter()) 00743 return false; 00744 for (dimension_type row = gen_sys.num_rows(); row-- > 0; ) { 00745 const Grid_Generator& gen = gen_sys[row]; 00746 if (gen.is_line_or_parameter() || gen != first_point) 00747 return false; 00748 } 00749 } 00750 return true; 00751 }
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 777 of file Grid_public.cc.
References add_recycled_congruences(), Parma_Polyhedra_Library::Congruence_System::insert(), is_empty(), marked_empty(), and space_dim.
00777 { 00778 // Empty grids have no points. 00779 if (marked_empty()) 00780 return false; 00781 00782 // A zero-dimensional, universe grid has, by convention, an 00783 // integer point. 00784 if (space_dim == 0) 00785 return true; 00786 00787 // A grid has an integer point if its intersection with the integer 00788 // grid is non-empty. 00789 Congruence_System cgs; 00790 for (dimension_type var_index = space_dim; var_index-- > 0; ) 00791 cgs.insert(Variable(var_index) %= 0); 00792 00793 Grid gr = *this; 00794 gr.add_recycled_congruences(cgs); 00795 return !gr.is_empty(); 00796 }
bool Parma_Polyhedra_Library::Grid::constrains | ( | Variable | var | ) | const |
Returns true
if and only if var
is constrained in *this
.
std::invalid_argument | Thrown if var is not a space dimension of *this . |
Definition at line 799 of file Grid_public.cc.
References Parma_Polyhedra_Library::Grid_Generator::coefficient(), con_sys, congruences_are_up_to_date(), gen_sys, generators_are_minimized(), generators_are_up_to_date(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Grid_Generator::is_line(), marked_empty(), minimize(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), throw_dimension_incompatible(), and update_congruences().
00799 { 00800 // `var' should be one of the dimensions of the polyhedron. 00801 const dimension_type var_space_dim = var.space_dimension(); 00802 if (space_dim < var_space_dim) 00803 throw_dimension_incompatible("constrains(v)", "v", var); 00804 00805 // An empty grid constrains all variables. 00806 if (marked_empty()) 00807 return true; 00808 00809 if (generators_are_up_to_date()) { 00810 // Since generators are up-to-date, the generator system (since it is 00811 // well formed) contains a point. Hence the grid is not empty. 00812 if (congruences_are_up_to_date()) 00813 // Here a variable is constrained if and only if it is 00814 // syntactically constrained. 00815 goto syntactic_check; 00816 00817 if (generators_are_minimized()) { 00818 // Try a quick, incomplete check for the universe grid: 00819 // a universe polyhedron constrains no variable. 00820 // Count the number of lines (they are linearly independent). 00821 dimension_type num_lines = 0; 00822 for (dimension_type i = gen_sys.num_rows(); i-- > 0; ) 00823 if (gen_sys[i].is_line()) 00824 ++num_lines; 00825 00826 if (num_lines == space_dim) 00827 return false; 00828 } 00829 00830 // Scan generators: perhaps we will find line(var). 00831 const dimension_type var_id = var.id(); 00832 for (dimension_type i = gen_sys.num_rows(); i-- > 0; ) { 00833 const Grid_Generator& g_i = gen_sys[i]; 00834 if (g_i.is_line()) { 00835 if (sgn(g_i.coefficient(var)) != 0) { 00836 for (dimension_type j = 0; j < space_dim; ++j) 00837 if (g_i.coefficient(Variable(j)) != 0 && j != var_id) 00838 goto next; 00839 return true; 00840 } 00841 } 00842 next: 00843 ; 00844 } 00845 00846 // We are still here: at least we know that the grid is not empty. 00847 update_congruences(); 00848 goto syntactic_check; 00849 } 00850 00851 // We must minimize to detect emptiness and obtain constraints. 00852 if (!minimize()) 00853 return true; 00854 00855 syntactic_check: 00856 for (dimension_type i = con_sys.num_rows(); i-- > 0; ) 00857 if (con_sys[i].coefficient(var) != 0) 00858 return true; 00859 return false; 00860 }
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.
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
Definition at line 335 of file Grid.inlines.hh.
References bounds().
00335 { 00336 return bounds(expr, "bounds_from_above(e)"); 00337 }
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.
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
Definition at line 340 of file Grid.inlines.hh.
References bounds().
00340 { 00341 return bounds(expr, "bounds_from_below(e)"); 00342 }
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.
expr | The linear expression to be maximized subject to *this ; | |
sup_n | The numerator of the supremum value; | |
sup_d | The denominator of the supremum value; | |
maximum | true if 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. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*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 345 of file Grid.inlines.hh.
References max_min().
00346 { 00347 return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum); 00348 }
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.
expr | The linear expression to be maximized subject to *this ; | |
sup_n | The numerator of the supremum value; | |
sup_d | The denominator of the supremum value; | |
maximum | true if 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; | |
point | When maximization succeeds, will be assigned a point where expr reaches its supremum value. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this
is empty or expr
is not bounded by *this
, false
is returned and sup_n
, sup_d
, maximum
and point
are left untouched.
Definition at line 351 of file Grid.inlines.hh.
References max_min().
00353 { 00354 return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum, &point); 00355 }
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.
expr | The linear expression to be minimized subject to *this ; | |
inf_n | The numerator of the infimum value; | |
inf_d | The denominator of the infimum value; | |
minimum | true if 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. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this
is empty or expr
is not bounded from below, false
is returned and inf_n
, inf_d
and minimum
are left untouched.
Definition at line 358 of file Grid.inlines.hh.
References max_min().
Referenced by is_included_in().
00359 { 00360 return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum); 00361 }
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.
expr | The linear expression to be minimized subject to *this ; | |
inf_n | The numerator of the infimum value; | |
inf_d | The denominator of the infimum value; | |
minimum | true if 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; | |
point | When minimization succeeds, will be assigned a point where expr reaches its infimum value. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this
is empty or expr
is not bounded from below, false
is returned and inf_n
, inf_d
, minimum
and point
are left untouched.
Definition at line 364 of file Grid.inlines.hh.
References max_min().
00366 { 00367 return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum, &point); 00368 }
bool Parma_Polyhedra_Library::Grid::contains | ( | const Grid & | y | ) | const |
Returns true
if and only if *this
contains y
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 2439 of file Grid_public.cc.
References is_empty(), is_included_in(), marked_empty(), quick_equivalence_test(), space_dim, throw_dimension_incompatible(), and TVB_TRUE.
Referenced by Parma_Polyhedra_Library::Pointset_Powerset< PS >::check_containment(), congruence_widening_assign(), difference_assign(), generator_widening_assign(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), strictly_contains(), and widening_assign().
02439 { 02440 const Grid& x = *this; 02441 02442 // Dimension-compatibility check. 02443 if (x.space_dim != y.space_dim) 02444 throw_dimension_incompatible("contains(y)", "y", y); 02445 02446 if (y.marked_empty()) 02447 return true; 02448 if (x.marked_empty()) 02449 return y.is_empty(); 02450 if (y.space_dim == 0) 02451 return true; 02452 if (x.quick_equivalence_test(y) == Grid::TVB_TRUE) 02453 return true; 02454 return y.is_included_in(x); 02455 }
bool Parma_Polyhedra_Library::Grid::strictly_contains | ( | const Grid & | y | ) | const [inline] |
Returns true
if and only if *this
strictly contains y
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 384 of file Grid.inlines.hh.
References contains().
00384 { 00385 const Grid& x = *this; 00386 return x.contains(y) && !y.contains(x); 00387 }
void Parma_Polyhedra_Library::Grid::get_covering_box | ( | Box< Interval > & | box | ) | const [inline] |
Writes the covering box for *this
into box
.
The covering box is a set of upper and lower values for each dimension. When the covering box written into box
is tiled onto empty space the corners of the tiles form the sparsest rectilinear grid that includes *this
.
The value of the lower bound of each interval of the resulting box
are as close as possible to the origin, with positive values taking preference when the lowest positive value equals the lowest negative value.
If all the points have a single value in a particular dimension of the grid then there is only a lower bound on the interval produced in box
, and the lower bound denotes the single value for the dimension. If the coordinates of the points in a particular dimension include every value then the upper and lower bounds of the associated interval in box
are set equal. The empty grid produces the empty box
. The zero dimension universe grid produces the zero dimension universe box.
box | The Box into which the covering box is written. |
std::invalid_argument | Thrown if *this and box are dimension-incompatible. |
Definition at line 238 of file Grid.templates.hh.
References Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator::is_line(), Parma_Polyhedra_Library::Grid_Generator::is_point(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_columns(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), Parma_Polyhedra_Library::Grid_Generator::set_divisor(), Parma_Polyhedra_Library::Box< ITV >::set_empty(), space_dim, Parma_Polyhedra_Library::Box< ITV >::space_dimension(), Parma_Polyhedra_Library::Box< ITV >::swap(), TEMP_INTEGER, throw_dimension_incompatible(), and update_generators().
00238 { 00239 // Dimension-compatibility check. 00240 if (space_dim > box.space_dimension()) 00241 throw_dimension_incompatible("get_covering_box(box)", "box", 00242 box.space_dimension()); 00243 00244 Box<Interval> new_box(box.space_dimension()); 00245 00246 if (marked_empty()) { 00247 box = new_box; 00248 box.set_empty(); 00249 return; 00250 } 00251 if (space_dim == 0) { 00252 return; 00253 } 00254 if (!generators_are_up_to_date() && !update_generators()) { 00255 // Updating found the grid empty. 00256 box = new_box; 00257 box.set_empty(); 00258 return; 00259 } 00260 00261 assert(!gen_sys.has_no_rows()); 00262 00263 dimension_type num_dims = gen_sys.num_columns() - 2 /* parameter divisor */; 00264 dimension_type num_rows = gen_sys.num_rows(); 00265 00266 TEMP_INTEGER(gcd); 00267 TEMP_INTEGER(bound); 00268 00269 if (num_rows > 1) { 00270 Row interval_sizes(num_dims, Row::Flags()); 00271 std::vector<bool> interval_emptiness(num_dims, false); 00272 00273 // Store in `interval_sizes', for each column (that is, for each 00274 // dimension), the GCD of all the values in that column where the 00275 // row is of type parameter. 00276 00277 for (dimension_type dim = num_dims; dim-- > 0; ) 00278 interval_sizes[dim] = 0; 00279 const Grid_Generator *first_point = NULL; 00280 for (dimension_type row = 0; row < num_rows; ++row) { 00281 Grid_Generator& gen = const_cast<Grid_Generator&>(gen_sys[row]); 00282 if (gen.is_line()) { 00283 for (dimension_type dim = 0; dim < num_dims; ++dim) 00284 if (!interval_emptiness[dim] && gen[dim+1] != 0) { 00285 // Empty interval, set both bounds for associated 00286 // dimension to zero. 00287 new_box.add_constraint(Variable(dim) == 0); 00288 interval_emptiness[dim] = true; 00289 } 00290 continue; 00291 } 00292 if (gen.is_point()) { 00293 if (first_point == NULL) { 00294 first_point = &gen_sys[row]; 00295 continue; 00296 } 00297 const Grid_Generator& point = *first_point; 00298 // Convert the point `gen' to a parameter. 00299 dimension_type dim = num_dims; 00300 do { 00301 gen[dim] -= point[dim]; 00302 } 00303 while (dim-- > 0); 00304 gen.set_divisor(point.divisor()); 00305 } 00306 for (dimension_type dim = num_dims; dim-- > 0; ) 00307 if (!interval_emptiness[dim]) 00308 gcd_assign(interval_sizes[dim], interval_sizes[dim], gen[dim+1]); 00309 } 00310 00311 // For each dimension set the lower bound of the interval to the 00312 // grid value closest to the origin, and the upper bound to the 00313 // addition of the lower bound and the shortest distance in the 00314 // given dimension between any two grid points. 00315 const Grid_Generator& point = *first_point; 00316 const Coefficient& divisor = point.divisor(); 00317 TEMP_INTEGER(lower_bound); 00318 for (dimension_type dim = num_dims; dim-- > 0; ) { 00319 if (interval_emptiness[dim]) 00320 continue; 00321 00322 lower_bound = point[dim+1]; 00323 00324 // If the interval size is zero then all points have the same 00325 // value in this dimension, so set only the lower bound. 00326 if (interval_sizes[dim] != 0) { 00327 // Make the lower bound as close as possible to the origin, 00328 // leaving the sign the same. 00329 lower_bound %= interval_sizes[dim]; 00330 // Check if the lowest value the other side of the origin is 00331 // closer to the origin, preferring the lowest positive if they 00332 // are equal. 00333 if (lower_bound > 0) { 00334 if (interval_sizes[dim] - lower_bound < lower_bound) 00335 lower_bound -= interval_sizes[dim]; 00336 } 00337 else if (lower_bound < 0 00338 && interval_sizes[dim] + lower_bound < - lower_bound) 00339 lower_bound += interval_sizes[dim]; 00340 00341 // Reduce the bound fraction first. 00342 bound = interval_sizes[dim] + lower_bound; 00343 gcd_assign(gcd, bound, divisor); 00344 exact_div_assign(bound, bound, gcd); 00345 exact_div_assign(gcd, divisor, gcd); 00346 // `gcd' now holds the reduced divisor. 00347 new_box.add_constraint(gcd*Variable(dim) <= bound); 00348 } 00349 00350 // Reduce the bound fraction first. 00351 gcd_assign(gcd, lower_bound, divisor); 00352 exact_div_assign(lower_bound, lower_bound, gcd); 00353 exact_div_assign(gcd, divisor, gcd); 00354 // `gcd' now holds the reduced divisor. 00355 new_box.add_constraint(gcd*Variable(dim) >= lower_bound); 00356 } 00357 } 00358 else { 00359 const Grid_Generator& point = gen_sys[0]; 00360 const Coefficient& divisor = point.divisor(); 00361 // The covering box of a single point has only lower bounds. 00362 for (dimension_type dim = num_dims; dim-- > 0; ) { 00363 // Reduce the bound fraction first. 00364 gcd_assign(gcd, point[dim+1], divisor); 00365 exact_div_assign(bound, point[dim+1], gcd); 00366 exact_div_assign(gcd, divisor, gcd); 00367 // `gcd' now holds the reduced divisor. 00368 new_box.add_constraint(gcd*Variable(dim) >= bound); 00369 } 00370 } 00371 00372 box.swap(new_box); 00373 }
bool Parma_Polyhedra_Library::Grid::OK | ( | bool | check_not_empty = false |
) | const |
Checks if all the invariants are satisfied.
true
if and only if *this
satisfies all the invariants and either check_not_empty
is false
or *this
is not empty.check_not_empty | true if and only if, in addition to checking the invariants, *this must be checked to be not empty. |
std::cerr
in case invariants are violated. This is useful for the purpose of debugging the library.
Definition at line 863 of file Grid_public.cc.
References ascii_dump(), Parma_Polyhedra_Library::Congruence_System::ascii_dump(), Parma_Polyhedra_Library::Grid_Generator_System::ascii_dump(), clear_generators_up_to_date(), con_sys, CON_VIRTUAL, congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, EQUALITY, gen_sys, GEN_VIRTUAL, generators_are_minimized(), generators_are_up_to_date(), Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::has_points(), Parma_Polyhedra_Library::Congruence_System::is_equal_to(), Parma_Polyhedra_Library::Grid_Generator::is_equal_to(), LINE, lower_triangular(), marked_empty(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), Parma_Polyhedra_Library::Congruence_System::OK(), Parma_Polyhedra_Library::Grid_Generator_System::OK(), Parma_Polyhedra_Library::Grid::Status::OK(), PARAMETER, PROPER_CONGRUENCE, simplify(), Parma_Polyhedra_Library::Grid_Generator::size(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), status, Parma_Polyhedra_Library::swap(), update_generators(), and upper_triangular().
Referenced by add_congruence_no_check(), add_grid_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_load(), bounded_affine_image(), bounded_affine_preimage(), concatenate_assign(), congruence_widening_assign(), construct(), difference_assign(), expand_space_dimension(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), generator_widening_assign(), Grid(), intersection_assign(), is_included_in(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), map_space_dimensions(), minimize(), remove_higher_space_dimensions(), remove_space_dimensions(), time_elapse_assign(), unconstrain(), and upper_bound_assign().
00863 { 00864 #ifndef NDEBUG 00865 using std::endl; 00866 using std::cerr; 00867 #endif 00868 00869 // Check whether the status information is legal. 00870 if (!status.OK()) 00871 goto fail; 00872 00873 if (marked_empty()) { 00874 if (check_not_empty) { 00875 // The caller does not want the grid to be empty. 00876 #ifndef NDEBUG 00877 cerr << "Empty grid!" << endl; 00878 #endif 00879 goto fail; 00880 } 00881 00882 if (con_sys.space_dimension() != space_dim) { 00883 #ifndef NDEBUG 00884 cerr << "The grid is in a space of dimension " << space_dim 00885 << " while the system of congruences is in a space of dimension " 00886 << con_sys.space_dimension() 00887 << endl; 00888 #endif 00889 goto fail; 00890 } 00891 return true; 00892 } 00893 00894 // A zero-dimensional universe grid is legal only if the system of 00895 // congruences `con_sys' is empty, and the generator system contains 00896 // one point. 00897 if (space_dim == 0) { 00898 if (con_sys.has_no_rows()) 00899 if (gen_sys.num_rows() == 1 && gen_sys[0].is_point()) 00900 return true; 00901 #ifndef NDEBUG 00902 cerr << "Zero-dimensional grid should have an empty congruence" << endl 00903 << "system and a generator system of a single point." << endl; 00904 #endif 00905 goto fail; 00906 } 00907 00908 // A grid is defined by a system of congruences or a system of 00909 // generators. At least one of them must be up to date. 00910 if (!congruences_are_up_to_date() && !generators_are_up_to_date()) { 00911 #ifndef NDEBUG 00912 cerr << "Grid not empty, not zero-dimensional" << endl 00913 << "and with neither congruences nor generators up-to-date!" 00914 << endl; 00915 #endif 00916 goto fail; 00917 } 00918 00919 { 00920 // The expected number of columns in the congruence and generator 00921 // systems, if they are not empty. 00922 const dimension_type num_columns = space_dim + 1; 00923 00924 // Here we check if the size of the matrices is consistent. 00925 // Let us suppose that all the matrices are up-to-date; this means: 00926 // `con_sys' : number of congruences x poly_num_columns 00927 // `gen_sys' : number of generators x poly_num_columns 00928 if (congruences_are_up_to_date()) 00929 if (con_sys.num_columns() != num_columns + 1 /* moduli */) { 00930 #ifndef NDEBUG 00931 cerr << "Incompatible size! (con_sys and space_dim)" 00932 << endl; 00933 #endif 00934 goto fail; 00935 } 00936 00937 if (generators_are_up_to_date()) { 00938 if (gen_sys.space_dimension() + 1 != num_columns) { 00939 #ifndef NDEBUG 00940 cerr << "Incompatible size! (gen_sys and space_dim)" 00941 << endl; 00942 #endif 00943 goto fail; 00944 } 00945 00946 // Check if the system of generators is well-formed. 00947 if (!gen_sys.OK()) 00948 goto fail; 00949 00950 // Check each generator in the system. 00951 for (dimension_type i = gen_sys.num_rows(); i-- > 0; ) { 00952 const Grid_Generator& g = gen_sys[i]; 00953 00954 if (g.size() < 1) { 00955 #ifndef NDEBUG 00956 cerr << "Parameter should have coefficients." << endl; 00957 #endif 00958 goto fail; 00959 } 00960 } 00961 00962 // A non-empty system of generators describing a grid is valid 00963 // if and only if it contains a point. 00964 if (!gen_sys.has_no_rows() && !gen_sys.has_points()) { 00965 #ifndef NDEBUG 00966 cerr << "Non-empty generator system declared up-to-date " 00967 << "has no points!" 00968 << endl; 00969 #endif 00970 goto fail; 00971 } 00972 00973 if (generators_are_minimized()) { 00974 Grid_Generator_System gs = gen_sys; 00975 00976 if (dim_kinds.size() != num_columns) { 00977 #ifndef NDEBUG 00978 cerr << "Size of dim_kinds should equal the number of columns." 00979 << endl; 00980 #endif 00981 goto fail; 00982 } 00983 00984 if (!upper_triangular(gs, dim_kinds)) { 00985 #ifndef NDEBUG 00986 cerr << "Reduced generators should be upper triangular." 00987 << endl; 00988 #endif 00989 goto fail; 00990 } 00991 00992 // Check that dim_kinds corresponds to the row kinds in gen_sys. 00993 for (dimension_type dim = space_dim, 00994 row = gen_sys.num_rows(); dim > 0; assert(row <= dim), --dim) { 00995 if (dim_kinds[dim] == GEN_VIRTUAL 00996 || (gen_sys[--row].is_parameter_or_point() 00997 && dim_kinds[dim] == PARAMETER) 00998 || (assert(gen_sys[row].is_line()), dim_kinds[dim] == LINE)) 00999 continue; 01000 #ifndef NDEBUG 01001 cerr << "Kinds in dim_kinds should match those in gen_sys." 01002 << endl; 01003 #endif 01004 goto fail; 01005 } 01006 01007 // A reduced generator system must be the same as a temporary 01008 // reduced copy. 01009 Dimension_Kinds dk = dim_kinds; 01010 // `gs' is minimized and marked_empty returned false, so `gs' 01011 // should contain rows. 01012 assert(!gs.has_no_rows()); 01013 simplify(gs, dk); 01014 // gs contained rows before being reduced, so it should 01015 // contain at least a single point afterward. 01016 assert(!gs.has_no_rows()); 01017 for (dimension_type row = gen_sys.num_rows(); row-- > 0; ) { 01018 Grid_Generator& g = gs[row]; 01019 const Grid_Generator& g_copy = gen_sys[row]; 01020 if (g.is_equal_to(g_copy)) 01021 continue; 01022 #ifndef NDEBUG 01023 cerr << "Generators are declared minimized," 01024 " but they change under reduction.\n" 01025 << "Here is the generator system:\n"; 01026 gen_sys.ascii_dump(cerr); 01027 cerr << "and here is the minimized form of the temporary copy:\n"; 01028 gs.ascii_dump(cerr); 01029 #endif 01030 goto fail; 01031 } 01032 } 01033 01034 } // if (congruences_are_up_to_date()) 01035 } 01036 01037 if (congruences_are_up_to_date()) { 01038 // Check if the system of congruences is well-formed. 01039 if (!con_sys.OK()) 01040 goto fail; 01041 01042 Grid tmp_gr = *this; 01043 Congruence_System cs_copy = tmp_gr.con_sys; 01044 01045 // Clear the generators in tmp_gr. 01046 Grid_Generator_System gs(space_dim); 01047 std::swap(tmp_gr.gen_sys, gs); 01048 tmp_gr.clear_generators_up_to_date(); 01049 01050 if (!tmp_gr.update_generators()) { 01051 if (check_not_empty) { 01052 // Want to know the satisfiability of the congruences. 01053 #ifndef NDEBUG 01054 cerr << "Unsatisfiable system of congruences!" 01055 << endl; 01056 #endif 01057 goto fail; 01058 } 01059 // The grid is empty, all checks are done. 01060 return true; 01061 } 01062 01063 if (congruences_are_minimized()) { 01064 // A reduced congruence system must be lower triangular. 01065 if (!lower_triangular(con_sys, dim_kinds)) { 01066 #ifndef NDEBUG 01067 cerr << "Reduced congruences should be lower triangular." << endl; 01068 #endif 01069 goto fail; 01070 } 01071 01072 // If the congruences are minimized, all the elements in the 01073 // congruence system must be the same as those in the temporary, 01074 // minimized system `cs_copy'. 01075 if (!con_sys.is_equal_to(cs_copy)) { 01076 #ifndef NDEBUG 01077 cerr << "Congruences are declared minimized, but they change under reduction!" 01078 << endl 01079 << "Here is the minimized form of the congruence system:" 01080 << endl; 01081 cs_copy.ascii_dump(cerr); 01082 cerr << endl; 01083 #endif 01084 goto fail; 01085 } 01086 01087 if (dim_kinds.size() != con_sys.num_columns() - 1 /* modulus */) { 01088 #ifndef NDEBUG 01089 cerr << "Size of dim_kinds should equal the number of columns." 01090 << endl; 01091 #endif 01092 goto fail; 01093 } 01094 01095 // Check that dim_kinds corresponds to the row kinds in con_sys. 01096 for (dimension_type dim = space_dim, row = 0; dim > 0; --dim) { 01097 if (dim_kinds[dim] == CON_VIRTUAL 01098 || (con_sys[row++].is_proper_congruence() 01099 && dim_kinds[dim] == PROPER_CONGRUENCE) 01100 || (assert(con_sys[row-1].is_equality()), 01101 dim_kinds[dim] == EQUALITY)) 01102 continue; 01103 #ifndef NDEBUG 01104 cerr << "Kinds in dim_kinds should match those in con_sys." << endl; 01105 #endif 01106 goto fail; 01107 } 01108 } 01109 } 01110 01111 return true; 01112 01113 fail: 01114 #ifndef NDEBUG 01115 cerr << "Here is the grid under check:" << endl; 01116 ascii_dump(cerr); 01117 #endif 01118 return false; 01119 }
void Parma_Polyhedra_Library::Grid::add_congruence | ( | const Congruence & | cg | ) | [inline] |
Adds a copy of congruence cg
to *this
.
std::invalid_argument | Thrown if *this and congruence cg are dimension-incompatible. |
Definition at line 253 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::Pointset_Powerset< PS >::approximate_partition_aux(), and refine_with_congruence().
00253 { 00254 // Dimension-compatibility check. 00255 if (space_dim < cg.space_dimension()) 00256 throw_dimension_incompatible("add_congruence(cg)", "cg", cg); 00257 00258 if (!marked_empty()) 00259 add_congruence_no_check(cg); 00260 }
bool Parma_Polyhedra_Library::Grid::add_congruence_and_minimize | ( | const Congruence & | c | ) |
Adds a copy of congruence cg
to the system of congruences of this
, reducing the result.
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and congruence cg are dimension-incompatible. |
Definition at line 1122 of file Grid_public.cc.
References add_recycled_congruences_and_minimize().
01122 { 01123 Congruence_System cgs(cg); 01124 return add_recycled_congruences_and_minimize(cgs); 01125 }
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
.
std::invalid_argument | Thrown if *this and generator g are dimension-incompatible, or if *this is an empty grid and g is not a point. |
Definition at line 1144 of file Grid_public.cc.
References clear_congruences_up_to_date(), clear_empty(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), 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(), marked_empty(), normalize_divisors(), OK(), set_generators_up_to_date(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Grid_Generator::space_dimension(), throw_dimension_incompatible(), throw_invalid_generator(), and update_generators().
Referenced by generalized_affine_image(), and generalized_affine_preimage().
01144 { 01145 // The dimension of `g' must be at most space_dim. 01146 const dimension_type g_space_dim = g.space_dimension(); 01147 if (space_dim < g_space_dim) 01148 throw_dimension_incompatible("add_grid_generator(g)", "g", g); 01149 01150 // Deal with zero-dimension case first. 01151 if (space_dim == 0) { 01152 // Points and parameters are the only zero-dimension generators 01153 // that can be created. 01154 if (marked_empty()) { 01155 if (g.is_parameter()) 01156 throw_invalid_generator("add_grid_generator(g)", "g"); 01157 set_zero_dim_univ(); 01158 } 01159 assert(OK()); 01160 return; 01161 } 01162 01163 if (marked_empty() 01164 || (!generators_are_up_to_date() && !update_generators())) { 01165 // Here the grid is empty: the specification says we can only 01166 // insert a point. 01167 if (g.is_line_or_parameter()) 01168 throw_invalid_generator("add_grid_generator(g)", "g"); 01169 gen_sys.insert(g); 01170 clear_empty(); 01171 } 01172 else { 01173 assert(generators_are_up_to_date()); 01174 gen_sys.insert(g); 01175 if (g.is_parameter_or_point()) 01176 normalize_divisors(gen_sys); 01177 } 01178 01179 // With the added generator, congruences are out of date. 01180 clear_congruences_up_to_date(); 01181 01182 clear_generators_minimized(); 01183 set_generators_up_to_date(); 01184 assert(OK()); 01185 }
bool Parma_Polyhedra_Library::Grid::add_grid_generator_and_minimize | ( | const Grid_Generator & | g | ) |
Adds a copy of grid generator g
to the system of generators of *this
, reducing the result.
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and generator g are dimension-incompatible, or if *this is an empty grid and g is not a point. |
Definition at line 1188 of file Grid_public.cc.
References add_recycled_grid_generators_and_minimize().
01188 { 01189 Grid_Generator_System gs(g); 01190 return add_recycled_grid_generators_and_minimize(gs); 01191 }
void Parma_Polyhedra_Library::Grid::add_congruences | ( | const Congruence_System & | cgs | ) | [inline] |
Adds a copy of each congruence in cgs
to *this
.
cgs | Contains the congruences that will be added to the system of congruences of *this . |
std::invalid_argument | Thrown if *this and cgs are dimension-incompatible. |
Definition at line 263 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 refine_with_congruences().
00263 { 00264 // TODO: this is just an executable specification. 00265 // Space dimension compatibility check. 00266 if (space_dim < cgs.space_dimension()) 00267 throw_dimension_incompatible("add_congruences(cgs)", "cgs", cgs); 00268 00269 if (!marked_empty()) { 00270 Congruence_System cgs_copy = cgs; 00271 add_recycled_congruences(cgs_copy); 00272 } 00273 }
void Parma_Polyhedra_Library::Grid::add_recycled_congruences | ( | Congruence_System & | cgs | ) |
Adds the congruences in cgs
to *this.
cgs | The congruence system to be added to *this . The congruences in cgs may be recycled. |
std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
cgs
upon successful or exceptional return is that it can be safely destroyed. Definition at line 1194 of file Grid_public.cc.
References Parma_Polyhedra_Library::Congruence_System::begin(), clear_congruences_minimized(), clear_generators_up_to_date(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::end(), Parma_Polyhedra_Library::Matrix::has_no_rows(), marked_empty(), OK(), Parma_Polyhedra_Library::Congruence_System::recycling_insert(), set_empty(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), throw_dimension_incompatible(), and update_congruences().
Referenced by add_congruences(), congruence_widening_assign(), contains_integer_point(), expand_space_dimension(), generalized_affine_image(), generalized_affine_preimage(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), and limited_generator_extrapolation_assign().
01194 { 01195 // Dimension-compatibility check. 01196 const dimension_type cgs_space_dim = cgs.space_dimension(); 01197 if (space_dim < cgs_space_dim) 01198 throw_dimension_incompatible("add_recycled_congruences(cgs)", "cgs", cgs); 01199 01200 if (cgs.has_no_rows()) 01201 return; 01202 01203 if (marked_empty()) 01204 return; 01205 01206 if (space_dim == 0) { 01207 // In a 0-dimensional space the congruences are trivial (e.g., 0 01208 // == 0 or 1 %= 0) or false (e.g., 1 == 0). In a system of 01209 // congruences `begin()' and `end()' are equal if and only if the 01210 // system contains only trivial congruences. 01211 if (cgs.begin() != cgs.end()) 01212 // There is a congruence, it must be false, the grid becomes empty. 01213 set_empty(); 01214 return; 01215 } 01216 01217 // The congruences are required. 01218 if (!congruences_are_up_to_date()) 01219 update_congruences(); 01220 01221 // Swap (instead of copying) the coefficients of `cgs' (which is 01222 // writable). 01223 con_sys.recycling_insert(cgs); 01224 01225 // Congruences may not be minimized and generators are out of date. 01226 clear_congruences_minimized(); 01227 clear_generators_up_to_date(); 01228 // Note: the congruence system may have become unsatisfiable, thus 01229 // we do not check for satisfiability. 01230 assert(OK()); 01231 }
bool Parma_Polyhedra_Library::Grid::add_congruences_and_minimize | ( | const Congruence_System & | cgs | ) | [inline] |
Adds a copy of the congruences in cgs
to the system of congruences of *this
, reducing the result.
false
if and only if the result is empty.cgs | Contains the congruences that will be added to the system of congruences of *this . |
std::invalid_argument | Thrown if *this and cgs are dimension-incompatible. |
Definition at line 276 of file Grid.inlines.hh.
References add_recycled_congruences_and_minimize().
00276 { 00277 Congruence_System cgs_copy = cgs; 00278 return add_recycled_congruences_and_minimize(cgs_copy); 00279 }
bool Parma_Polyhedra_Library::Grid::add_recycled_congruences_and_minimize | ( | Congruence_System & | cgs | ) |
Adds the congruences in cgs
to the system of congruences of this
, reducing the result.
false
if and only if the result is empty.cgs | The congruence system to be added to *this . The congruences in cgs may be recycled. |
std::invalid_argument | Thrown if *this and cgs are dimension-incompatible. |
cgs
upon successful or exceptional return is that it can be safely destroyed.Definition at line 1234 of file Grid_public.cc.
References Parma_Polyhedra_Library::Congruence_System::begin(), clear_congruences_minimized(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::end(), Parma_Polyhedra_Library::Matrix::has_no_rows(), marked_empty(), minimize(), OK(), Parma_Polyhedra_Library::Congruence_System::recycling_insert(), set_empty(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), status, Parma_Polyhedra_Library::Grid::Status::test_zero_dim_univ(), throw_dimension_incompatible(), update_congruences(), and update_generators().
Referenced by add_congruence_and_minimize(), and add_congruences_and_minimize().
01234 { 01235 // Dimension-compatibility check. 01236 const dimension_type cgs_space_dim = cgs.space_dimension(); 01237 if (space_dim < cgs_space_dim) 01238 throw_dimension_incompatible("add_recycled_congruences_and_minimize(cgs)", 01239 "cgs", cgs); 01240 01241 // Adding no congruences: just minimize. 01242 if (cgs.has_no_rows()) 01243 return minimize(); 01244 01245 // Dealing with zero-dimensional space grids first. 01246 if (space_dim == 0) { 01247 // In a 0-dimensional space the congruences are trivial (e.g., 0 01248 // == 0 or 1 %= 0) or false (e.g., 1 == 0). In a system of 01249 // congruences `begin()' and `end()' are equal if and only if the 01250 // system contains only trivial congruences. 01251 if (cgs.begin() == cgs.end()) 01252 return true; 01253 // There is a congruence, it must be false, the grid is empty. 01254 if (status.test_zero_dim_univ()) 01255 set_empty(); 01256 return false; 01257 } 01258 01259 if (marked_empty()) 01260 return false; 01261 01262 if (!congruences_are_up_to_date()) 01263 update_congruences(); 01264 01265 con_sys.recycling_insert(cgs); 01266 01267 clear_congruences_minimized(); 01268 01269 #ifndef NDEBUG 01270 bool ret = update_generators(); 01271 assert(OK()); 01272 return ret; 01273 #else 01274 return update_generators(); 01275 #endif 01276 }
void Parma_Polyhedra_Library::Grid::add_constraint | ( | const Constraint & | c | ) | [inline] |
If the constraint c
is an equality, it is added to *this
.
c | The constraint. |
std::invalid_argument | Thrown if c is not an equality constraint or if *this and c are dimension-incompatible. |
Definition at line 302 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 add_constraint_and_minimize().
00302 { 00303 // Space dimension compatibility check. 00304 if (space_dim < c.space_dimension()) 00305 throw_dimension_incompatible("add_constraint(c)", "c", c); 00306 if (!marked_empty()) 00307 add_constraint_no_check(c); 00308 }
bool Parma_Polyhedra_Library::Grid::add_constraint_and_minimize | ( | const Constraint & | c | ) | [inline] |
If the constraint c
is an equality, it is added to *this
, reducing the result.
c | The constraint. |
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and c are dimension-incompatible. |
Definition at line 311 of file Grid.inlines.hh.
References add_constraint(), and minimize().
00311 { 00312 add_constraint(c); 00313 return minimize(); 00314 }
void Parma_Polyhedra_Library::Grid::add_constraints | ( | const Constraint_System & | cs | ) |
If all constraints in cs
are equality constraints, then copies are added to *this
.
cs | The constraints to be added. |
std::invalid_argument | Thrown if cs contains an equality constraint or if *this and cs are dimension-incompatible. |
Definition at line 1128 of file Grid_public.cc.
References add_constraint_no_check(), Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Constraint_System::end(), marked_empty(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
Referenced by add_constraints_and_minimize(), add_recycled_constraints(), and add_recycled_constraints_and_minimize().
01128 { 01129 // The dimension of `cs' must be at most `space_dim'. 01130 if (space_dim < cs.space_dimension()) 01131 throw_dimension_incompatible("add_constraints(cs)", "cs", cs); 01132 if (marked_empty()) 01133 return; 01134 01135 for (Constraint_System::const_iterator i = cs.begin(), 01136 cs_end = cs.end(); i != cs_end; ++i) { 01137 add_constraint_no_check(*i); 01138 if (marked_empty()) 01139 return; 01140 } 01141 }
bool Parma_Polyhedra_Library::Grid::add_constraints_and_minimize | ( | const Constraint_System & | cs | ) | [inline] |
If all the constraints in cs
are equality constraints, then copies are added to *this
, reducing the result.
cs | The constraints to be added. |
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
Definition at line 317 of file Grid.inlines.hh.
References add_constraints(), and minimize().
00317 { 00318 add_constraints(cs); 00319 return minimize(); 00320 }
void Parma_Polyhedra_Library::Grid::add_recycled_constraints | ( | Constraint_System & | cs | ) | [inline] |
If all the constraints in cs
are equality constraints, then they are added to *this
.
cs | The constraint system to be added to *this . The equalities in cs may be recycled. |
std::invalid_argument | Thrown if cs contains an equality constraint or if *this and cs are dimension-incompatible. |
cs
upon successful or exceptional return is that it can be safely destroyed. Definition at line 323 of file Grid.inlines.hh.
References add_constraints().
00323 { 00324 // TODO: really recycle the constraints. 00325 add_constraints(cs); 00326 }
bool Parma_Polyhedra_Library::Grid::add_recycled_constraints_and_minimize | ( | Constraint_System & | cs | ) | [inline] |
If all the constraints in cs
are equality constraints, then they are added to *this
, reducing the result.
cs | The constraint system to be added to *this . The equalities in cs may be recycled. |
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
cs
upon successful or exceptional return is that it can be safely destroyed.Definition at line 329 of file Grid.inlines.hh.
References add_constraints(), and minimize().
00329 { 00330 add_constraints(cs); 00331 return minimize(); 00332 }
void Parma_Polyhedra_Library::Grid::refine_with_congruence | ( | const Congruence & | cg | ) | [inline] |
Uses a copy of the congruence cg
to refine *this
.
cg | The congruence used. |
std::invalid_argument | Thrown if *this and congruence cg are dimension-incompatible. |
Definition at line 282 of file Grid.inlines.hh.
References add_congruence().
00282 { 00283 add_congruence(cg); 00284 }
void Parma_Polyhedra_Library::Grid::refine_with_congruences | ( | const Congruence_System & | cgs | ) | [inline] |
Uses a copy of the congruences in cgs
to refine *this
.
cgs | The congruences used. |
std::invalid_argument | Thrown if *this and cgs are dimension-incompatible. |
Definition at line 287 of file Grid.inlines.hh.
References add_congruences().
00287 { 00288 add_congruences(cgs); 00289 }
void Parma_Polyhedra_Library::Grid::refine_with_constraint | ( | const Constraint & | c | ) |
Uses a copy of the constraint c
to refine *this
.
c | The constraint used. If it is not an equality, it will be ignored |
std::invalid_argument | Thrown if *this and c are dimension-incompatible. |
Definition at line 1407 of file Grid_public.cc.
References marked_empty(), refine_no_check(), space_dim, Parma_Polyhedra_Library::Constraint::space_dimension(), and throw_dimension_incompatible().
01407 { 01408 // The dimension of `c' must be at most `space_dim'. 01409 if (space_dim < c.space_dimension()) 01410 throw_dimension_incompatible("refine_with_constraint(c)", "c", c); 01411 if (marked_empty()) 01412 return; 01413 refine_no_check(c); 01414 }
void Parma_Polyhedra_Library::Grid::refine_with_constraints | ( | const Constraint_System & | cs | ) |
Uses a copy of the constraints in cs
to refine *this
.
cs | The constraints used. Constraints that are not equalities are ignored. |
std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
Definition at line 1417 of file Grid_public.cc.
References Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Constraint_System::end(), marked_empty(), refine_no_check(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01417 { 01418 // The dimension of `cs' must be at most `space_dim'. 01419 if (space_dim < cs.space_dimension()) 01420 throw_dimension_incompatible("refine_with_constraints(cs)", "cs", cs); 01421 01422 for (Constraint_System::const_iterator i = cs.begin(), 01423 cs_end = cs.end(); !marked_empty() && i != cs_end; ++i) 01424 refine_no_check(*i); 01425 }
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
.
gs | Contains the generators that will be added to the system of generators of *this . |
std::invalid_argument | Thrown 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 1338 of file Grid_public.cc.
References add_recycled_grid_generators().
01338 { 01339 // TODO: this is just an executable specification. 01340 Grid_Generator_System gs_copy = gs; 01341 add_recycled_grid_generators(gs_copy); 01342 }
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
.
gs | The generator system to be added to *this . The generators in gs may be recycled. |
std::invalid_argument | Thrown if *this and gs are dimension-incompatible. |
gs
upon successful or exceptional return is that it can be safely destroyed. Definition at line 1279 of file Grid_public.cc.
References clear_congruences_up_to_date(), clear_empty(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::has_points(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), marked_empty(), normalize_divisors(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), set_generators_up_to_date(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), Parma_Polyhedra_Library::swap(), throw_dimension_incompatible(), throw_invalid_generators(), and update_generators().
Referenced by add_grid_generators(), generalized_affine_image(), generalized_affine_preimage(), and generator_widening_assign().
01279 { 01280 // Dimension-compatibility check. 01281 const dimension_type gs_space_dim = gs.space_dimension(); 01282 if (space_dim < gs_space_dim) 01283 throw_dimension_incompatible("add_recycled_grid_generators(gs)", "gs", gs); 01284 01285 // Adding no generators leaves the grid the same. 01286 if (gs.has_no_rows()) 01287 return; 01288 01289 // Adding valid generators to a zero-dimensional grid transforms it 01290 // to the zero-dimensional universe grid. 01291 if (space_dim == 0) { 01292 if (marked_empty()) 01293 set_zero_dim_univ(); 01294 else 01295 assert(gs.has_points()); 01296 assert(OK(true)); 01297 return; 01298 } 01299 01300 if (!marked_empty()) { 01301 // The grid contains at least one point. 01302 01303 if (!generators_are_up_to_date()) 01304 update_generators(); 01305 normalize_divisors(gs, gen_sys); 01306 01307 gen_sys.recycling_insert(gs); 01308 01309 // Congruences are out of date and generators are not minimized. 01310 clear_congruences_up_to_date(); 01311 clear_generators_minimized(); 01312 01313 assert(OK(true)); 01314 return; 01315 } 01316 01317 // The grid is empty. 01318 01319 // `gs' must contain at least one point. 01320 if (!gs.has_points()) 01321 throw_invalid_generators("add_recycled_grid_generators(gs)", "gs"); 01322 01323 // Adjust `gs' to the right dimension. 01324 gs.insert(parameter(0*Variable(space_dim-1))); 01325 01326 std::swap(gen_sys, gs); 01327 01328 normalize_divisors(gen_sys); 01329 01330 // The grid is no longer empty and generators are up-to-date. 01331 set_generators_up_to_date(); 01332 clear_empty(); 01333 01334 assert(OK()); 01335 }
bool Parma_Polyhedra_Library::Grid::add_grid_generators_and_minimize | ( | const Grid_Generator_System & | gs | ) |
Adds a copy of the generators in gs
to the system of generators of *this
, reducing the result.
false
if and only if the result is empty.gs | Contains the generators that will be added to the system of generators of *this . |
std::invalid_argument | Thrown 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 1400 of file Grid_public.cc.
References add_recycled_grid_generators_and_minimize().
01400 { 01401 // TODO: this is just an executable specification. 01402 Grid_Generator_System gs_copy = gs; 01403 return add_recycled_grid_generators_and_minimize(gs_copy); 01404 }
bool Parma_Polyhedra_Library::Grid::add_recycled_grid_generators_and_minimize | ( | Grid_Generator_System & | gs | ) |
Adds the generators in gs
to the system of generators of this
, reducing the result.
false
if and only if the result is empty.gs | The generator system to be added to *this . The generators in gs may be recycled. |
std::invalid_argument | Thrown if *this and gs are dimension-incompatible. |
gs
upon successful or exceptional return is that it can be safely destroyed.Definition at line 1346 of file Grid_public.cc.
References clear_empty(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::has_points(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), marked_empty(), minimize(), normalize_divisors(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), Parma_Polyhedra_Library::swap(), throw_dimension_incompatible(), throw_invalid_generators(), update_congruences(), and update_generators().
Referenced by add_grid_generator_and_minimize(), and add_grid_generators_and_minimize().
01346 { 01347 // Dimension-compatibility check: the dimension of `gs' must be less 01348 // than or equal to that of space_dim. 01349 const dimension_type gs_space_dim = gs.space_dimension(); 01350 if (space_dim < gs_space_dim) 01351 throw_dimension_incompatible("add_recycled_generators_and_minimize(gs)", 01352 "gs", gs); 01353 01354 // Adding no generators is equivalent to just requiring reduction. 01355 if (gs.has_no_rows()) 01356 return minimize(); 01357 01358 // Adding valid generators to a zero-dimensional grid produces the 01359 // zero-dimensional universe grid. 01360 if (space_dim == 0) { 01361 if (marked_empty()) 01362 set_zero_dim_univ(); 01363 else 01364 assert(gs.has_points()); 01365 assert(OK(true)); 01366 return true; 01367 } 01368 01369 // Adjust `gs' to the right dimension. 01370 gs.insert(parameter(0*Variable(space_dim-1))); 01371 01372 if (!marked_empty()) { 01373 // The grid contains at least one point. 01374 01375 if (!generators_are_up_to_date()) 01376 update_generators(); 01377 normalize_divisors(gs, gen_sys); 01378 01379 for (dimension_type row = 0, 01380 gs_num_rows = gs.num_rows(); row < gs_num_rows; ++row) 01381 gen_sys.recycling_insert(gs[row]); 01382 } 01383 else { 01384 // The grid is empty: check if `gs' contains a point. 01385 if (!gs.has_points()) 01386 throw_invalid_generators("add_recycled_generators_and_minimize(gs)", 01387 "gs"); 01388 std::swap(gen_sys, gs); 01389 normalize_divisors(gen_sys); 01390 clear_empty(); 01391 } 01392 clear_generators_minimized(); 01393 update_congruences(); 01394 01395 assert(OK(true)); 01396 return true; 01397 }
void Parma_Polyhedra_Library::Grid::unconstrain | ( | Variable | var | ) |
Computes the cylindrification of *this
with respect to space dimension var
, assigning the result to *this
.
var | The space dimension that will be unconstrained. |
std::invalid_argument | Thrown if var is not a space dimension of *this . |
Definition at line 1428 of file Grid_public.cc.
References clear_congruences_up_to_date(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Variable::id(), marked_empty(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), space_dim, throw_dimension_incompatible(), and update_generators().
01428 { 01429 // Dimension-compatibility check. 01430 if (space_dim < var.id()) 01431 throw_dimension_incompatible("unconstrain(var)", var.id()); 01432 01433 // Do something only if the grid is non-empty. 01434 if (marked_empty() 01435 || (!generators_are_up_to_date() && !update_generators())) 01436 // Empty: do nothing. 01437 return; 01438 01439 assert(generators_are_up_to_date()); 01440 Grid_Generator l = grid_line(var); 01441 gen_sys.recycling_insert(l); 01442 // With the added generator, congruences are out of date. 01443 clear_congruences_up_to_date(); 01444 clear_generators_minimized(); 01445 assert(OK()); 01446 }
void Parma_Polyhedra_Library::Grid::unconstrain | ( | const Variables_Set & | to_be_unconstrained | ) |
Computes the cylindrification of *this
with respect to the set of space dimensions to_be_unconstrained
, assigning the result to *this
.
to_be_unconstrained | The set of space dimension that will be unconstrained. |
std::invalid_argument | Thrown if *this is dimension-incompatible with one of the Variable objects contained in to_be_removed . |
Definition at line 1449 of file Grid_public.cc.
References clear_congruences_up_to_date(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), marked_empty(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), space_dim, throw_dimension_incompatible(), and update_generators().
01449 { 01450 // The cylindrification wrt no dimensions is a no-op. 01451 // This case also captures the only legal cylindrification 01452 // of a grid in a 0-dim space. 01453 if (to_be_unconstrained.empty()) 01454 return; 01455 01456 // Dimension-compatibility check. 01457 const dimension_type min_space_dim = to_be_unconstrained.space_dimension(); 01458 if (space_dim < min_space_dim) 01459 throw_dimension_incompatible("unconstrain(vs)", min_space_dim); 01460 01461 // Do something only if the grid is non-empty. 01462 if (marked_empty() 01463 || (!generators_are_up_to_date() && !update_generators())) 01464 // Empty: do nothing. 01465 return; 01466 01467 assert(generators_are_up_to_date()); 01468 // Since `gen_sys' is not empty, the space dimension of the inserted 01469 // generators are automatically adjusted. 01470 for (Variables_Set::const_iterator tbu = to_be_unconstrained.begin(), 01471 tbu_end = to_be_unconstrained.end(); tbu != tbu_end; ++tbu) { 01472 Grid_Generator l = grid_line(Variable(*tbu)); 01473 gen_sys.recycling_insert(l); 01474 } 01475 // Constraints are no longer up-to-date. 01476 clear_generators_minimized(); 01477 clear_congruences_up_to_date(); 01478 assert(OK()); 01479 }
void Parma_Polyhedra_Library::Grid::intersection_assign | ( | const Grid & | y | ) |
Assigns to *this
the intersection of *this
and y
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1482 of file Grid_public.cc.
References clear_congruences_minimized(), clear_generators_up_to_date(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Congruence_System::insert(), marked_empty(), OK(), set_empty(), space_dim, throw_dimension_incompatible(), and update_congruences().
Referenced by intersection_assign_and_minimize(), and is_disjoint_from().
01482 { 01483 Grid& x = *this; 01484 // Dimension-compatibility check. 01485 if (x.space_dim != y.space_dim) 01486 throw_dimension_incompatible("intersection_assign(y)", "y", y); 01487 01488 // If one of the two grids is empty, the intersection is empty. 01489 if (x.marked_empty()) 01490 return; 01491 if (y.marked_empty()) { 01492 x.set_empty(); 01493 return; 01494 } 01495 01496 // If both grids are zero-dimensional, then at this point they are 01497 // necessarily universe, so the intersection is also universe. 01498 if (x.space_dim == 0) 01499 return; 01500 01501 // The congruences must be up-to-date. 01502 if (!x.congruences_are_up_to_date()) 01503 x.update_congruences(); 01504 if (!y.congruences_are_up_to_date()) 01505 y.update_congruences(); 01506 01507 if (!y.con_sys.has_no_rows()) { 01508 x.con_sys.insert(y.con_sys); 01509 // Grid_Generators may be out of date and congruences may have changed 01510 // from minimal form. 01511 x.clear_generators_up_to_date(); 01512 x.clear_congruences_minimized(); 01513 } 01514 01515 assert(x.OK() && y.OK()); 01516 }
bool Parma_Polyhedra_Library::Grid::intersection_assign_and_minimize | ( | const Grid & | y | ) |
Assigns to *this
the intersection of *this
and y
, reducing the result.
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1519 of file Grid_public.cc.
References intersection_assign(), and minimize().
01519 { 01520 intersection_assign(y); 01521 return minimize(); 01522 }
void Parma_Polyhedra_Library::Grid::upper_bound_assign | ( | const Grid & | y | ) |
Assigns to *this
the least upper bound of *this
and y
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1525 of file Grid_public.cc.
References clear_congruences_up_to_date(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), marked_empty(), normalize_divisors(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), space_dim, throw_dimension_incompatible(), and update_generators().
Referenced by difference_assign(), fold_space_dimensions(), upper_bound_assign_and_minimize(), and upper_bound_assign_if_exact().
01525 { 01526 Grid& x = *this; 01527 // Dimension-compatibility check. 01528 if (x.space_dim != y.space_dim) 01529 throw_dimension_incompatible("upper_bound_assign(y)", "y", y); 01530 01531 // The join of a grid `gr' with an empty grid is `gr'. 01532 if (y.marked_empty()) 01533 return; 01534 if (x.marked_empty()) { 01535 x = y; 01536 return; 01537 } 01538 01539 // If both grids are zero-dimensional, then they are necessarily 01540 // universe grids, and so is their join. 01541 if (x.space_dim == 0) 01542 return; 01543 01544 // The generators must be up-to-date. 01545 if (!x.generators_are_up_to_date() && !x.update_generators()) { 01546 // Discovered `x' empty when updating generators. 01547 x = y; 01548 return; 01549 } 01550 if (!y.generators_are_up_to_date() && !y.update_generators()) 01551 // Discovered `y' empty when updating generators. 01552 return; 01553 01554 // Match the divisors of the x and y generator systems. 01555 Grid_Generator_System gs(y.gen_sys); 01556 normalize_divisors(x.gen_sys, gs); 01557 x.gen_sys.recycling_insert(gs); 01558 // Congruences may be out of date and generators may have lost 01559 // minimal form. 01560 x.clear_congruences_up_to_date(); 01561 x.clear_generators_minimized(); 01562 01563 // At this point both `x' and `y' are not empty. 01564 assert(x.OK(true) && y.OK(true)); 01565 }
bool Parma_Polyhedra_Library::Grid::upper_bound_assign_and_minimize | ( | const Grid & | y | ) |
Assigns to *this
the least upper bound of *this
and y
, reducing the result.
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1568 of file Grid_public.cc.
References minimize(), and upper_bound_assign().
01568 { 01569 upper_bound_assign(y); 01570 return minimize(); 01571 }
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.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1574 of file Grid_public.cc.
References difference_assign(), generators_are_up_to_date(), is_included_in(), marked_empty(), space_dim, throw_dimension_incompatible(), and upper_bound_assign().
01574 { 01575 Grid& x = *this; 01576 01577 // Dimension-compatibility check. 01578 if (x.space_dim != y.space_dim) 01579 throw_dimension_incompatible("upper_bound_assign_if_exact(y)", "y", y); 01580 01581 if (x.marked_empty() 01582 || y.marked_empty() 01583 || x.space_dim == 0 01584 || x.is_included_in(y) 01585 || y.is_included_in(x)) { 01586 upper_bound_assign(y); 01587 return true; 01588 } 01589 01590 // The above test 'x.is_included_in(y)' will ensure the generators of x 01591 // are up to date. 01592 assert(generators_are_up_to_date()); 01593 01594 Grid x_copy = x; 01595 x_copy.upper_bound_assign(y); 01596 x_copy.difference_assign(y); 01597 if (x_copy.is_included_in(x)) { 01598 upper_bound_assign(y); 01599 return true; 01600 } 01601 01602 return false; 01603 }
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.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1606 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::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(), OK(), relation_with(), set_empty(), space_dim, throw_dimension_incompatible(), and upper_bound_assign().
Referenced by upper_bound_assign_if_exact().
01606 { 01607 Grid& x = *this; 01608 // Dimension-compatibility check. 01609 if (x.space_dim != y.space_dim) 01610 throw_dimension_incompatible("difference_assign(y)", "y", y); 01611 01612 if (y.marked_empty() || x.marked_empty()) 01613 return; 01614 01615 // If both grids are zero-dimensional, then they are necessarily 01616 // universe grids, so the result is empty. 01617 if (x.space_dim == 0) { 01618 x.set_empty(); 01619 return; 01620 } 01621 01622 if (y.contains(x)) { 01623 x.set_empty(); 01624 return; 01625 } 01626 01627 Grid new_grid(x.space_dim, EMPTY); 01628 01629 const Congruence_System& y_cgs = y.congruences(); 01630 for (Congruence_System::const_iterator i = y_cgs.begin(), 01631 y_cgs_end = y_cgs.end(); i != y_cgs_end; ++i) { 01632 const Congruence& cg = *i; 01633 01634 // The 2-complement cg2 of cg = ((e %= 0) / m) is the congruence 01635 // defining the sets of points exactly half-way between successive 01636 // hyperplanes e = km and e = (k+1)m, for any integer k; that is, 01637 // the hyperplanes defined by 2e = (2k + 1)m, for any integer k. 01638 // Thus `cg2' is the congruence ((2e %= m) / 2m). 01639 01640 // As the grid difference must be a grid, only add the 01641 // 2-complement congruence to x if the resulting grid includes all 01642 // the points in x that did not satisfy `cg'. 01643 01644 // The 2-complement of cg can be included in the result only if x 01645 // holds points other than those in cg. 01646 if (x.relation_with(cg).implies(Poly_Con_Relation::is_included())) 01647 continue; 01648 01649 if (cg.is_proper_congruence()) { 01650 const Linear_Expression e = Linear_Expression(cg); 01651 // Congruence cg is ((e %= 0) / m). 01652 const Coefficient& m = cg.modulus(); 01653 // If x is included in the grid defined by the congruences cg 01654 // and its 2-complement (i.e. the grid defined by the congruence 01655 // (2e %= 0) / m) then add the 2-complement to the potential 01656 // result. 01657 if (x.relation_with((2*e %= 0) / m) 01658 .implies(Poly_Con_Relation::is_included())) { 01659 Grid z = x; 01660 z.add_congruence_no_check((2*e %= m) / (2*m)); 01661 new_grid.upper_bound_assign(z); 01662 continue; 01663 } 01664 } 01665 return; 01666 } 01667 01668 *this = new_grid; 01669 01670 assert(OK()); 01671 }
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.
std::invalid_argument | Thrown if *this and y are topology-incompatible or dimension-incompatible. |
Definition at line 1674 of file Grid_public.cc.
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
.
var | The variable to which the affine expression is assigned; | |
expr | The numerator of the affine expression; | |
denominator | The denominator of the affine expression (optional argument with default value 1). |
std::invalid_argument | Thrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a space dimension of *this . |
is assigned to var
where expr
is (
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:
var
in this transformation (i.e.,
so that the inverse transformation is
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 1681 of file Grid_public.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::affine_image(), Parma_Polyhedra_Library::Congruence_System::affine_preimage(), clear_congruences_minimized(), clear_congruences_up_to_date(), clear_generators_minimized(), con_sys, congruences_are_up_to_date(), gen_sys, generators_are_up_to_date(), marked_empty(), minimize(), Parma_Polyhedra_Library::neg_assign(), normalize_divisors(), OK(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), throw_dimension_incompatible(), and throw_invalid_argument().
Referenced by fold_space_dimensions(), and generalized_affine_image().
01683 { 01684 // The denominator cannot be zero. 01685 if (denominator == 0) 01686 throw_invalid_argument("affine_image(v, e, d)", "d == 0"); 01687 01688 // Dimension-compatibility checks. 01689 // The dimension of `expr' must be at most the dimension of `*this'. 01690 const dimension_type expr_space_dim = expr.space_dimension(); 01691 if (space_dim < expr_space_dim) 01692 throw_dimension_incompatible("affine_image(v, e, d)", "e", expr); 01693 // `var' must be one of the dimensions of the grid. 01694 const dimension_type var_space_dim = var.space_dimension(); 01695 if (space_dim < var_space_dim) 01696 throw_dimension_incompatible("affine_image(v, e, d)", "v", var); 01697 01698 if (marked_empty()) 01699 return; 01700 01701 if (var_space_dim <= expr_space_dim && expr[var_space_dim] != 0) { 01702 // The transformation is invertible. 01703 if (generators_are_up_to_date()) { 01704 // Grid_Generator_System::affine_image() requires the third argument 01705 // to be a positive Coefficient. 01706 if (denominator > 0) 01707 gen_sys.affine_image(var_space_dim, expr, denominator); 01708 else 01709 gen_sys.affine_image(var_space_dim, -expr, -denominator); 01710 clear_generators_minimized(); 01711 // Strong normalization in gs::affine_image may have modified 01712 // divisors. 01713 normalize_divisors(gen_sys); 01714 } 01715 if (congruences_are_up_to_date()) { 01716 // To build the inverse transformation, 01717 // after copying and negating `expr', 01718 // we exchange the roles of `expr[var_space_dim]' and `denominator'. 01719 Linear_Expression inverse; 01720 if (expr[var_space_dim] > 0) { 01721 inverse = -expr; 01722 inverse[var_space_dim] = denominator; 01723 con_sys.affine_preimage(var_space_dim, inverse, expr[var_space_dim]); 01724 } 01725 else { 01726 // The new denominator is negative: we negate everything once 01727 // more, as Congruence_System::affine_preimage() requires the 01728 // third argument to be positive. 01729 inverse = expr; 01730 inverse[var_space_dim] = denominator; 01731 neg_assign(inverse[var_space_dim]); 01732 con_sys.affine_preimage(var_space_dim, inverse, -expr[var_space_dim]); 01733 } 01734 clear_congruences_minimized(); 01735 } 01736 } 01737 else { 01738 // The transformation is not invertible. 01739 // We need an up-to-date system of generators. 01740 if (!generators_are_up_to_date()) 01741 minimize(); 01742 if (!marked_empty()) { 01743 // Grid_Generator_System::affine_image() requires the third argument 01744 // to be a positive Coefficient. 01745 if (denominator > 0) 01746 gen_sys.affine_image(var_space_dim, expr, denominator); 01747 else 01748 gen_sys.affine_image(var_space_dim, -expr, -denominator); 01749 01750 clear_congruences_up_to_date(); 01751 clear_generators_minimized(); 01752 // Strong normalization in gs::affine_image may have modified 01753 // divisors. 01754 normalize_divisors(gen_sys); 01755 } 01756 } 01757 assert(OK()); 01758 }
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
.
var | The variable to which the affine expression is substituted; | |
expr | The numerator of the affine expression; | |
denominator | The denominator of the affine expression (optional argument with default value 1). |
std::invalid_argument | Thrown if denominator is zero or if expr and *this are dimension-incompatible or if var is not a space dimension of *this . |
is assigned to var
where expr
is (
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:
var
in this transformation (i.e.
, the inverse transformation is
.
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 1762 of file Grid_public.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::affine_image(), Parma_Polyhedra_Library::Congruence_System::affine_preimage(), clear_congruences_minimized(), clear_generators_minimized(), clear_generators_up_to_date(), con_sys, congruences_are_up_to_date(), gen_sys, generators_are_up_to_date(), marked_empty(), minimize(), Parma_Polyhedra_Library::neg_assign(), OK(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), throw_dimension_incompatible(), and throw_invalid_argument().
Referenced by generalized_affine_preimage().
01764 { 01765 // The denominator cannot be zero. 01766 if (denominator == 0) 01767 throw_invalid_argument("affine_preimage(v, e, d)", "d == 0"); 01768 01769 // Dimension-compatibility checks. 01770 // The dimension of `expr' should not be greater than the dimension 01771 // of `*this'. 01772 const dimension_type expr_space_dim = expr.space_dimension(); 01773 if (space_dim < expr_space_dim) 01774 throw_dimension_incompatible("affine_preimage(v, e, d)", "e", expr); 01775 // `var' should be one of the dimensions of the polyhedron. 01776 const dimension_type var_space_dim = var.space_dimension(); 01777 if (space_dim < var_space_dim) 01778 throw_dimension_incompatible("affine_preimage(v, e, d)", "v", var); 01779 01780 if (marked_empty()) 01781 return; 01782 01783 if (var_space_dim <= expr_space_dim && expr[var_space_dim] != 0) { 01784 // The transformation is invertible. 01785 if (congruences_are_up_to_date()) { 01786 // Congruence_System::affine_preimage() requires the third argument 01787 // to be a positive Coefficient. 01788 if (denominator > 0) 01789 con_sys.affine_preimage(var_space_dim, expr, denominator); 01790 else 01791 con_sys.affine_preimage(var_space_dim, -expr, -denominator); 01792 clear_congruences_minimized(); 01793 } 01794 if (generators_are_up_to_date()) { 01795 // To build the inverse transformation, 01796 // after copying and negating `expr', 01797 // we exchange the roles of `expr[var_space_dim]' and `denominator'. 01798 Linear_Expression inverse; 01799 if (expr[var_space_dim] > 0) { 01800 inverse = -expr; 01801 inverse[var_space_dim] = denominator; 01802 gen_sys.affine_image(var_space_dim, inverse, expr[var_space_dim]); 01803 } 01804 else { 01805 // The new denominator is negative: we negate everything once 01806 // more, as Grid_Generator_System::affine_image() requires the 01807 // third argument to be positive. 01808 inverse = expr; 01809 inverse[var_space_dim] = denominator; 01810 neg_assign(inverse[var_space_dim]); 01811 gen_sys.affine_image(var_space_dim, inverse, -expr[var_space_dim]); 01812 } 01813 clear_generators_minimized(); 01814 } 01815 } 01816 else { 01817 // The transformation is not invertible. 01818 // We need an up-to-date system of congruences. 01819 if (!congruences_are_up_to_date()) 01820 minimize(); 01821 // Congruence_System::affine_preimage() requires the third argument 01822 // to be a positive Coefficient. 01823 if (denominator > 0) 01824 con_sys.affine_preimage(var_space_dim, expr, denominator); 01825 else 01826 con_sys.affine_preimage(var_space_dim, -expr, -denominator); 01827 01828 clear_generators_up_to_date(); 01829 clear_congruences_minimized(); 01830 } 01831 assert(OK()); 01832 }
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 .
var | The left hand side variable of the generalized affine relation; | |
relsym | The relation symbol where EQUAL is the symbol for a congruence relation; | |
expr | The numerator of the right hand side affine expression; | |
denominator | The denominator of the right hand side affine expression. Optional argument with an automatic value of one; | |
modulus | The modulus of the congruence lhs = rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero. |
std::invalid_argument | Thrown 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 1836 of file Grid_public.cc.
References add_grid_generator(), affine_image(), clear_congruences_up_to_date(), clear_generators_minimized(), Parma_Polyhedra_Library::EQUAL, gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), marked_empty(), minimize(), normalize_divisors(), OK(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), throw_dimension_incompatible(), and throw_invalid_argument().
Referenced by bounded_affine_image(), and generalized_affine_preimage().
01840 { 01841 01842 // The denominator cannot be zero. 01843 if (denominator == 0) 01844 throw_invalid_argument("generalized_affine_image(v, r, e, d, m)", 01845 "d == 0"); 01846 01847 // Dimension-compatibility checks. 01848 // The dimension of `expr' should not be greater than the dimension 01849 // of `*this'. 01850 const dimension_type expr_space_dim = expr.space_dimension(); 01851 if (space_dim < expr_space_dim) 01852 throw_dimension_incompatible("generalized_affine_image(v, r, e, d, m)", 01853 "e", expr); 01854 // `var' should be one of the dimensions of the grid. 01855 const dimension_type var_space_dim = var.space_dimension(); 01856 if (space_dim < var_space_dim) 01857 throw_dimension_incompatible("generalized_affine_image(v, r, e, d, m)", 01858 "v", var); 01859 01860 // Any image of an empty grid is empty. 01861 if (marked_empty()) 01862 return; 01863 01864 // If relsym is not EQUAL, then we return a safe approximation 01865 // by adding a line in the direction of var. 01866 if (relsym != EQUAL) { 01867 01868 if (modulus != 0) 01869 throw_invalid_argument("generalized_affine_image(v, r, e, d, m)", 01870 "r != EQUAL && m != 0"); 01871 01872 if (!generators_are_up_to_date()) 01873 minimize(); 01874 01875 // Any image of an empty grid is empty. 01876 if (marked_empty()) 01877 return; 01878 01879 add_grid_generator(grid_line(var)); 01880 01881 assert(OK()); 01882 return; 01883 } 01884 01885 assert(relsym == EQUAL); 01886 01887 affine_image(var, expr, denominator); 01888 01889 if (modulus == 0) 01890 return; 01891 01892 // Modulate dimension `var' according to `modulus'. 01893 01894 if (!generators_are_up_to_date()) 01895 minimize(); 01896 01897 // Test if minimization, possibly in affine_image, found an empty 01898 // grid. 01899 if (marked_empty()) 01900 return; 01901 01902 if (modulus < 0) 01903 gen_sys.insert(parameter(-modulus * var)); 01904 else 01905 gen_sys.insert(parameter(modulus * var)); 01906 01907 normalize_divisors(gen_sys); 01908 01909 clear_generators_minimized(); 01910 clear_congruences_up_to_date(); 01911 01912 assert(OK()); 01913 }
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 .
var | The left hand side variable of the generalized affine relation; | |
relsym | The relation symbol where EQUAL is the symbol for a congruence relation; | |
expr | The numerator of the right hand side affine expression; | |
denominator | The denominator of the right hand side affine expression. Optional argument with an automatic value of one; | |
modulus | The modulus of the congruence lhs = rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero. |
std::invalid_argument | Thrown 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 1916 of file Grid_public.cc.
References add_congruence_no_check(), add_grid_generator(), affine_preimage(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::EQUAL, generalized_affine_image(), generators_are_up_to_date(), is_empty(), marked_empty(), minimize(), Parma_Polyhedra_Library::neg_assign(), OK(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), TEMP_INTEGER, throw_dimension_incompatible(), and throw_invalid_argument().
Referenced by bounded_affine_preimage().
01920 { 01921 // The denominator cannot be zero. 01922 if (denominator == 0) 01923 throw_invalid_argument("generalized_affine_preimage(v, e, d, m)", 01924 "d == 0"); 01925 01926 // The dimension of `expr' should be at most the dimension of 01927 // `*this'. 01928 const dimension_type expr_space_dim = expr.space_dimension(); 01929 if (space_dim < expr_space_dim) 01930 throw_dimension_incompatible("generalized_affine_preimage(v, e, d, m)", 01931 "e", expr); 01932 // `var' should be one of the dimensions of the grid. 01933 const dimension_type var_space_dim = var.space_dimension(); 01934 if (space_dim < var_space_dim) 01935 throw_dimension_incompatible("generalized_affine_preimage(v, e, d, m)", 01936 "v", var); 01937 01938 // If relsym is not EQUAL, then we return a safe approximation 01939 // by adding a line in the direction of var. 01940 if (relsym != EQUAL) { 01941 01942 if (modulus != 0) 01943 throw_invalid_argument("generalized_affine_preimage(v, r, e, d, m)", 01944 "r != EQUAL && m != 0"); 01945 01946 if (!generators_are_up_to_date()) 01947 minimize(); 01948 01949 // Any image of an empty grid is empty. 01950 if (marked_empty()) 01951 return; 01952 01953 add_grid_generator(grid_line(var)); 01954 01955 assert(OK()); 01956 return; 01957 } 01958 01959 assert(relsym == EQUAL); 01960 // Any image of an empty grid is empty. 01961 if (marked_empty()) 01962 return; 01963 01964 // Check whether the affine relation is an affine function. 01965 if (modulus == 0) { 01966 affine_preimage(var, expr, denominator); 01967 return; 01968 } 01969 01970 // Check whether the preimage of this affine relation can be easily 01971 // computed as the image of its inverse relation. 01972 const Coefficient& var_coefficient = expr.coefficient(var); 01973 if (var_space_dim <= expr_space_dim && var_coefficient != 0) { 01974 Linear_Expression inverse_expr 01975 = expr - (denominator + var_coefficient) * var; 01976 TEMP_INTEGER(inverse_denominator); 01977 neg_assign(inverse_denominator, var_coefficient); 01978 if (modulus < 0) 01979 generalized_affine_image(var, EQUAL, inverse_expr, inverse_denominator, 01980 - modulus); 01981 else 01982 generalized_affine_image(var, EQUAL, inverse_expr, inverse_denominator, 01983 modulus); 01984 return; 01985 } 01986 01987 // Here `var_coefficient == 0', so that the preimage cannot be 01988 // easily computed by inverting the affine relation. Add the 01989 // congruence induced by the affine relation. 01990 { 01991 Congruence cg((denominator*var %= expr) / denominator); 01992 if (modulus < 0) 01993 cg /= -modulus; 01994 else 01995 cg /= modulus; 01996 add_congruence_no_check(cg); 01997 } 01998 01999 // If the resulting grid is empty, its preimage is empty too. 02000 // Note: DO check for emptiness here, as we will later add a line. 02001 if (is_empty()) 02002 return; 02003 add_grid_generator(grid_line(var)); 02004 assert(OK()); 02005 }
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 .
lhs | The left hand side affine expression. | |
relsym | The relation symbol where EQUAL is the symbol for a congruence relation; | |
rhs | The right hand side affine expression. | |
modulus | The modulus of the congruence lhs = rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero. |
std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs . |
Definition at line 2009 of file Grid_public.cc.
References add_congruence_no_check(), add_grid_generator(), add_recycled_congruences(), add_recycled_grid_generators(), add_space_dimensions_and_embed(), clear_congruences_up_to_date(), clear_generators_minimized(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::EQUAL, gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), is_empty(), marked_empty(), minimize(), Parma_Polyhedra_Library::neg_assign(), normalize_divisors(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), remove_higher_space_dimensions(), space_dim, Parma_Polyhedra_Library::Linear_Expression::space_dimension(), TEMP_INTEGER, throw_dimension_incompatible(), throw_invalid_argument(), and update_generators().
02012 { 02013 // Dimension-compatibility checks. 02014 // The dimension of `lhs' should be at most the dimension of 02015 // `*this'. 02016 dimension_type lhs_space_dim = lhs.space_dimension(); 02017 if (space_dim < lhs_space_dim) 02018 throw_dimension_incompatible("generalized_affine_image(e1, r, e2)", 02019 "e1", lhs); 02020 // The dimension of `rhs' should be at most the dimension of 02021 // `*this'. 02022 const dimension_type rhs_space_dim = rhs.space_dimension(); 02023 if (space_dim < rhs_space_dim) 02024 throw_dimension_incompatible("generalized_affine_image(e1, r, e2)", 02025 "e2", rhs); 02026 02027 // Any image of an empty grid is empty. 02028 if (marked_empty()) 02029 return; 02030 02031 // If relsym is not EQUAL, then we return a safe approximation 02032 // by adding a line in the direction of var. 02033 if (relsym != EQUAL) { 02034 02035 if (modulus != 0) 02036 throw_invalid_argument("generalized_affine_image(e1, r, e2, m)", 02037 "r != EQUAL && m != 0"); 02038 02039 if (!generators_are_up_to_date()) 02040 minimize(); 02041 02042 // Any image of an empty grid is empty. 02043 if (marked_empty()) 02044 return; 02045 02046 for (dimension_type i = space_dim; i-- > 0; ) 02047 if (lhs.coefficient(Variable(i)) != 0) 02048 add_grid_generator(grid_line(Variable(i))); 02049 02050 assert(OK()); 02051 return; 02052 } 02053 02054 assert(relsym == EQUAL); 02055 02056 TEMP_INTEGER(tmp_modulus); 02057 tmp_modulus = modulus; 02058 if (tmp_modulus < 0) 02059 neg_assign(tmp_modulus); 02060 02061 // Compute the actual space dimension of `lhs', 02062 // i.e., the highest dimension having a non-zero coefficient in `lhs'. 02063 do { 02064 if (lhs_space_dim == 0) { 02065 // All variables have zero coefficients, so `lhs' is a constant. 02066 add_congruence_no_check((lhs %= rhs) / tmp_modulus); 02067 return; 02068 } 02069 } 02070 while (lhs.coefficient(Variable(--lhs_space_dim)) == 0); 02071 02072 // Gather in `new_lines' the collections of all the lines having the 02073 // direction of variables occurring in `lhs'. While at it, check 02074 // whether there exists a variable occurring in both `lhs' and 02075 // `rhs'. 02076 Grid_Generator_System new_lines; 02077 bool lhs_vars_intersect_rhs_vars = false; 02078 for (dimension_type i = lhs_space_dim + 1; i-- > 0; ) 02079 if (lhs.coefficient(Variable(i)) != 0) { 02080 new_lines.insert(grid_line(Variable(i))); 02081 if (rhs.coefficient(Variable(i)) != 0) 02082 lhs_vars_intersect_rhs_vars = true; 02083 } 02084 02085 if (lhs_vars_intersect_rhs_vars) { 02086 // Some variables in `lhs' also occur in `rhs'. 02087 // To ease the computation, add an additional dimension. 02088 const Variable new_var = Variable(space_dim); 02089 add_space_dimensions_and_embed(1); 02090 02091 // Constrain the new dimension to be equal to the right hand side. 02092 // TODO: Use add_congruence() when it has been updated. 02093 Congruence_System new_cgs1(new_var == rhs); 02094 add_recycled_congruences(new_cgs1); 02095 if (!is_empty()) { 02096 // The grid still contains points. 02097 02098 // Existentially quantify all the variables occurring in the left 02099 // hand side expression. 02100 02101 // Adjust `new_lines' to the right dimension. 02102 new_lines.insert(parameter(0*Variable(space_dim-1))); 02103 // Add the lines to `gen_sys' (first make sure they are up-to-date). 02104 update_generators(); 02105 gen_sys.recycling_insert(new_lines); 02106 normalize_divisors(gen_sys); 02107 // Update the flags. 02108 clear_congruences_up_to_date(); 02109 clear_generators_minimized(); 02110 02111 // Constrain the new dimension so that it is congruent to the left 02112 // hand side expression modulo `modulus'. 02113 // TODO: Use add_congruence() when it has been updated. 02114 Congruence_System new_cgs2((lhs %= new_var) / tmp_modulus); 02115 add_recycled_congruences(new_cgs2); 02116 } 02117 02118 // Remove the temporarily added dimension. 02119 remove_higher_space_dimensions(space_dim-1); 02120 } 02121 else { 02122 // `lhs' and `rhs' variables are disjoint: 02123 // there is no need to add a further dimension. 02124 02125 // Only add the lines and congruence if there are points. 02126 if (is_empty()) 02127 return; 02128 02129 // Existentially quantify all the variables occurring in the left hand 02130 // side expression. 02131 add_recycled_grid_generators(new_lines); 02132 02133 // Constrain the left hand side expression so that it is congruent to 02134 // the right hand side expression modulo `modulus'. 02135 add_congruence_no_check((lhs %= rhs) / tmp_modulus); 02136 } 02137 02138 assert(OK()); 02139 }
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 .
lhs | The left hand side affine expression; | |
relsym | The relation symbol where EQUAL is the symbol for a congruence relation; | |
rhs | The right hand side affine expression; | |
modulus | The modulus of the congruence lhs = rhs. A modulus of zero indicates lhs == rhs. Optional argument with an automatic value of zero. |
std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs . |
Definition at line 2142 of file Grid_public.cc.
References add_congruence_no_check(), add_grid_generator(), add_recycled_congruences(), add_recycled_grid_generators(), add_space_dimensions_and_embed(), clear_congruences_up_to_date(), clear_generators_minimized(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), Parma_Polyhedra_Library::EQUAL, gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), is_empty(), marked_empty(), minimize(), Parma_Polyhedra_Library::neg_assign(), normalize_divisors(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), remove_higher_space_dimensions(), space_dim, Parma_Polyhedra_Library::Linear_Expression::space_dimension(), TEMP_INTEGER, throw_dimension_incompatible(), throw_invalid_argument(), and update_generators().
02145 { 02146 02147 // The dimension of `lhs' must be at most the dimension of `*this'. 02148 dimension_type lhs_space_dim = lhs.space_dimension(); 02149 if (space_dim < lhs_space_dim) 02150 throw_dimension_incompatible("generalized_affine_preimage(e1, e2, m)", 02151 "lhs", lhs); 02152 // The dimension of `rhs' must be at most the dimension of `*this'. 02153 const dimension_type rhs_space_dim = rhs.space_dimension(); 02154 if (space_dim < rhs_space_dim) 02155 throw_dimension_incompatible("generalized_affine_preimage(e1, e2, m)", 02156 "e2", rhs); 02157 02158 // Any preimage of an empty polyhedron is empty. 02159 if (marked_empty()) 02160 return; 02161 02162 // If relsym is not EQUAL, then we return a safe approximation 02163 // by adding a line in the direction of var. 02164 if (relsym != EQUAL) { 02165 02166 if (modulus != 0) 02167 throw_invalid_argument("generalized_affine_preimage(e1, r, e2, m)", 02168 "r != EQUAL && m != 0"); 02169 02170 if (!generators_are_up_to_date()) 02171 minimize(); 02172 02173 // Any image of an empty grid is empty. 02174 if (marked_empty()) 02175 return; 02176 02177 for (dimension_type i = lhs_space_dim + 1; i-- > 0; ) 02178 if (lhs.coefficient(Variable(i)) != 0) 02179 add_grid_generator(grid_line(Variable(i))); 02180 02181 assert(OK()); 02182 return; 02183 } 02184 02185 assert(relsym == EQUAL); 02186 02187 TEMP_INTEGER(tmp_modulus); 02188 tmp_modulus = modulus; 02189 if (tmp_modulus < 0) 02190 neg_assign(tmp_modulus); 02191 02192 // Compute the actual space dimension of `lhs', 02193 // i.e., the highest dimension having a non-zero coefficient in `lhs'. 02194 do { 02195 if (lhs_space_dim == 0) { 02196 // All variables have zero coefficients, so `lhs' is a constant. 02197 // In this case, preimage and image happen to be the same. 02198 add_congruence_no_check((lhs %= rhs) / tmp_modulus); 02199 return; 02200 } 02201 } 02202 while (lhs.coefficient(Variable(--lhs_space_dim)) == 0); 02203 02204 // Gather in `new_lines' the collections of all the lines having 02205 // the direction of variables occurring in `lhs'. 02206 // While at it, check whether or not there exists a variable 02207 // occurring in both `lhs' and `rhs'. 02208 Grid_Generator_System new_lines; 02209 bool lhs_vars_intersect_rhs_vars = false; 02210 for (dimension_type i = lhs_space_dim + 1; i-- > 0; ) 02211 if (lhs.coefficient(Variable(i)) != 0) { 02212 new_lines.insert(grid_line(Variable(i))); 02213 if (rhs.coefficient(Variable(i)) != 0) 02214 lhs_vars_intersect_rhs_vars = true; 02215 } 02216 02217 if (lhs_vars_intersect_rhs_vars) { 02218 // Some variables in `lhs' also occur in `rhs'. 02219 // To ease the computation, add an additional dimension. 02220 const Variable new_var = Variable(space_dim); 02221 add_space_dimensions_and_embed(1); 02222 02223 // Constrain the new dimension to be equal to `lhs' 02224 // TODO: Use add_congruence() when it has been updated. 02225 Congruence_System new_cgs1(new_var == lhs); 02226 add_recycled_congruences(new_cgs1); 02227 if (!is_empty()) { 02228 // The grid still contains points. 02229 02230 // Existentially quantify all the variables occurring in the left 02231 // hand side 02232 02233 // Adjust `new_lines' to the right dimension. 02234 new_lines.insert(parameter(0*Variable(space_dim-1))); 02235 // Add the lines to `gen_sys' (first make sure they are up-to-date). 02236 update_generators(); 02237 gen_sys.recycling_insert(new_lines); 02238 normalize_divisors(gen_sys); 02239 // Update the flags. 02240 clear_congruences_up_to_date(); 02241 clear_generators_minimized(); 02242 02243 // Constrain the new dimension so that it is related to 02244 // the right hand side modulo `modulus'. 02245 // TODO: Use add_congruence() when it has been updated. 02246 Congruence_System new_cgs2((rhs %= new_var) / tmp_modulus); 02247 add_recycled_congruences(new_cgs2); 02248 } 02249 02250 // Remove the temporarily added dimension. 02251 remove_higher_space_dimensions(space_dim-1); 02252 } 02253 else { 02254 // `lhs' and `rhs' variables are disjoint: 02255 // there is no need to add a further dimension. 02256 02257 // Constrain the left hand side expression so that it is congruent to 02258 // the right hand side expression modulo `mod'. 02259 add_congruence_no_check((lhs %= rhs) / tmp_modulus); 02260 02261 // Any image of an empty grid is empty. 02262 if (is_empty()) 02263 return; 02264 02265 // Existentially quantify all the variables occurring in `lhs'. 02266 add_recycled_grid_generators(new_lines); 02267 } 02268 assert(OK()); 02269 }
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 .
var | The variable updated by the affine relation; | |
lb_expr | The numerator of the lower bounding affine expression; | |
ub_expr | The numerator of the upper bounding affine expression; | |
denominator | The (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1). |
std::invalid_argument | Thrown if denominator is zero or if lb_expr (resp., ub_expr ) and *this are dimension-incompatible or if var is not a space dimension of *this . |
Definition at line 2273 of file Grid_public.cc.
References generalized_affine_image(), Parma_Polyhedra_Library::LESS_OR_EQUAL, marked_empty(), OK(), space_dim, Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::Variable::space_dimension(), throw_dimension_incompatible(), and throw_invalid_argument().
02276 { 02277 02278 // The denominator cannot be zero. 02279 if (denominator == 0) 02280 throw_invalid_argument("bounded_affine_image(v, lb, ub, d)", "d == 0"); 02281 02282 // Dimension-compatibility checks. 02283 // `var' should be one of the dimensions of the polyhedron. 02284 const dimension_type var_space_dim = var.space_dimension(); 02285 if (space_dim < var_space_dim) 02286 throw_dimension_incompatible("bounded_affine_image(v, lb, ub, d)", 02287 "v", var); 02288 // The dimension of `lb_expr' and `ub_expr' should not be 02289 // greater than the dimension of `*this'. 02290 const dimension_type lb_space_dim = lb_expr.space_dimension(); 02291 if (space_dim < lb_space_dim) 02292 throw_dimension_incompatible("bounded_affine_image(v, lb, ub)", 02293 "lb", lb_expr); 02294 const dimension_type ub_space_dim = ub_expr.space_dimension(); 02295 if (space_dim < ub_space_dim) 02296 throw_dimension_incompatible("bounded_affine_image(v, lb, ub)", 02297 "ub", ub_expr); 02298 02299 // Any image of an empty grid is empty. 02300 if (marked_empty()) 02301 return; 02302 02303 // In all other cases, generalized_affine_preimage() must 02304 // just add a line in the direction of var. 02305 generalized_affine_image(var, 02306 LESS_OR_EQUAL, 02307 ub_expr, 02308 denominator); 02309 02310 assert(OK()); 02311 }
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 .
var | The variable updated by the affine relation; | |
lb_expr | The numerator of the lower bounding affine expression; | |
ub_expr | The numerator of the upper bounding affine expression; | |
denominator | The (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1). |
std::invalid_argument | Thrown if denominator is zero or if lb_expr (resp., ub_expr ) and *this are dimension-incompatible or if var is not a space dimension of *this . |
Definition at line 2316 of file Grid_public.cc.
References generalized_affine_preimage(), Parma_Polyhedra_Library::LESS_OR_EQUAL, marked_empty(), OK(), space_dim, Parma_Polyhedra_Library::Linear_Expression::space_dimension(), Parma_Polyhedra_Library::Variable::space_dimension(), throw_dimension_incompatible(), and throw_invalid_argument().
02319 { 02320 02321 // The denominator cannot be zero. 02322 if (denominator == 0) 02323 throw_invalid_argument("bounded_affine_preimage(v, lb, ub, d)", "d == 0"); 02324 02325 // Dimension-compatibility checks. 02326 // `var' should be one of the dimensions of the polyhedron. 02327 const dimension_type var_space_dim = var.space_dimension(); 02328 if (space_dim < var_space_dim) 02329 throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub, d)", 02330 "v", var); 02331 // The dimension of `lb_expr' and `ub_expr' should not be 02332 // greater than the dimension of `*this'. 02333 const dimension_type lb_space_dim = lb_expr.space_dimension(); 02334 if (space_dim < lb_space_dim) 02335 throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub)", 02336 "lb", lb_expr); 02337 const dimension_type ub_space_dim = ub_expr.space_dimension(); 02338 if (space_dim < ub_space_dim) 02339 throw_dimension_incompatible("bounded_affine_preimage(v, lb, ub)", 02340 "ub", ub_expr); 02341 02342 // Any preimage of an empty polyhedron is empty. 02343 if (marked_empty()) 02344 return; 02345 02346 // In all other cases, generalized_affine_preimage() must 02347 // just add a line in the direction of var. 02348 generalized_affine_preimage(var, 02349 LESS_OR_EQUAL, 02350 ub_expr, 02351 denominator); 02352 02353 assert(OK()); 02354 }
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
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 2357 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(), normalize_divisors(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), set_empty(), Parma_Polyhedra_Library::Grid_Generator::set_is_parameter(), space_dim, throw_dimension_incompatible(), and update_generators().
02357 { 02358 Grid& x = *this; 02359 // Check dimension-compatibility. 02360 if (x.space_dim != y.space_dim) 02361 throw_dimension_incompatible("time_elapse_assign(y)", "y", y); 02362 02363 // Deal with the zero-dimensional case. 02364 if (x.space_dim == 0) { 02365 if (y.marked_empty()) 02366 x.set_empty(); 02367 return; 02368 } 02369 02370 // If either one of `x' or `y' is empty, the result is empty too. 02371 if (x.marked_empty()) 02372 return; 02373 if (y.marked_empty() 02374 || (!x.generators_are_up_to_date() && !x.update_generators()) 02375 || (!y.generators_are_up_to_date() && !y.update_generators())) { 02376 x.set_empty(); 02377 return; 02378 } 02379 02380 // At this point both generator systems are up-to-date. 02381 Grid_Generator_System gs = y.gen_sys; 02382 dimension_type gs_num_rows = gs.num_rows(); 02383 02384 normalize_divisors(gs, gen_sys); 02385 02386 for (dimension_type i = gs_num_rows; i-- > 0; ) { 02387 Grid_Generator& g = gs[i]; 02388 if (g.is_point()) 02389 // Transform the point into a parameter. 02390 g.set_is_parameter(); 02391 } 02392 02393 if (gs_num_rows == 0) 02394 // `y' was the grid containing a single point at the origin, so 02395 // the result is `x'. 02396 return; 02397 02398 // Append `gs' to the generators of `x'. 02399 02400 gen_sys.recycling_insert(gs); 02401 02402 x.clear_congruences_up_to_date(); 02403 x.clear_generators_minimized(); 02404 02405 assert(x.OK(true) && y.OK(true)); 02406 }
void Parma_Polyhedra_Library::Grid::topological_closure_assign | ( | ) | [inline] |
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.
y | A grid that must be contained in *this ; | |
tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 75 of file Grid_widenings.cc.
References add_recycled_congruences(), con_sys, congruences_are_minimized(), congruences_are_up_to_date(), contains(), dim_kinds, marked_empty(), Parma_Polyhedra_Library::Congruence_System::num_equalities(), Parma_Polyhedra_Library::Matrix::num_rows(), OK(), select_wider_congruences(), set_congruences_minimized(), set_empty(), simplify(), space_dim, Parma_Polyhedra_Library::swap(), throw_dimension_incompatible(), and update_congruences().
Referenced by limited_congruence_extrapolation_assign(), and widening_assign().
00075 { 00076 Grid& x = *this; 00077 Grid& y = const_cast<Grid&>(const_y); 00078 // Dimension-compatibility check. 00079 if (x.space_dim != y.space_dim) 00080 throw_dimension_incompatible("widening_assign(y)", "y", y); 00081 00082 // Stable behavior is only guaranteed if y is contained in or equal 00083 // to x. 00084 #ifndef NDEBUG 00085 { 00086 // Assume y is contained in or equal to x. 00087 const Grid x_copy = x; 00088 const Grid y_copy = y; 00089 assert(x_copy.contains(y_copy)); 00090 } 00091 #endif 00092 00093 // Leave `x' the same if `x' or `y' is zero-dimensional or empty. 00094 if (x.space_dim == 0 || x.marked_empty() || y.marked_empty()) 00095 return; 00096 00097 // Ensure that the `x' congruences are in minimal form. 00098 if (x.congruences_are_up_to_date()) { 00099 if (!x.congruences_are_minimized()) { 00100 if (simplify(x.con_sys, x.dim_kinds)) { 00101 // `x' is empty. 00102 x.set_empty(); 00103 return; 00104 } 00105 x.set_congruences_minimized(); 00106 } 00107 } 00108 else 00109 x.update_congruences(); 00110 00111 // Ensure that the `y' congruences are in minimal form. 00112 if (y.congruences_are_up_to_date()) { 00113 if (!y.congruences_are_minimized()) { 00114 if (simplify(y.con_sys, y.dim_kinds)) { 00115 // `y' is empty. 00116 y.set_empty(); 00117 return; 00118 } 00119 y.set_congruences_minimized(); 00120 } 00121 } 00122 else 00123 y.update_congruences(); 00124 00125 if (con_sys.num_equalities() < y.con_sys.num_equalities()) 00126 return; 00127 00128 // Copy into `cgs' the congruences of `x' that are common to `y', 00129 // according to the grid widening. 00130 Congruence_System cgs; 00131 x.select_wider_congruences(y, cgs); 00132 00133 if (cgs.num_rows() == con_sys.num_rows()) 00134 // All congruences were selected, thus the result is `x'. 00135 return; 00136 00137 // A strict subset of the congruences was selected. 00138 00139 Grid result(x.space_dim); 00140 result.add_recycled_congruences(cgs); 00141 00142 // Check whether we are using the widening-with-tokens technique 00143 // and there are still tokens available. 00144 if (tp && *tp > 0) { 00145 // There are tokens available. If `result' is not a subset of 00146 // `x', then it is less precise and we use one of the available 00147 // tokens. 00148 if (!x.contains(result)) 00149 --(*tp); 00150 } 00151 else 00152 // No tokens. 00153 std::swap(x, result); 00154 00155 assert(x.OK(true)); 00156 }
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.
y | A grid that must be contained in *this ; | |
tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 277 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::Matrix::has_no_rows(), 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(), simplify(), space_dim, Parma_Polyhedra_Library::swap(), throw_dimension_incompatible(), and update_generators().
Referenced by limited_generator_extrapolation_assign(), and widening_assign().
00277 { 00278 Grid& x = *this; 00279 Grid& y = const_cast<Grid&>(const_y); 00280 // Dimension-compatibility check. 00281 if (x.space_dim != y.space_dim) 00282 throw_dimension_incompatible("generator_widening_assign(y)", "y", y); 00283 00284 // Stable behavior is only guaranteed if y is contained in or equal 00285 // to x. 00286 #ifndef NDEBUG 00287 { 00288 // Assume y is contained in or equal to x. 00289 const Grid x_copy = x; 00290 const Grid y_copy = y; 00291 assert(x_copy.contains(y_copy)); 00292 } 00293 #endif 00294 00295 // Leave `x' the same if `x' or `y' is zero-dimensional or empty. 00296 if (x.space_dim == 0 || x.marked_empty() || y.marked_empty()) 00297 return; 00298 00299 // Ensure that the `x' generators are in minimal form. 00300 if (x.generators_are_up_to_date()) { 00301 if (!x.generators_are_minimized()) { 00302 simplify(x.gen_sys, x.dim_kinds); 00303 assert(!x.gen_sys.has_no_rows()); 00304 x.set_generators_minimized(); 00305 } 00306 } 00307 else 00308 x.update_generators(); 00309 00310 if (x.marked_empty()) 00311 return; 00312 00313 // Ensure that the `y' generators are in minimal form. 00314 if (y.generators_are_up_to_date()) { 00315 if (!y.generators_are_minimized()) { 00316 simplify(y.gen_sys, y.dim_kinds); 00317 assert(!y.gen_sys.has_no_rows()); 00318 y.set_generators_minimized(); 00319 } 00320 } 00321 else 00322 y.update_generators(); 00323 00324 if (gen_sys.num_rows() > y.gen_sys.num_rows()) 00325 return; 00326 00327 if (gen_sys.num_lines() > y.gen_sys.num_lines()) 00328 return; 00329 00330 // Copy into `ggs' the generators of `x' that are common to `y', 00331 // according to the grid widening. 00332 Grid_Generator_System ggs; 00333 x.select_wider_generators(y, ggs); 00334 00335 if (ggs.num_parameters() == gen_sys.num_parameters()) 00336 // All parameters are kept as parameters, thus the result is `x'. 00337 return; 00338 00339 // A strict subset of the parameters was selected. 00340 00341 Grid result(x.space_dim, EMPTY); 00342 result.add_recycled_grid_generators(ggs); 00343 00344 // Check whether we are using the widening-with-tokens technique 00345 // and there are still tokens available. 00346 if (tp && *tp > 0) { 00347 // There are tokens available. If `result' is not a subset of 00348 // `x', then it is less precise and we use one of the available 00349 // tokens. 00350 if (!x.contains(result)) 00351 --(*tp); 00352 } 00353 else 00354 // No tokens. 00355 std::swap(x, result); 00356 00357 assert(x.OK(true)); 00358 }
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.
y | A grid that must be contained in *this ; | |
tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 431 of file Grid_widenings.cc.
References congruence_widening_assign(), congruences_are_up_to_date(), contains(), generator_widening_assign(), generators_are_up_to_date(), space_dim, and throw_dimension_incompatible().
Referenced by limited_congruence_extrapolation_assign(), and limited_extrapolation_assign().
00431 { 00432 Grid& x = *this; 00433 Grid& y = const_cast<Grid&>(const_y); 00434 // Dimension-compatibility check. 00435 if (x.space_dim != y.space_dim) 00436 throw_dimension_incompatible("widening_assign(y)", "y", y); 00437 00438 // Stable behavior is only guaranteed if y is contained in or equal 00439 // to x. 00440 #ifndef NDEBUG 00441 { 00442 // Assume y is contained in or equal to x. 00443 const Grid x_copy = x; 00444 const Grid y_copy = y; 00445 assert(x_copy.contains(y_copy)); 00446 } 00447 #endif 00448 00449 // If the `x' congruences are up to date and `y' congruences are up 00450 // to date use the congruence widening. 00451 if (x.congruences_are_up_to_date() && y.congruences_are_up_to_date()) { 00452 x.congruence_widening_assign(y, tp); 00453 return; 00454 } 00455 00456 // If the `x' generators are up to date and `y' generators are up to 00457 // date use the generator widening. 00458 if (x.generators_are_up_to_date() && y.generators_are_up_to_date()) { 00459 x.generator_widening_assign(y, tp); 00460 return; 00461 } 00462 00463 x.congruence_widening_assign(y, tp); 00464 }
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
.
y | A grid that must be contained in *this ; | |
cgs | The system of congruences used to improve the widened grid; | |
tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
std::invalid_argument | Thrown if *this , y and cs are dimension-incompatible. |
Definition at line 159 of file Grid_widenings.cc.
References add_recycled_congruences(), congruence_widening_assign(), contains(), generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), marked_empty(), Parma_Polyhedra_Library::Matrix::num_rows(), OK(), relation_with(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), throw_dimension_incompatible(), update_generators(), and widening_assign().
00161 { 00162 Grid& x = *this; 00163 00164 // Check dimension compatibility. 00165 if (x.space_dim != y.space_dim) 00166 throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)", 00167 "y", y); 00168 // `cgs' must be dimension-compatible with the two grids. 00169 const dimension_type cgs_space_dim = cgs.space_dimension(); 00170 if (x.space_dim < cgs_space_dim) 00171 throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)", 00172 "cgs", cgs); 00173 00174 const dimension_type cgs_num_rows = cgs.num_rows(); 00175 // If `cgs' is empty (of rows), fall back to ordinary widening. 00176 if (cgs_num_rows == 0) { 00177 x.widening_assign(y, tp); 00178 return; 00179 } 00180 00181 #ifndef NDEBUG 00182 { 00183 // Assume that y is contained in or equal to x. 00184 const Grid x_copy = x; 00185 const Grid y_copy = y; 00186 assert(x_copy.contains(y_copy)); 00187 } 00188 #endif 00189 00190 if (y.marked_empty()) 00191 return; 00192 if (x.marked_empty()) 00193 return; 00194 00195 // The limited widening between two grids in a zero-dimensional 00196 // space is also a grid in a zero-dimensional space. 00197 if (x.space_dim == 0) 00198 return; 00199 00200 // Update the generators of `x': these are used to select, from the 00201 // congruences in `cgs', those that must be added to the widened 00202 // grid. 00203 if (!x.generators_are_up_to_date() && !x.update_generators()) 00204 // `x' is empty. 00205 return; 00206 00207 if (tp == NULL || *tp == 0) { 00208 // Widening may change the grid, so add the congruences. 00209 Congruence_System new_cgs; 00210 // The congruences to be added need only be satisfied by all the 00211 // generators of `x', as `y <= x'. Iterate upwards here, to keep 00212 // the relative ordering of congruences (just for aesthetics). 00213 for (dimension_type i = 0; i < cgs_num_rows; ++i) { 00214 const Congruence& cg = cgs[i]; 00215 if (x.relation_with(cg) == Poly_Con_Relation::is_included()) 00216 new_cgs.insert(cg); 00217 } 00218 x.congruence_widening_assign(y, tp); 00219 x.add_recycled_congruences(new_cgs); 00220 } 00221 else 00222 // There are tokens, so widening will leave the grid the same. 00223 x.congruence_widening_assign(y, tp); 00224 00225 assert(OK()); 00226 }
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
.
y | A grid that must be contained in *this ; | |
cgs | The system of congruences used to improve the widened grid; | |
tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
std::invalid_argument | Thrown if *this , y and cs are dimension-incompatible. |
Definition at line 361 of file Grid_widenings.cc.
References add_recycled_congruences(), contains(), 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::Matrix::num_rows(), OK(), relation_with(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), throw_dimension_incompatible(), and update_generators().
00363 { 00364 Grid& x = *this; 00365 00366 // Check dimension compatibility. 00367 if (x.space_dim != y.space_dim) 00368 throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)", 00369 "y", y); 00370 // `cgs' must be dimension-compatible with the two grids. 00371 const dimension_type cgs_space_dim = cgs.space_dimension(); 00372 if (x.space_dim < cgs_space_dim) 00373 throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)", 00374 "cgs", cgs); 00375 00376 const dimension_type cgs_num_rows = cgs.num_rows(); 00377 // If `cgs' is empty (of rows), fall back to ordinary widening. 00378 if (cgs_num_rows == 0) { 00379 x.generator_widening_assign(y, tp); 00380 return; 00381 } 00382 00383 #ifndef NDEBUG 00384 { 00385 // Assume that y is contained in or equal to x. 00386 const Grid x_copy = x; 00387 const Grid y_copy = y; 00388 assert(x_copy.contains(y_copy)); 00389 } 00390 #endif 00391 00392 if (y.marked_empty()) 00393 return; 00394 if (x.marked_empty()) 00395 return; 00396 00397 // The limited widening between two grids in a zero-dimensional 00398 // space is also a grid in a zero-dimensional space. 00399 if (x.space_dim == 0) 00400 return; 00401 00402 // Update the generators of `x': these are used to select, from the 00403 // congruences in `cgs', those that must be added to the widened 00404 // grid. 00405 if (!x.generators_are_up_to_date() && !x.update_generators()) 00406 // `x' is empty. 00407 return; 00408 00409 if (tp == NULL || *tp == 0) { 00410 // Widening may change the grid, so add the congruences. 00411 Congruence_System new_cgs; 00412 // The congruences to be added need only be satisfied by all the 00413 // generators of `x', as `y <= x'. Iterate upwards here, to keep 00414 // the relative ordering of congruences (just for aesthetics). 00415 for (dimension_type i = 0; i < cgs_num_rows; ++i) { 00416 const Congruence& cg = cgs[i]; 00417 if (x.relation_with(cg) == Poly_Con_Relation::is_included()) 00418 new_cgs.insert(cg); 00419 } 00420 x.generator_widening_assign(y, tp); 00421 x.add_recycled_congruences(new_cgs); 00422 } 00423 else 00424 // There are tokens, so widening will leave the grid the same. 00425 x.generator_widening_assign(y, tp); 00426 00427 assert(OK()); 00428 }
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
.
y | A grid that must be contained in *this ; | |
cgs | The system of congruences used to improve the widened grid; | |
tp | An optional pointer to an unsigned variable storing the number of available tokens (to be used when applying the widening with tokens delay technique). |
std::invalid_argument | Thrown if *this , y and cs are dimension-incompatible. |
Definition at line 467 of file Grid_widenings.cc.
References add_recycled_congruences(), contains(), generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Poly_Con_Relation::is_included(), marked_empty(), Parma_Polyhedra_Library::Matrix::num_rows(), OK(), relation_with(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), throw_dimension_incompatible(), update_generators(), and widening_assign().
00469 { 00470 Grid& x = *this; 00471 00472 // Check dimension compatibility. 00473 if (x.space_dim != y.space_dim) 00474 throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)", 00475 "y", y); 00476 // `cgs' must be dimension-compatible with the two grids. 00477 const dimension_type cgs_space_dim = cgs.space_dimension(); 00478 if (x.space_dim < cgs_space_dim) 00479 throw_dimension_incompatible("limited_extrapolation_assign(y, cgs)", 00480 "cgs", cgs); 00481 00482 const dimension_type cgs_num_rows = cgs.num_rows(); 00483 // If `cgs' is empty (of rows), fall back to ordinary widening. 00484 if (cgs_num_rows == 0) { 00485 x.widening_assign(y, tp); 00486 return; 00487 } 00488 00489 #ifndef NDEBUG 00490 { 00491 // Assume that y is contained in or equal to x. 00492 const Grid x_copy = x; 00493 const Grid y_copy = y; 00494 assert(x_copy.contains(y_copy)); 00495 } 00496 #endif 00497 00498 if (y.marked_empty()) 00499 return; 00500 if (x.marked_empty()) 00501 return; 00502 00503 // The limited widening between two grids in a zero-dimensional 00504 // space is also a grid in a zero-dimensional space. 00505 if (x.space_dim == 0) 00506 return; 00507 00508 // Update the generators of `x': these are used to select, from the 00509 // congruences in `cgs', those that must be added to the widened 00510 // grid. 00511 if (!x.generators_are_up_to_date() && !x.update_generators()) 00512 // `x' is empty. 00513 return; 00514 00515 if (tp == NULL || *tp == 0) { 00516 // Widening may change the grid, so add the congruences. 00517 Congruence_System new_cgs; 00518 // The congruences to be added need only be satisfied by all the 00519 // generators of `x', as `y <= x'. Iterate upwards here, to keep 00520 // the relative ordering of congruences (just for aesthetics). 00521 for (dimension_type i = 0; i < cgs_num_rows; ++i) { 00522 const Congruence& cg = cgs[i]; 00523 if (x.relation_with(cg) == Poly_Con_Relation::is_included()) 00524 new_cgs.insert(cg); 00525 } 00526 x.widening_assign(y, tp); 00527 x.add_recycled_congruences(new_cgs); 00528 } 00529 else 00530 // There are tokens, so widening will leave the grid the same. 00531 x.widening_assign(y, tp); 00532 00533 assert(OK()); 00534 }
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.
m | The number of dimensions to add. |
std::length_error | Thrown if adding m new space dimensions would cause the vector space to exceed dimension max_space_dimension() . |
Definition at line 78 of file Grid_chdims.cc.
References add_space_dimensions(), Parma_Polyhedra_Library::Grid_Generator_System::add_universe_rows_and_columns(), Parma_Polyhedra_Library::Matrix::add_zero_columns(), con_sys, CON_VIRTUAL, congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, gen_sys, generators_are_minimized(), generators_are_up_to_date(), LINE, marked_empty(), max_space_dimension(), Parma_Polyhedra_Library::Matrix::num_columns(), OK(), set_empty(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), space_dimension(), status, swap(), Parma_Polyhedra_Library::Matrix::swap_columns(), Parma_Polyhedra_Library::Grid::Status::test_zero_dim_univ(), throw_space_dimension_overflow(), and Parma_Polyhedra_Library::UNIVERSE.
Referenced by expand_space_dimension(), generalized_affine_image(), and generalized_affine_preimage().
00078 { 00079 if (m == 0) 00080 return; 00081 00082 // The space dimension of the resulting grid must be at most the 00083 // maximum allowed space dimension. 00084 if (m > max_space_dimension() - space_dimension()) 00085 throw_space_dimension_overflow("add_space_dimensions_and_embed(m)", 00086 "adding m new space dimensions exceeds " 00087 "the maximum allowed space dimension"); 00088 00089 // Adding dimensions to an empty grid is obtained by adjusting 00090 // `space_dim' and clearing `con_sys' (since it can contain the 00091 // integrality congruence of the current dimension). 00092 if (marked_empty()) { 00093 space_dim += m; 00094 set_empty(); 00095 return; 00096 } 00097 00098 // The case of a zero-dimension space grid. 00099 if (space_dim == 0) { 00100 // Since it is not empty, it has to be the universe grid. 00101 assert(status.test_zero_dim_univ()); 00102 // Swap *this with a newly created `m'-dimensional universe grid. 00103 Grid gr(m, UNIVERSE); 00104 swap(gr); 00105 return; 00106 } 00107 00108 // To embed an n-dimension space grid in a (n+m)-dimension space, we 00109 // add `m' zero-columns to the rows in the system of congruences; in 00110 // contrast, the system of generators needs additional rows, 00111 // corresponding to the vectors of the canonical basis for the added 00112 // dimensions. That is, for each new dimension we add the line 00113 // having that direction. This is done by invoking the function 00114 // add_space_dimensions(). 00115 if (congruences_are_up_to_date()) 00116 if (generators_are_up_to_date()) 00117 // Adds rows and/or columns to both matrices. 00118 add_space_dimensions(con_sys, gen_sys, m); 00119 else { 00120 // Only congruences are up-to-date, so modify only them. 00121 con_sys.add_zero_columns(m); 00122 dimension_type size = con_sys.num_columns() - 1; 00123 // Move the moduli. 00124 con_sys.swap_columns(size - m, size); 00125 if (congruences_are_minimized()) 00126 dim_kinds.resize(size, CON_VIRTUAL); 00127 } 00128 else { 00129 // Only generators are up-to-date, so modify only them. 00130 assert(generators_are_up_to_date()); 00131 gen_sys.add_universe_rows_and_columns(m); 00132 if (generators_are_minimized()) 00133 dim_kinds.resize(gen_sys.space_dimension() + 1, LINE); 00134 } 00135 // Update the space dimension. 00136 space_dim += m; 00137 00138 // Note: we do not check for satisfiability, because the system of 00139 // congruences may be unsatisfiable. 00140 assert(OK()); 00141 }
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.
m | The number of space dimensions to add. |
std::length_error | Thrown if adding m new space dimensions would cause the vector space to exceed dimension max_space_dimension() . |
Definition at line 152 of file Grid_chdims.cc.
References add_space_dimensions(), Parma_Polyhedra_Library::Congruence_System::add_unit_rows_and_columns(), con_sys, congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, EQUALITY, gen_sys, generators_are_minimized(), generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), marked_empty(), max_space_dimension(), normalize_divisors(), Parma_Polyhedra_Library::Matrix::num_columns(), OK(), set_empty(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), space_dimension(), status, swap(), Parma_Polyhedra_Library::Grid::Status::test_zero_dim_univ(), throw_space_dimension_overflow(), and Parma_Polyhedra_Library::UNIVERSE.
00152 { 00153 if (m == 0) 00154 return; 00155 00156 // The space dimension of the resulting grid should be at most the 00157 // maximum allowed space dimension. 00158 if (m > max_space_dimension() - space_dimension()) 00159 throw_space_dimension_overflow("add_space_dimensions_and_project(m)", 00160 "adding m new space dimensions exceeds " 00161 "the maximum allowed space dimension"); 00162 00163 // Adding dimensions to an empty grid is obtained by merely 00164 // adjusting `space_dim'. 00165 if (marked_empty()) { 00166 space_dim += m; 00167 set_empty(); 00168 return; 00169 } 00170 00171 if (space_dim == 0) { 00172 assert(status.test_zero_dim_univ()); 00173 // Swap *this with a newly created `n'-dimensional universe grid. 00174 Grid gr(m, UNIVERSE); 00175 swap(gr); 00176 return; 00177 } 00178 00179 // To project an n-dimension space grid in a (n+m)-dimension space, 00180 // we just add to the system of generators `m' zero-columns; in 00181 // contrast, in the system of congruences, new rows are needed in 00182 // order to avoid embedding the old grid in the new space. Thus, 00183 // for each new dimensions `x[k]', we add the constraint x[k] = 0; 00184 // this is done by invoking the function add_space_dimensions() 00185 // giving the system of constraints as the second argument. 00186 if (congruences_are_up_to_date()) 00187 if (generators_are_up_to_date()) 00188 // Add rows and/or columns to both matrices. 00189 add_space_dimensions(gen_sys, con_sys, m); 00190 else { 00191 // Only congruences are up-to-date so modify only them. 00192 con_sys.add_unit_rows_and_columns(m); 00193 if (congruences_are_minimized()) 00194 dim_kinds.resize(con_sys.num_columns() - 1, EQUALITY); 00195 } 00196 else { 00197 // Only generators are up-to-date so modify only them. 00198 assert(generators_are_up_to_date()); 00199 00200 // Add m zero columns onto gs. 00201 gen_sys.insert(parameter(0*Variable(space_dim + m - 1))); 00202 00203 normalize_divisors(gen_sys); 00204 00205 if (generators_are_minimized()) 00206 dim_kinds.resize(gen_sys.space_dimension() + 1, EQUALITY); 00207 } 00208 // Now update the space dimension. 00209 space_dim += m; 00210 00211 // Note: we do not check for satisfiability, because the system of 00212 // congruences may be unsatisfiable. 00213 assert(OK()); 00214 }
void Parma_Polyhedra_Library::Grid::concatenate_assign | ( | const Grid & | y | ) |
Assigns to *this
the concatenation of *this
and y
, taken in this order.
std::length_error | Thrown if the concatenation would cause the vector space to exceed dimension max_space_dimension() . |
Definition at line 217 of file Grid_chdims.cc.
References clear_congruences_minimized(), clear_generators_up_to_date(), con_sys, Parma_Polyhedra_Library::Congruence_System::concatenate(), congruences(), congruences_are_up_to_date(), marked_empty(), max_space_dimension(), OK(), set_empty(), space_dim, space_dimension(), throw_space_dimension_overflow(), and update_congruences().
00217 { 00218 // The space dimension of the resulting grid must be at most the 00219 // maximum allowed space dimension. 00220 if (y.space_dim > max_space_dimension() - space_dimension()) 00221 throw_space_dimension_overflow("concatenate_assign(y)", 00222 "concatenation exceeds the maximum " 00223 "allowed space dimension"); 00224 00225 const dimension_type added_columns = y.space_dim; 00226 00227 // If `*this' or `y' are empty grids just adjust the space 00228 // dimension. 00229 if (marked_empty() || y.marked_empty()) { 00230 space_dim += added_columns; 00231 set_empty(); 00232 return; 00233 } 00234 00235 // If `y' is a universe 0-dim grid, the result is `*this'. 00236 if (added_columns == 0) 00237 return; 00238 00239 // If `*this' is a universe 0-dim space grid, the result is `y'. 00240 if (space_dim == 0) { 00241 *this = y; 00242 return; 00243 } 00244 00245 if (!congruences_are_up_to_date()) 00246 update_congruences(); 00247 00248 con_sys.concatenate(y.congruences()); 00249 00250 space_dim += added_columns; 00251 00252 clear_congruences_minimized(); 00253 clear_generators_up_to_date(); 00254 00255 // Check that the system is OK, taking into account that the system 00256 // of congruences may now be empty. 00257 assert(OK()); 00258 }
void Parma_Polyhedra_Library::Grid::remove_space_dimensions | ( | const Variables_Set & | to_be_removed | ) |
Removes all the specified dimensions from the vector space.
to_be_removed | The set of Variable objects corresponding to the space dimensions to be removed. |
std::invalid_argument | Thrown if *this is dimension-incompatible with one of the Variable objects contained in to_be_removed . |
Definition at line 261 of file Grid_chdims.cc.
References clear_congruences_up_to_date(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), marked_empty(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::remove_space_dimensions(), set_empty(), set_zero_dim_univ(), space_dim, throw_dimension_incompatible(), and update_generators().
Referenced by fold_space_dimensions().
00261 { 00262 // The removal of no dimensions from any grid is a no-op. This case 00263 // also captures the only legal removal of dimensions from a grid in 00264 // a 0-dim space. 00265 if (to_be_removed.empty()) { 00266 assert(OK()); 00267 return; 00268 } 00269 00270 // Dimension-compatibility check. 00271 const dimension_type min_space_dim = to_be_removed.space_dimension(); 00272 if (space_dim < min_space_dim) 00273 throw_dimension_incompatible("remove_space_dimensions(vs)", min_space_dim); 00274 00275 const dimension_type new_space_dim = space_dim - to_be_removed.size(); 00276 00277 if (marked_empty() 00278 || (!generators_are_up_to_date() && !update_generators())) { 00279 // Update the space dimension. 00280 space_dim = new_space_dim; 00281 set_empty(); 00282 assert(OK()); 00283 return; 00284 } 00285 00286 // Removing _all_ dimensions from a non-empty grid obtains the 00287 // zero-dimensional universe grid. 00288 if (new_space_dim == 0) { 00289 set_zero_dim_univ(); 00290 return; 00291 } 00292 00293 gen_sys.remove_space_dimensions(to_be_removed); 00294 00295 clear_congruences_up_to_date(); 00296 clear_generators_minimized(); 00297 00298 // Update the space dimension. 00299 space_dim = new_space_dim; 00300 00301 assert(OK(true)); 00302 }
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
.
std::invalid_argument | Thrown if new_dimensions is greater than the space dimension of *this . |
Definition at line 305 of file Grid_chdims.cc.
References clear_congruences_up_to_date(), clear_generators_up_to_date(), con_sys, CON_VIRTUAL, congruences_are_minimized(), dim_kinds, Parma_Polyhedra_Library::Matrix::erase_to_end(), Parma_Polyhedra_Library::Grid_Generator_System::erase_to_end(), gen_sys, GEN_VIRTUAL, generators_are_minimized(), generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), is_empty(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), OK(), Parma_Polyhedra_Library::Congruence_System::remove_higher_space_dimensions(), Parma_Polyhedra_Library::Grid_Generator_System::remove_higher_space_dimensions(), set_empty(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::swap(), Parma_Polyhedra_Library::swap(), Parma_Polyhedra_Library::Congruence_System::swap(), throw_dimension_incompatible(), Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().
Referenced by generalized_affine_image(), and generalized_affine_preimage().
00305 { 00306 // Dimension-compatibility check. 00307 if (new_dimension > space_dim) 00308 throw_dimension_incompatible("remove_higher_space_dimensions(nd)", 00309 new_dimension); 00310 00311 // The removal of no dimensions from any grid is a no-op. 00312 // Note that this case also captures the only legal removal of 00313 // dimensions from a grid in a 0-dim space. 00314 if (new_dimension == space_dim) { 00315 assert(OK()); 00316 return; 00317 } 00318 00319 if (is_empty()) { 00320 // Removing dimensions from the empty grid just updates the space 00321 // dimension. 00322 space_dim = new_dimension; 00323 set_empty(); 00324 assert(OK()); 00325 return; 00326 } 00327 00328 if (new_dimension == 0) { 00329 // Removing all dimensions from a non-empty grid just returns the 00330 // zero-dimensional universe grid. 00331 set_zero_dim_univ(); 00332 return; 00333 } 00334 00335 // Favor the generators, as is done by is_empty(). 00336 if (generators_are_up_to_date()) { 00337 gen_sys.remove_higher_space_dimensions(new_dimension); 00338 if (generators_are_minimized()) { 00339 // Count the actual number of rows that are now redundant. 00340 dimension_type num_redundant = 0; 00341 const dimension_type num_old_gs = space_dim - new_dimension; 00342 for (dimension_type row = 0; row < num_old_gs; ++row) 00343 dim_kinds[row] == GEN_VIRTUAL || ++num_redundant; 00344 if (num_redundant > 0) { 00345 // Chop zero rows from end of system, to keep minimal form. 00346 gen_sys.erase_to_end(gen_sys.num_rows() - num_redundant); 00347 gen_sys.unset_pending_rows(); 00348 } 00349 dim_kinds.erase(dim_kinds.begin() + new_dimension + 1, dim_kinds.end()); 00350 // TODO: Consider if it is worth also preserving the congruences 00351 // if they are also in minimal form. 00352 } 00353 clear_congruences_up_to_date(); 00354 // Extend the zero dim false congruence system to the appropriate 00355 // dimension and then swap it with `con_sys'. 00356 Congruence_System cgs(Congruence::zero_dim_false()); 00357 // Extra 2 columns for inhomogeneous term and modulus. 00358 cgs.increase_space_dimension(new_dimension + 2); 00359 con_sys.swap(cgs); 00360 } 00361 else { 00362 assert(congruences_are_minimized()); 00363 con_sys.remove_higher_space_dimensions(new_dimension); 00364 // Count the actual number of rows that are now redundant. 00365 dimension_type num_redundant = 0; 00366 for (dimension_type row = space_dim; row > new_dimension; --row) 00367 dim_kinds[row] == CON_VIRTUAL || ++num_redundant; 00368 if (num_redundant > 0) { 00369 dimension_type rows = con_sys.num_rows(); 00370 // Shuffle the remaining rows upwards. 00371 for (dimension_type low = 0, high = num_redundant; 00372 high < rows; 00373 ++high, ++low) 00374 std::swap(con_sys[low], con_sys[high]); 00375 // Chop newly redundant rows from end of system, to keep minimal 00376 // form. 00377 con_sys.erase_to_end(rows - num_redundant); 00378 } 00379 dim_kinds.erase(dim_kinds.begin() + new_dimension + 1, dim_kinds.end()); 00380 clear_generators_up_to_date(); 00381 // Replace gen_sys with an empty system of the right dimension. 00382 // Extra 2 columns for inhomogeneous term and modulus. 00383 Grid_Generator_System gs(new_dimension + 2); 00384 gen_sys.swap(gs); 00385 } 00386 00387 // Update the space dimension. 00388 space_dim = new_dimension; 00389 00390 assert(OK(true)); 00391 }
void Parma_Polyhedra_Library::Grid::map_space_dimensions | ( | const Partial_Function & | pfunc | ) | [inline] |
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
.
pfunc | The partial function specifying the destiny of each space dimension. |
bool has_empty_codomain() const
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
max_in_codomain()
method is called at most once. bool maps(dimension_type i, dimension_type& j) const
i
. If j
and true
is returned. If false
is returned. This method is called at most
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 377 of file Grid.templates.hh.
References Parma_Polyhedra_Library::Grid_Generator_System::begin(), clear_congruences_minimized(), clear_generators_minimized(), Parma_Polyhedra_Library::Generator::CLOSURE_POINT, Parma_Polyhedra_Library::Grid_Generator::coefficient(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::EMPTY, Parma_Polyhedra_Library::Grid_Generator_System::end(), gen_sys, generators_are_up_to_date(), grid_generators(), Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Grid_Generator::LINE, marked_empty(), Parma_Polyhedra_Library::not_a_dimension(), OK(), Parma_Polyhedra_Library::Grid_Generator::PARAMETER, Parma_Polyhedra_Library::Grid_Generator_System::permute_columns(), Parma_Polyhedra_Library::Matrix::permute_columns(), Parma_Polyhedra_Library::Grid_Generator::POINT, set_empty(), Parma_Polyhedra_Library::Grid_Generator_System::set_sorted(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::swap(), throw_invalid_argument(), Parma_Polyhedra_Library::Grid_Generator::type(), and update_generators().
00377 { 00378 if (space_dim == 0) 00379 return; 00380 00381 if (pfunc.has_empty_codomain()) { 00382 // All dimensions vanish: the grid becomes zero_dimensional. 00383 if (marked_empty() 00384 || (!generators_are_up_to_date() && !update_generators())) { 00385 // Removing all dimensions from the empty grid. 00386 space_dim = 0; 00387 set_empty(); 00388 } 00389 else 00390 // Removing all dimensions from a non-empty grid. 00391 set_zero_dim_univ(); 00392 00393 assert(OK()); 00394 return; 00395 } 00396 00397 dimension_type new_space_dimension = pfunc.max_in_codomain() + 1; 00398 00399 if (new_space_dimension == space_dim) { 00400 // The partial function `pfunc' is indeed total and thus specifies 00401 // a permutation, that is, a renaming of the dimensions. For 00402 // maximum efficiency, we will simply permute the columns of the 00403 // constraint system and/or the generator system. 00404 00405 // We first compute suitable permutation cycles for the columns of 00406 // the `con_sys' and `gen_sys' matrices. We will represent them 00407 // with a linear array, using 0 as a terminator for each cycle 00408 // (notice that the columns with index 0 of `con_sys' and 00409 // `gen_sys' represent the inhomogeneous terms, and thus are 00410 // unaffected by the permutation of dimensions). 00411 // Cycles of length 1 will be omitted so that, in the worst case, 00412 // we will have `space_dim' elements organized in `space_dim/2' 00413 // cycles, which means we will have at most `space_dim/2' 00414 // terminators. 00415 std::vector<dimension_type> cycles; 00416 cycles.reserve(space_dim + space_dim/2); 00417 00418 // Used to mark elements as soon as they are inserted in a cycle. 00419 std::deque<bool> visited(space_dim); 00420 00421 for (dimension_type i = space_dim; i-- > 0; ) { 00422 if (!visited[i]) { 00423 dimension_type j = i; 00424 do { 00425 visited[j] = true; 00426 // The following initialization is only to make the compiler happy. 00427 dimension_type k = 0; 00428 if (!pfunc.maps(j, k)) 00429 throw_invalid_argument("map_space_dimensions(pfunc)", 00430 " pfunc is inconsistent"); 00431 if (k == j) 00432 // Cycle of length 1: skip it. 00433 goto skip; 00434 00435 cycles.push_back(j+1); 00436 // Go along the cycle. 00437 j = k; 00438 } while (!visited[j]); 00439 // End of cycle: mark it. 00440 cycles.push_back(0); 00441 skip: 00442 ; 00443 } 00444 } 00445 00446 // If `cycles' is empty then `pfunc' is the identity. 00447 if (cycles.empty()) 00448 return; 00449 00450 // Permute all that is up-to-date. 00451 if (congruences_are_up_to_date()) { 00452 con_sys.permute_columns(cycles); 00453 clear_congruences_minimized(); 00454 } 00455 00456 if (generators_are_up_to_date()) { 00457 gen_sys.permute_columns(cycles); 00458 clear_generators_minimized(); 00459 } 00460 00461 assert(OK()); 00462 return; 00463 } 00464 00465 // If control gets here, then `pfunc' is not a permutation and some 00466 // dimensions must be projected away. 00467 00468 const Grid_Generator_System& old_gensys = grid_generators(); 00469 00470 if (old_gensys.has_no_rows()) { 00471 // The grid is empty. 00472 Grid new_grid(new_space_dimension, EMPTY); 00473 std::swap(*this, new_grid); 00474 assert(OK()); 00475 return; 00476 } 00477 00478 // Make a local copy of the partial function. 00479 std::vector<dimension_type> pfunc_maps(space_dim, not_a_dimension()); 00480 for (dimension_type j = space_dim; j-- > 0; ) { 00481 dimension_type pfunc_j; 00482 if (pfunc.maps(j, pfunc_j)) 00483 pfunc_maps[j] = pfunc_j; 00484 } 00485 00486 Grid_Generator_System new_gensys; 00487 // Set sortedness, for the assertion met via gs::insert. 00488 new_gensys.set_sorted(false); 00489 // Get the divisor of the first point. 00490 Grid_Generator_System::const_iterator i; 00491 Grid_Generator_System::const_iterator old_gensys_end = old_gensys.end(); 00492 for (i = old_gensys.begin(); i != old_gensys_end; ++i) 00493 if (i->is_point()) 00494 break; 00495 assert(i != old_gensys_end); 00496 const Coefficient& system_divisor = i->divisor(); 00497 for (i = old_gensys.begin(); i != old_gensys_end; ++i) { 00498 const Grid_Generator& old_g = *i; 00499 Linear_Expression e(0 * Variable(new_space_dimension-1)); 00500 bool all_zeroes = true; 00501 for (dimension_type j = space_dim; j-- > 0; ) { 00502 if (old_g.coefficient(Variable(j)) != 0 00503 && pfunc_maps[j] != not_a_dimension()) { 00504 e += Variable(pfunc_maps[j]) * old_g.coefficient(Variable(j)); 00505 all_zeroes = false; 00506 } 00507 } 00508 switch (old_g.type()) { 00509 case Grid_Generator::LINE: 00510 if (!all_zeroes) 00511 new_gensys.insert(grid_line(e)); 00512 break; 00513 case Grid_Generator::PARAMETER: 00514 if (!all_zeroes) 00515 new_gensys.insert(parameter(e, system_divisor)); 00516 break; 00517 case Grid_Generator::POINT: 00518 new_gensys.insert(grid_point(e, old_g.divisor())); 00519 break; 00520 case Grid_Generator::CLOSURE_POINT: 00521 default: 00522 assert(0); 00523 } 00524 } 00525 00526 Grid new_grid(new_gensys); 00527 std::swap(*this, new_grid); 00528 00529 assert(OK(true)); 00530 }
void Parma_Polyhedra_Library::Grid::expand_space_dimension | ( | Variable | var, | |
dimension_type | m | |||
) |
Creates m
copies of the space dimension corresponding to var
.
var | The variable corresponding to the space dimension to be replicated; | |
m | The number of replicas to be created. |
std::invalid_argument | Thrown if var does not correspond to a dimension of the vector space. | |
std::length_error | Thrown if adding m new space dimensions would cause the vector space to exceed dimension max_space_dimension() . |
*this
has space dimension var
has space dimension m
new space dimensions Definition at line 394 of file Grid_chdims.cc.
References add_recycled_congruences(), add_space_dimensions_and_embed(), Parma_Polyhedra_Library::Congruence_System::begin(), Parma_Polyhedra_Library::Congruence::coefficient(), congruences(), Parma_Polyhedra_Library::Congruence_System::end(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Congruence::inhomogeneous_term(), Parma_Polyhedra_Library::Congruence_System::insert_verbatim(), max_space_dimension(), Parma_Polyhedra_Library::Congruence::modulus(), OK(), space_dim, space_dimension(), Parma_Polyhedra_Library::Variable::space_dimension(), throw_dimension_incompatible(), and throw_space_dimension_overflow().
00394 { 00395 // TODO: this implementation is _really_ an executable specification. 00396 00397 // `var' must be one of the dimensions of the vector space. 00398 if (var.space_dimension() > space_dim) 00399 throw_dimension_incompatible("expand_space_dimension(v, m)", "v", var); 00400 00401 // Adding 0 dimensions leaves the same grid. 00402 if (m == 0) 00403 return; 00404 00405 // The resulting space dimension must be at most the maximum. 00406 if (m > max_space_dimension() - space_dimension()) 00407 throw_space_dimension_overflow("expand_space_dimension(v, m)", 00408 "adding m new space dimensions exceeds " 00409 "the maximum allowed space dimension"); 00410 00411 // Save the number of dimensions before adding new ones. 00412 dimension_type old_dim = space_dim; 00413 00414 // Add the required new dimensions. 00415 add_space_dimensions_and_embed(m); 00416 00417 const dimension_type src_d = var.id(); 00418 const Congruence_System& cgs = congruences(); 00419 Congruence_System new_congruences; 00420 for (Congruence_System::const_iterator i = cgs.begin(), 00421 cgs_end = cgs.end(); i != cgs_end; ++i) { 00422 const Congruence& cg = *i; 00423 00424 // Only consider congruences that constrain `var'. 00425 if (cg.coefficient(var) == 0) 00426 continue; 00427 00428 // Each relevant congruence results in `m' new congruences. 00429 for (dimension_type dst_d = old_dim; dst_d < old_dim+m; ++dst_d) { 00430 Linear_Expression e; 00431 for (dimension_type j = old_dim; j-- > 0; ) 00432 e += 00433 cg.coefficient(Variable(j)) 00434 * (j == src_d ? Variable(dst_d) : Variable(j)); 00435 new_congruences.insert_verbatim((e + cg.inhomogeneous_term() %= 0) 00436 / cg.modulus()); 00437 } 00438 } 00439 add_recycled_congruences(new_congruences); 00440 assert(OK()); 00441 }
void Parma_Polyhedra_Library::Grid::fold_space_dimensions | ( | const Variables_Set & | to_be_folded, | |
Variable | var | |||
) |
Folds the space dimensions in to_be_folded
into var
.
to_be_folded | The set of Variable objects corresponding to the space dimensions to be folded; | |
var | The variable corresponding to the space dimension that is the destination of the folding operation. |
std::invalid_argument | Thrown if *this is dimension-incompatible with var or with one of the Variable objects contained in to_be_folded . Also thrown if var is contained in to_be_folded . |
*this
has space dimension var
has space dimension to_be_folded
is a set of variables whose maximum space dimension is also less than or equal to var
is not a member of to_be_folded
, then the space dimensions corresponding to variables in to_be_folded
are folded into the Definition at line 444 of file Grid_chdims.cc.
References affine_image(), grid_generators(), Parma_Polyhedra_Library::Variable::id(), marked_empty(), OK(), remove_space_dimensions(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), throw_dimension_incompatible(), throw_invalid_argument(), and upper_bound_assign().
00445 { 00446 // TODO: this implementation is _really_ an executable specification. 00447 00448 // `var' should be one of the dimensions of the grid. 00449 if (var.space_dimension() > space_dim) 00450 throw_dimension_incompatible("fold_space_dimensions(tbf, v)", "v", var); 00451 00452 // Folding only has effect if dimensions are given. 00453 if (to_be_folded.empty()) 00454 return; 00455 00456 // All variables in `to_be_folded' must be dimensions of the grid. 00457 if (to_be_folded.space_dimension() > space_dim) 00458 throw_dimension_incompatible("fold_space_dimensions(tbf, v)", 00459 "tbf.space_dimension()", 00460 to_be_folded.space_dimension()); 00461 00462 // Moreover, `var.id()' must not occur in `to_be_folded'. 00463 if (to_be_folded.find(var.id()) != to_be_folded.end()) 00464 throw_invalid_argument("fold_space_dimensions(tbf, v)", 00465 "v should not occur in tbf"); 00466 // All of the affine images we are going to compute are not invertible, 00467 // hence we will need to compute the grid generators of the polyhedron. 00468 // Since we keep taking copies, make sure that a single conversion 00469 // from congruences to grid generators is computed. 00470 (void) grid_generators(); 00471 // Having grid generators, we now know if the grid is empty: 00472 // in that case, folding is equivalent to just removing space dimensions. 00473 if (!marked_empty()) { 00474 for (Variables_Set::const_iterator i = to_be_folded.begin(), 00475 tbf_end = to_be_folded.end(); i != tbf_end; ++i) { 00476 Grid copy = *this; 00477 copy.affine_image(var, Linear_Expression(Variable(*i))); 00478 upper_bound_assign(copy); 00479 } 00480 } 00481 remove_space_dimensions(to_be_folded); 00482 assert(OK()); 00483 }
void Parma_Polyhedra_Library::Grid::swap | ( | Grid & | y | ) | [inline] |
Swaps *this
with grid y
. (*this
and y
can be dimension-incompatible.).
Definition at line 244 of file Grid.inlines.hh.
References con_sys, dim_kinds, gen_sys, space_dim, status, and Parma_Polyhedra_Library::swap().
Referenced by add_space_dimensions_and_embed(), add_space_dimensions_and_project(), construct(), set_empty(), and swap().
00244 { 00245 std::swap(con_sys, y.con_sys); 00246 std::swap(gen_sys, y.gen_sys); 00247 std::swap(status, y.status); 00248 std::swap(space_dim, y.space_dim); 00249 std::swap(dim_kinds, y.dim_kinds); 00250 }
void Parma_Polyhedra_Library::Grid::ascii_dump | ( | ) | const |
void Parma_Polyhedra_Library::Grid::ascii_dump | ( | std::ostream & | s | ) | const |
Writes to s
an ASCII representation of *this
.
Definition at line 2468 of file Grid_public.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::ascii_dump(), Parma_Polyhedra_Library::Congruence_System::ascii_dump(), Parma_Polyhedra_Library::Grid::Status::ascii_dump(), con_sys, congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, gen_sys, generators_are_minimized(), generators_are_up_to_date(), space_dim, and status.
02468 { 02469 using std::endl; 02470 02471 s << "space_dim " 02472 << space_dim 02473 << endl; 02474 status.ascii_dump(s); 02475 s << "con_sys (" 02476 << (congruences_are_up_to_date() ? "" : "not_") 02477 << "up-to-date)" 02478 << endl; 02479 con_sys.ascii_dump(s); 02480 s << "gen_sys (" 02481 << (generators_are_up_to_date() ? "" : "not_") 02482 << "up-to-date)" 02483 << endl; 02484 gen_sys.ascii_dump(s); 02485 s << "dimension_kinds"; 02486 if ((generators_are_up_to_date() && generators_are_minimized()) 02487 || (congruences_are_up_to_date() && congruences_are_minimized())) 02488 for (Dimension_Kinds::const_iterator i = dim_kinds.begin(); 02489 i != dim_kinds.end(); 02490 ++i) 02491 s << " " << *i; 02492 s << endl; 02493 }
void Parma_Polyhedra_Library::Grid::print | ( | ) | const |
Prints *this
to std::cerr
using operator<<
.
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 2498 of file Grid_public.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::ascii_load(), Parma_Polyhedra_Library::Congruence_System::ascii_load(), Parma_Polyhedra_Library::Grid::Status::ascii_load(), con_sys, congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, gen_sys, GEN_VIRTUAL, generators_are_minimized(), generators_are_up_to_date(), LINE, marked_empty(), OK(), PARAMETER, set_congruences_up_to_date(), set_generators_up_to_date(), space_dim, and status.
02498 { 02499 std::string str; 02500 02501 if (!(s >> str) || str != "space_dim") 02502 return false; 02503 02504 if (!(s >> space_dim)) 02505 return false; 02506 02507 if (!status.ascii_load(s)) 02508 return false; 02509 02510 if (!(s >> str) || str != "con_sys") 02511 return false; 02512 02513 if (s >> str) { 02514 if (str == "(up-to-date)") 02515 set_congruences_up_to_date(); 02516 else if (str != "(not_up-to-date)") 02517 return false; 02518 } 02519 else 02520 return false; 02521 02522 if (!con_sys.ascii_load(s)) 02523 return false; 02524 02525 if (!(s >> str) || str != "gen_sys") 02526 return false; 02527 02528 if (s >> str) { 02529 if (str == "(up-to-date)") 02530 set_generators_up_to_date(); 02531 else if (str != "(not_up-to-date)") 02532 return false; 02533 } 02534 else 02535 return false; 02536 02537 if (!gen_sys.ascii_load(s)) 02538 return false; 02539 02540 if (!(s >> str) || str != "dimension_kinds") 02541 return false; 02542 02543 if (!marked_empty() 02544 && ((generators_are_up_to_date() && generators_are_minimized()) 02545 || (congruences_are_up_to_date() && congruences_are_minimized()))) { 02546 dim_kinds.resize(space_dim + 1); 02547 for (Dimension_Kinds::size_type dim = 0; dim <= space_dim; ++dim) { 02548 short unsigned int dim_kind; 02549 if (!(s >> dim_kind)) 02550 return false; 02551 switch(dim_kind) { 02552 case 0: dim_kinds[dim] = PARAMETER; break; 02553 case 1: dim_kinds[dim] = LINE; break; 02554 case 2: dim_kinds[dim] = GEN_VIRTUAL; break; 02555 default: return false; 02556 } 02557 } 02558 } 02559 02560 // Check invariants. 02561 assert(OK()); 02562 return true; 02563 }
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 224 of file Grid.inlines.hh.
References external_memory_in_bytes().
00224 { 00225 return sizeof(*this) + external_memory_in_bytes(); 00226 }
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 2566 of file Grid_public.cc.
References con_sys, Parma_Polyhedra_Library::Grid_Generator_System::external_memory_in_bytes(), Parma_Polyhedra_Library::Congruence_System::external_memory_in_bytes(), and gen_sys.
Referenced by total_memory_in_bytes().
02566 { 02567 return 02568 con_sys.external_memory_in_bytes() 02569 + gen_sys.external_memory_in_bytes(); 02570 }
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 229 of file Grid.inlines.hh.
References space_dimension().
00229 { 00230 return space_dimension() & 0x7fffffff; 00231 }
void Parma_Polyhedra_Library::Grid::construct | ( | dimension_type | num_dimensions, | |
Degenerate_Element | kind | |||
) | [private] |
Builds a grid universe or empty grid.
num_dimensions | The number of dimensions of the vector space enclosing the grid; | |
kind | specifies whether the universe or the empty grid has to be built. |
Definition at line 51 of file Grid_nonpublic.cc.
References con_sys, CON_VIRTUAL, dim_kinds, Parma_Polyhedra_Library::EMPTY, gen_sys, Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), OK(), PROPER_CONGRUENCE, set_congruences_minimized(), Parma_Polyhedra_Library::Grid::Status::set_empty(), set_generators_minimized(), set_zero_dim_univ(), space_dim, status, Parma_Polyhedra_Library::Congruence_System::swap(), swap(), Parma_Polyhedra_Library::Congruence::zero_dim_false(), and Parma_Polyhedra_Library::Congruence::zero_dim_integrality().
Referenced by Grid().
00052 { 00053 space_dim = num_dimensions; 00054 00055 if (kind == EMPTY) { 00056 // Set emptiness directly instead of with set_empty, as gen_sys is 00057 // already correctly initialized. 00058 00059 status.set_empty(); 00060 00061 // Extend the zero dim false congruence system to the appropriate 00062 // dimension and then store it in `con_sys'. 00063 Congruence_System cgs(Congruence::zero_dim_false()); 00064 cgs.increase_space_dimension(space_dim); 00065 const_cast<Congruence_System&>(con_sys).swap(cgs); 00066 00067 assert(OK()); 00068 return; 00069 } 00070 00071 if (num_dimensions > 0) { 00072 con_sys.increase_space_dimension(num_dimensions); 00073 00074 // Initialize both systems to universe representations. 00075 00076 set_congruences_minimized(); 00077 set_generators_minimized(); 00078 dim_kinds.resize(num_dimensions + 1); 00079 00080 // Extend the zero dim integrality congruence system to the 00081 // appropriate dimension and then store it in `con_sys'. 00082 Congruence_System cgs(Congruence::zero_dim_integrality()); 00083 cgs.increase_space_dimension(space_dim); 00084 cgs[0][0] = 1; // Recover minimal form after cgs(zdi) normalization. 00085 con_sys.swap(cgs); 00086 00087 dim_kinds[0] = PROPER_CONGRUENCE /* a.k.a. PARAMETER */; 00088 00089 // Trivially true point. 00090 gen_sys.insert(grid_point(0*(Variable(0)))); 00091 00092 // A line for each dimension. 00093 dimension_type dim = 0; 00094 while (dim < num_dimensions) { 00095 gen_sys.insert(grid_line(Variable(dim))); 00096 dim_kinds[++dim] = CON_VIRTUAL /* a.k.a. LINE */; 00097 } 00098 } 00099 else 00100 set_zero_dim_univ(); 00101 }
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.
cgs | The system of congruences defining the grid. Its data-structures may be recycled to build the grid. |
Definition at line 104 of file Grid_nonpublic.cc.
References con_sys, gen_sys, Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Congruence_System::insert(), max_space_dimension(), Parma_Polyhedra_Library::Congruence_System::normalize_moduli(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Matrix::num_rows(), OK(), set_congruences_up_to_date(), Parma_Polyhedra_Library::Grid::Status::set_empty(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), status, Parma_Polyhedra_Library::swap(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().
00104 { 00105 // Protecting against space dimension overflow is up to the caller. 00106 assert(cgs.space_dimension() <= max_space_dimension()); 00107 // Preparing con_sys and gen_sys is up to the caller. 00108 assert(cgs.space_dimension() == con_sys.space_dimension()); 00109 assert(cgs.space_dimension() == gen_sys.space_dimension()); 00110 assert(con_sys.has_no_rows()); 00111 assert(gen_sys.has_no_rows()); 00112 00113 // Set the space dimension. 00114 space_dim = cgs.space_dimension(); 00115 00116 if (space_dim > 0) { 00117 // Stealing the rows from `cgs'. 00118 std::swap(con_sys, cgs); 00119 con_sys.normalize_moduli(); 00120 set_congruences_up_to_date(); 00121 } 00122 else { 00123 // Here `space_dim == 0'. 00124 if (cgs.num_columns() > 1) 00125 // See if an inconsistent congruence has been passed. 00126 for (dimension_type i = cgs.num_rows(); i-- > 0; ) 00127 if (cgs[i].is_inconsistent()) { 00128 // Inconsistent congruence found: the grid is empty. 00129 status.set_empty(); 00130 // Insert the zero dim false congruence system into `con_sys'. 00131 // `gen_sys' is already in empty form. 00132 con_sys.insert(Congruence::zero_dim_false()); 00133 assert(OK()); 00134 return; 00135 } 00136 set_zero_dim_univ(); 00137 } 00138 assert(OK()); 00139 }
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.
ggs | The system of grid generators defining the grid. Its data-structures may be recycled to build the grid. |
Definition at line 142 of file Grid_nonpublic.cc.
References con_sys, gen_sys, Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator_System::has_points(), Parma_Polyhedra_Library::Congruence_System::insert(), max_space_dimension(), normalize_divisors(), OK(), Parma_Polyhedra_Library::Grid::Status::set_empty(), set_generators_up_to_date(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), status, Parma_Polyhedra_Library::swap(), throw_invalid_generators(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().
00142 { 00143 // Protecting against space dimension overflow is up to the caller. 00144 assert(ggs.space_dimension() <= max_space_dimension()); 00145 // Preparing con_sys and gen_sys is up to the caller. 00146 assert(ggs.space_dimension() == con_sys.space_dimension()); 00147 assert(ggs.space_dimension() == gen_sys.space_dimension()); 00148 assert(con_sys.has_no_rows()); 00149 assert(gen_sys.has_no_rows()); 00150 00151 // Set the space dimension. 00152 space_dim = ggs.space_dimension(); 00153 00154 // An empty set of generators defines the empty grid. 00155 if (ggs.has_no_rows()) { 00156 status.set_empty(); 00157 // Insert the zero dim false congruence system into `con_sys'. 00158 // `gen_sys' is already in empty form. 00159 con_sys.insert(Congruence::zero_dim_false()); 00160 return; 00161 } 00162 00163 // Non-empty valid generator systems have a supporting point, at least. 00164 if (!ggs.has_points()) 00165 throw_invalid_generators("Grid(ggs)", "ggs"); 00166 00167 if (space_dim == 0) 00168 set_zero_dim_univ(); 00169 else { 00170 // Steal the rows from `ggs'. 00171 std::swap(gen_sys, ggs); 00172 normalize_divisors(gen_sys); 00173 // Generators are now up-to-date. 00174 set_generators_up_to_date(); 00175 } 00176 00177 assert(OK()); 00178 }
bool Parma_Polyhedra_Library::Grid::marked_empty | ( | ) | const [inline, private] |
Returns true
if the grid is known to be empty.
The return value false
does not necessarily implies that *this
is non-empty.
Definition at line 34 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_empty().
Referenced by add_congruence(), add_congruence_no_check(), add_congruences(), add_constraint(), add_constraint_no_check(), add_constraints(), add_grid_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_load(), bounded_affine_image(), bounded_affine_preimage(), bounds(), Parma_Polyhedra_Library::Box< ITV >::Box(), concatenate_assign(), congruence_widening_assign(), congruences(), constrains(), contains(), contains_integer_point(), difference_assign(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), generator_widening_assign(), get_covering_box(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), grid_generators(), intersection_assign(), is_bounded(), is_discrete(), is_empty(), is_included_in(), is_universe(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), map_space_dimensions(), max_min(), minimize(), minimized_grid_generators(), OK(), operator=(), quick_equivalence_test(), refine_no_check(), refine_with_constraint(), refine_with_constraints(), relation_with(), remove_space_dimensions(), select_wider_congruences(), select_wider_generators(), time_elapse_assign(), unconstrain(), update_congruences(), update_generators(), upper_bound_assign(), and upper_bound_assign_if_exact().
00034 { 00035 return status.test_empty(); 00036 }
bool Parma_Polyhedra_Library::Grid::congruences_are_up_to_date | ( | ) | const [inline, private] |
Returns true
if the system of congruences is up-to-date.
Definition at line 39 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_c_up_to_date().
Referenced by add_congruence_no_check(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_dimension(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), concatenate_assign(), congruence_widening_assign(), congruences(), constrains(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), intersection_assign(), is_included_in(), is_universe(), map_space_dimensions(), minimize(), minimized_congruences(), OK(), operator=(), relation_with(), update_generators(), and widening_assign().
00039 { 00040 return status.test_c_up_to_date(); 00041 }
bool Parma_Polyhedra_Library::Grid::generators_are_up_to_date | ( | ) | const [inline, private] |
Returns true
if the system of generators is up-to-date.
Definition at line 44 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_g_up_to_date().
Referenced by add_grid_generator(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_dimension(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), bounds(), Parma_Polyhedra_Library::Box< ITV >::Box(), constrains(), generalized_affine_image(), generalized_affine_preimage(), generator_widening_assign(), get_covering_box(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), grid_generators(), is_bounded(), is_discrete(), is_empty(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), map_space_dimensions(), minimize(), minimized_grid_generators(), OK(), operator=(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), time_elapse_assign(), unconstrain(), upper_bound_assign(), upper_bound_assign_if_exact(), and widening_assign().
00044 { 00045 return status.test_g_up_to_date(); 00046 }
bool Parma_Polyhedra_Library::Grid::congruences_are_minimized | ( | ) | const [inline, private] |
Returns true
if the system of congruences is minimized.
Definition at line 49 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_c_minimized().
Referenced by add_space_dimensions(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_dimension(), ascii_dump(), ascii_load(), congruence_widening_assign(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_empty(), is_included_in(), is_universe(), minimize(), minimized_congruences(), OK(), quick_equivalence_test(), remove_higher_space_dimensions(), select_wider_congruences(), and update_generators().
00049 { 00050 return status.test_c_minimized(); 00051 }
bool Parma_Polyhedra_Library::Grid::generators_are_minimized | ( | ) | const [inline, private] |
Returns true
if the system of generators is minimized.
Definition at line 54 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_g_minimized().
Referenced by add_space_dimensions(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_dimension(), ascii_dump(), ascii_load(), constrains(), generator_widening_assign(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), max_min(), minimize(), minimized_grid_generators(), OK(), quick_equivalence_test(), remove_higher_space_dimensions(), select_wider_generators(), and update_congruences().
00054 { 00055 return status.test_g_minimized(); 00056 }
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 348 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::clear(), Parma_Polyhedra_Library::Congruence_System::clear(), con_sys, gen_sys, Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Grid::Status::set_zero_dim_univ(), space_dim, and status.
Referenced by add_grid_generator(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), construct(), Grid(), map_space_dimensions(), operator=(), remove_higher_space_dimensions(), and remove_space_dimensions().
00348 { 00349 status.set_zero_dim_univ(); 00350 space_dim = 0; 00351 con_sys.clear(); 00352 gen_sys.clear(); 00353 gen_sys.insert(grid_point()); 00354 }
void Parma_Polyhedra_Library::Grid::set_empty | ( | ) | [private] |
Sets status
to express that the grid is empty, clearing all corresponding matrices.
Definition at line 357 of file Grid_nonpublic.cc.
References con_sys, gen_sys, Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), Parma_Polyhedra_Library::Grid::Status::set_empty(), space_dim, status, swap(), Parma_Polyhedra_Library::Grid_Generator_System::swap(), and Parma_Polyhedra_Library::Congruence::zero_dim_false().
Referenced by add_congruence_no_check(), add_constraint_no_check(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), concatenate_assign(), congruence_widening_assign(), difference_assign(), Grid(), intersection_assign(), is_empty(), map_space_dimensions(), minimized_congruences(), operator=(), refine_no_check(), remove_higher_space_dimensions(), remove_space_dimensions(), time_elapse_assign(), and update_generators().
00357 { 00358 status.set_empty(); 00359 00360 // Replace gen_sys with an empty system of the right dimension. 00361 Grid_Generator_System gs(space_dim); 00362 gen_sys.swap(gs); 00363 00364 // Extend the zero dim false congruence system to the appropriate 00365 // dimension and then swap it with `con_sys'. 00366 Congruence_System cgs(Congruence::zero_dim_false()); 00367 cgs.increase_space_dimension(space_dim); 00368 const_cast<Congruence_System&>(con_sys).swap(cgs); 00369 }
void Parma_Polyhedra_Library::Grid::set_congruences_up_to_date | ( | ) | [inline, private] |
Sets status
to express that congruences are up-to-date.
Definition at line 64 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::set_c_up_to_date(), and status.
Referenced by add_congruence_no_check(), ascii_load(), construct(), Grid(), and set_congruences_minimized().
00064 { 00065 status.set_c_up_to_date(); 00066 }
void Parma_Polyhedra_Library::Grid::set_generators_up_to_date | ( | ) | [inline, private] |
Sets status
to express that generators are up-to-date.
Definition at line 59 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::set_g_up_to_date(), and status.
Referenced by add_grid_generator(), add_recycled_grid_generators(), ascii_load(), construct(), Grid(), and set_generators_minimized().
00059 { 00060 status.set_g_up_to_date(); 00061 }
void Parma_Polyhedra_Library::Grid::set_congruences_minimized | ( | ) | [inline, private] |
Sets status
to express that congruences are minimized.
Definition at line 69 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().
00069 { 00070 set_congruences_up_to_date(); 00071 status.set_c_minimized(); 00072 }
void Parma_Polyhedra_Library::Grid::set_generators_minimized | ( | ) | [inline, private] |
Sets status
to express that generators are minimized.
Definition at line 75 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().
00075 { 00076 set_generators_up_to_date(); 00077 status.set_g_minimized(); 00078 }
void Parma_Polyhedra_Library::Grid::clear_empty | ( | ) | [inline, private] |
Clears the status
flag indicating that the grid is empty.
Definition at line 81 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::reset_empty(), and status.
Referenced by add_grid_generator(), add_recycled_grid_generators(), and add_recycled_grid_generators_and_minimize().
00081 { 00082 status.reset_empty(); 00083 }
void Parma_Polyhedra_Library::Grid::clear_congruences_up_to_date | ( | ) | [inline, private] |
Sets status
to express that congruences are out of date.
Definition at line 96 of file Grid.inlines.hh.
References clear_congruences_minimized(), Parma_Polyhedra_Library::Grid::Status::reset_c_up_to_date(), and status.
Referenced by add_grid_generator(), add_recycled_grid_generators(), affine_image(), generalized_affine_image(), generalized_affine_preimage(), remove_higher_space_dimensions(), remove_space_dimensions(), time_elapse_assign(), unconstrain(), and upper_bound_assign().
00096 { 00097 clear_congruences_minimized(); 00098 status.reset_c_up_to_date(); 00099 // Can get rid of con_sys here. 00100 }
void Parma_Polyhedra_Library::Grid::clear_generators_up_to_date | ( | ) | [inline, private] |
Sets status
to express that generators are out of date.
Definition at line 103 of file Grid.inlines.hh.
References clear_generators_minimized(), Parma_Polyhedra_Library::Grid::Status::reset_g_up_to_date(), and status.
Referenced by add_congruence_no_check(), add_recycled_congruences(), affine_preimage(), concatenate_assign(), intersection_assign(), OK(), and remove_higher_space_dimensions().
00103 { 00104 clear_generators_minimized(); 00105 status.reset_g_up_to_date(); 00106 // Can get rid of gen_sys here. 00107 }
void Parma_Polyhedra_Library::Grid::clear_congruences_minimized | ( | ) | [inline, private] |
Sets status
to express that congruences are no longer minimized.
Definition at line 86 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::reset_c_minimized(), and status.
Referenced by add_congruence_no_check(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), affine_image(), affine_preimage(), clear_congruences_up_to_date(), concatenate_assign(), intersection_assign(), and map_space_dimensions().
00086 { 00087 status.reset_c_minimized(); 00088 }
void Parma_Polyhedra_Library::Grid::clear_generators_minimized | ( | ) | [inline, private] |
Sets status
to express that generators are no longer minimized.
Definition at line 91 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::reset_g_minimized(), and status.
Referenced by add_grid_generator(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), affine_image(), affine_preimage(), clear_generators_up_to_date(), generalized_affine_image(), generalized_affine_preimage(), map_space_dimensions(), remove_space_dimensions(), time_elapse_assign(), unconstrain(), and upper_bound_assign().
00091 { 00092 status.reset_g_minimized(); 00093 }
void Parma_Polyhedra_Library::Grid::update_congruences | ( | ) | const [private] |
Updates and minimizes the congruences from the generators.
Definition at line 372 of file Grid_nonpublic.cc.
References gen_sys, generators_are_minimized(), Parma_Polyhedra_Library::Matrix::has_no_rows(), marked_empty(), space_dim, and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().
Referenced by add_congruence_no_check(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_grid_generators_and_minimize(), concatenate_assign(), congruence_widening_assign(), congruences(), constrains(), intersection_assign(), is_included_in(), is_universe(), minimize(), and relation_with().
00372 { 00373 // The caller must ensure that the generators are up to date. 00374 assert(space_dim > 0); 00375 assert(!marked_empty()); 00376 assert(!gen_sys.has_no_rows()); 00377 assert(gen_sys.space_dimension() > 0); 00378 00379 Grid& gr = const_cast<Grid&>(*this); 00380 00381 if (!generators_are_minimized()) 00382 gr.simplify(gr.gen_sys, gr.dim_kinds); 00383 00384 // `gen_sys' contained rows before being reduced, so it should 00385 // contain at least a single point afterward. 00386 assert(!gen_sys.has_no_rows()); 00387 00388 // Populate `con_sys' with congruences characterizing the grid 00389 // described by `gen_sys'. 00390 gr.conversion(gr.gen_sys, gr.con_sys, gr.dim_kinds); 00391 00392 // Both systems are minimized. 00393 gr.set_congruences_minimized(); 00394 gr.set_generators_minimized(); 00395 }
bool Parma_Polyhedra_Library::Grid::update_generators | ( | ) | const [private] |
Updates and minimizes the generators from the congruences.
false
if and only if *this
turns out to be an empty grid.Definition at line 398 of file Grid_nonpublic.cc.
References con_sys, congruences_are_minimized(), congruences_are_up_to_date(), conversion(), dim_kinds, gen_sys, marked_empty(), set_congruences_minimized(), set_empty(), set_generators_minimized(), simplify(), and space_dim.
Referenced by add_grid_generator(), add_recycled_congruences_and_minimize(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), bounds(), Parma_Polyhedra_Library::Box< ITV >::Box(), generalized_affine_image(), generalized_affine_preimage(), generator_widening_assign(), get_covering_box(), grid_generators(), is_bounded(), is_discrete(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), map_space_dimensions(), minimize(), minimized_grid_generators(), OK(), relation_with(), remove_space_dimensions(), time_elapse_assign(), unconstrain(), and upper_bound_assign().
00398 { 00399 assert(space_dim > 0); 00400 assert(!marked_empty()); 00401 assert(congruences_are_up_to_date()); 00402 00403 Grid& x = const_cast<Grid&>(*this); 00404 00405 if (!congruences_are_minimized()) 00406 // Either the system of congruences is consistent, or the grid is 00407 // empty. 00408 if (simplify(x.con_sys, x.dim_kinds)) { 00409 x.set_empty(); 00410 return false; 00411 } 00412 00413 // Populate gen_sys with generators characterizing the grid 00414 // described by con_sys. 00415 conversion(x.con_sys, x.gen_sys, x.dim_kinds); 00416 00417 // Both systems are minimized. 00418 x.set_congruences_minimized(); 00419 x.set_generators_minimized(); 00420 return true; 00421 }
bool Parma_Polyhedra_Library::Grid::minimize | ( | ) | const [private] |
Minimizes both the congruences and the generators.
false
if and only if *this
turns out to be an empty grid.Definition at line 424 of file Grid_nonpublic.cc.
References con_sys, congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, empty, gen_sys, generators_are_minimized(), generators_are_up_to_date(), marked_empty(), OK(), set_congruences_minimized(), set_generators_minimized(), simplify(), space_dim, update_congruences(), and update_generators().
Referenced by add_constraint_and_minimize(), add_constraints_and_minimize(), add_recycled_congruences_and_minimize(), add_recycled_constraints_and_minimize(), add_recycled_grid_generators_and_minimize(), affine_image(), affine_preimage(), constrains(), generalized_affine_image(), generalized_affine_preimage(), intersection_assign_and_minimize(), and upper_bound_assign_and_minimize().
00424 { 00425 // 0-dimension and empty grids are already minimized. 00426 if (marked_empty()) 00427 return false; 00428 if (space_dim == 0) 00429 return true; 00430 00431 // Are both systems already minimized? 00432 if (congruences_are_minimized() && generators_are_minimized()) 00433 return true; 00434 00435 // Invoke update_generators, update_congruences or simplify, 00436 // depending on the state of the systems. 00437 if (congruences_are_up_to_date()) { 00438 if (generators_are_up_to_date()) { 00439 Grid& gr = const_cast<Grid&>(*this); 00440 // Only one of the systems can be minimized here. 00441 if (congruences_are_minimized()) { 00442 // Minimize the generator system. 00443 gr.simplify(gr.gen_sys, gr.dim_kinds); 00444 gr.set_generators_minimized(); 00445 } 00446 else { 00447 #ifndef NDEBUG 00448 // Both systems are up to date, and the empty case is handled 00449 // above, so the grid should contain points. 00450 bool empty = simplify(gr.con_sys, gr.dim_kinds); 00451 assert(!empty); 00452 #else 00453 simplify(gr.con_sys, gr.dim_kinds); 00454 #endif 00455 gr.set_congruences_minimized(); 00456 if (!generators_are_minimized()) { 00457 // Minimize the generator system. 00458 gr.simplify(gr.gen_sys, gr.dim_kinds); 00459 gr.set_generators_minimized(); 00460 } 00461 } 00462 } 00463 else { 00464 // Updating the generators may reveal that `*this' is empty. 00465 const bool ret = update_generators(); 00466 assert(OK()); 00467 return ret; 00468 } 00469 } 00470 else { 00471 assert(generators_are_up_to_date()); 00472 update_congruences(); 00473 } 00474 assert(OK()); 00475 return true; 00476 }
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 181 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::Matrix::num_rows(), space_dim, TVB_DONT_KNOW, TVB_FALSE, and TVB_TRUE.
Referenced by contains().
00181 { 00182 // Private method: the caller must ensure the following. 00183 assert(space_dim == y.space_dim); 00184 assert(!marked_empty() && !y.marked_empty() && space_dim > 0); 00185 00186 const Grid& x = *this; 00187 00188 bool css_normalized = false; 00189 00190 if (x.congruences_are_minimized() && y.congruences_are_minimized()) { 00191 // Equivalent minimized congruence systems have: 00192 // - the same number of congruences; ... 00193 if (x.con_sys.num_rows() != y.con_sys.num_rows()) 00194 return Grid::TVB_FALSE; 00195 // - the same number of equalities; ... 00196 dimension_type x_num_equalities = x.con_sys.num_equalities(); 00197 if (x_num_equalities != y.con_sys.num_equalities()) 00198 return Grid::TVB_FALSE; 00199 // - and if there are no equalities, the same congruences. 00200 // Delay this test: try cheaper tests on generators first. 00201 css_normalized = (x_num_equalities == 0); 00202 } 00203 00204 if (x.generators_are_minimized() && y.generators_are_minimized()) { 00205 // Equivalent minimized generator systems have: 00206 // - the same number of generators; ... 00207 if (x.gen_sys.num_rows() != y.gen_sys.num_rows()) 00208 return Grid::TVB_FALSE; 00209 // - the same number of lines; ... 00210 const dimension_type x_num_lines = x.gen_sys.num_lines(); 00211 if (x_num_lines != y.gen_sys.num_lines()) 00212 return Grid::TVB_FALSE; 00213 // - and if there are no lines, the same generators. 00214 if (x_num_lines == 0) { 00215 // Check for syntactic identity. 00216 if (x.gen_sys == y.gen_sys) 00217 return Grid::TVB_TRUE; 00218 else 00219 return Grid::TVB_FALSE; 00220 } 00221 } 00222 00223 // TODO: Consider minimizing the systems and re-performing these 00224 // checks. 00225 00226 if (css_normalized) { 00227 if (x.con_sys == y.con_sys) 00228 return Grid::TVB_TRUE; 00229 else 00230 return Grid::TVB_FALSE; 00231 } 00232 00233 return Grid::TVB_DONT_KNOW; 00234 }
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 237 of file Grid_nonpublic.cc.
References con_sys, congruences_are_minimized(), congruences_are_up_to_date(), marked_empty(), minimize(), OK(), Parma_Polyhedra_Library::Congruence_System::satisfies_all_congruences(), space_dim, and update_congruences().
Referenced by contains(), and upper_bound_assign_if_exact().
00237 { 00238 // Private method: the caller must ensure the following. 00239 assert(space_dim == y.space_dim); 00240 assert(!marked_empty() && !y.marked_empty() && space_dim > 0); 00241 00242 const Grid& x = *this; 00243 00244 #if BE_LAZY 00245 if (!x.generators_are_up_to_date() && !x.update_generators()) 00246 // Updating found `x' empty. 00247 return true; 00248 if (!y.congruences_are_up_to_date()) 00249 y.update_congruences(); 00250 #else 00251 if (!x.generators_are_minimized() && !x.minimize()) 00252 // Minimizing found `x' empty. 00253 return true; 00254 if (!y.congruences_are_minimized()) 00255 y.minimize(); 00256 #endif 00257 00258 assert(x.OK()); 00259 assert(y.OK()); 00260 00261 const Grid_Generator_System& gs = x.gen_sys; 00262 const Congruence_System& cgs = y.con_sys; 00263 00264 dimension_type num_rows = gs.num_rows(); 00265 for (dimension_type i = num_rows; i-- > 0; ) 00266 if (!cgs.satisfies_all_congruences(gs[i])) 00267 return false; 00268 00269 // Inclusion holds. 00270 return true; 00271 }
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
.
expr | The linear expression to test; | |
method_call | The call description of the public parent method, for example "bounded_from_above(e)". Passed to throw_dimension_incompatible, as the first argument. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
Definition at line 274 of file Grid_nonpublic.cc.
References gen_sys, generators_are_up_to_date(), Parma_Polyhedra_Library::Scalar_Products::homogeneous_sign(), Parma_Polyhedra_Library::Grid_Generator::is_line_or_parameter(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), space_dim, Parma_Polyhedra_Library::Linear_Expression::space_dimension(), throw_dimension_incompatible(), and update_generators().
Referenced by bounds_from_above(), bounds_from_below(), and max_min().
00275 { 00276 // The dimension of `expr' must be at most the dimension of *this. 00277 if (space_dim < expr.space_dimension()) 00278 throw_dimension_incompatible(method_call, "e", expr); 00279 00280 // A zero-dimensional or empty grid bounds everything. 00281 if (space_dim == 0 00282 || marked_empty() 00283 || (!generators_are_up_to_date() && !update_generators())) 00284 return true; 00285 00286 // The generators are up to date. 00287 for (dimension_type i = gen_sys.num_rows(); i-- > 0; ) { 00288 const Grid_Generator& g = gen_sys[i]; 00289 // Only lines and parameters in `*this' can cause `expr' to be 00290 // unbounded. 00291 if (g.is_line_or_parameter()) { 00292 const int sp_sign = Scalar_Products::homogeneous_sign(expr, g); 00293 if (sp_sign != 0) 00294 // `*this' does not bound `expr'. 00295 return false; 00296 } 00297 } 00298 return true; 00299 }
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
.
expr | The linear expression to be maximized or minimized subject to this ; | |
method_call | The call description of the public parent method, for example "maximize(e)". Passed to throw_dimension_incompatible, as the first argument; | |
ext_n | The numerator of the extremum value; | |
ext_d | The denominator of the extremum value; | |
included | true if and only if the extremum of expr in this can actually be reached (which is always the case); | |
point | When maximization or minimization succeeds, will be assigned the point where expr reaches the extremum value. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
*this
is empty or expr
is not bounded in the appropriate direction, false
is returned and ext_n
, ext_d
, included
and point
are left untouched.
Definition at line 302 of file Grid_nonpublic.cc.
References bounds(), Parma_Polyhedra_Library::Grid_Generator::coefficient(), dim_kinds, Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), gen_sys, generators_are_minimized(), Parma_Polyhedra_Library::Scalar_Products::homogeneous_assign(), Parma_Polyhedra_Library::Linear_Expression::inhomogeneous_term(), marked_empty(), Parma_Polyhedra_Library::Generator::point(), set_generators_minimized(), simplify(), space_dim, and TEMP_INTEGER.
Referenced by maximize(), and minimize().
00305 { 00306 if (bounds(expr, method_call)) { 00307 if (marked_empty()) 00308 return false; 00309 if (space_dim == 0) { 00310 ext_n = 0; 00311 ext_d = 1; 00312 included = true; 00313 if (point) 00314 *point = Generator::point(); 00315 return true; 00316 } 00317 // Grid::bounds above ensures the generators are up to date. 00318 if (!generators_are_minimized()) { 00319 // Minimize the generator system. 00320 Grid& gr = const_cast<Grid&>(*this); 00321 gr.simplify(gr.gen_sys, gr.dim_kinds); 00322 gr.set_generators_minimized(); 00323 } 00324 00325 const Grid_Generator& gen = gen_sys[0]; 00326 Scalar_Products::homogeneous_assign(ext_n, expr, gen); 00327 ext_n += expr.inhomogeneous_term(); 00328 ext_d = gen.divisor(); 00329 // Reduce ext_n and ext_d. 00330 TEMP_INTEGER(gcd); 00331 gcd_assign(gcd, ext_n, ext_d); 00332 exact_div_assign(ext_n, ext_n, gcd); 00333 exact_div_assign(ext_d, ext_d, gcd); 00334 00335 included = true; 00336 if (point) { 00337 Linear_Expression e; 00338 for (dimension_type i = space_dim; i-- > 0; ) 00339 e += gen.coefficient(Variable(i)) * Variable(i); 00340 *point = Generator::point(e, gen.divisor()); 00341 } 00342 return true; 00343 } 00344 return false; 00345 }
void Parma_Polyhedra_Library::Grid::add_congruence_no_check | ( | const Congruence & | cg | ) | [private] |
Adds the congruence cg
to *this
.
cg
and *this
are dimension-incompatible, the behavior is undefined. Definition at line 555 of file Grid_nonpublic.cc.
References clear_congruences_minimized(), clear_generators_up_to_date(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Congruence::is_inconsistent(), marked_empty(), OK(), set_congruences_up_to_date(), set_empty(), space_dim, Parma_Polyhedra_Library::Congruence::space_dimension(), and update_congruences().
Referenced by add_congruence(), add_constraint_no_check(), difference_assign(), generalized_affine_image(), generalized_affine_preimage(), and refine_no_check().
00555 { 00556 assert(!marked_empty()); 00557 assert(space_dim >= cg.space_dimension()); 00558 00559 // Dealing with a zero-dimensional space grid first. 00560 if (space_dim == 0) { 00561 if (cg.is_inconsistent()) 00562 set_empty(); 00563 return; 00564 } 00565 00566 if (!congruences_are_up_to_date()) 00567 update_congruences(); 00568 00569 con_sys.insert(cg); 00570 00571 clear_congruences_minimized(); 00572 set_congruences_up_to_date(); 00573 clear_generators_up_to_date(); 00574 00575 // Note: the congruence system may have become unsatisfiable, thus 00576 // we do not check for satisfiability. 00577 assert(OK()); 00578 }
void Parma_Polyhedra_Library::Grid::add_constraint_no_check | ( | const Constraint & | c | ) | [private] |
Uses the constraint c
to refine *this
.
c | The constraint to be added. |
std::invalid_argument | Thrown if c is a non-trivial inequality constraint. |
c
and *this
are dimension-incompatible, the behavior is undefined. Definition at line 581 of file Grid_nonpublic.cc.
References add_congruence_no_check(), Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Constraint::is_inconsistent(), Parma_Polyhedra_Library::Constraint::is_inequality(), Parma_Polyhedra_Library::Constraint::is_tautological(), marked_empty(), set_empty(), space_dim, Parma_Polyhedra_Library::Constraint::space_dimension(), and throw_invalid_constraint().
Referenced by add_constraint(), and add_constraints().
00581 { 00582 assert(!marked_empty()); 00583 assert(space_dim >= c.space_dimension()); 00584 00585 if (c.is_inequality()) { 00586 // Only trivial inequalities can be handled. 00587 if (c.is_inconsistent()) { 00588 set_empty(); 00589 return; 00590 } 00591 if (c.is_tautological()) 00592 return; 00593 // Non-trivial inequality constraints are not allowed. 00594 throw_invalid_constraint("add_constraint(c)", "c"); 00595 } 00596 00597 assert(c.is_equality()); 00598 Congruence cg(c); 00599 add_congruence_no_check(cg); 00600 }
void Parma_Polyhedra_Library::Grid::refine_no_check | ( | const Constraint & | c | ) | [private] |
Uses the constraint c
to refine *this
.
c | The constraint to be added. Non-trivial inequalities are ignored. |
c
and *this
are dimension-incompatible, the behavior is undefined. Definition at line 603 of file Grid_nonpublic.cc.
References add_congruence_no_check(), Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Constraint::is_inconsistent(), marked_empty(), set_empty(), space_dim, and Parma_Polyhedra_Library::Constraint::space_dimension().
Referenced by refine_with_constraint(), and refine_with_constraints().
00603 { 00604 assert(!marked_empty()); 00605 assert(space_dim >= c.space_dimension()); 00606 00607 if (c.is_equality()) { 00608 Congruence cg(c); 00609 add_congruence_no_check(cg); 00610 } 00611 else if (c.is_inconsistent()) 00612 set_empty(); 00613 }
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 34 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().
00035 { 00036 // Private method: the caller must ensure the following conditions 00037 // (beside the inclusion `y <= x'). 00038 assert(space_dim == y.space_dim); 00039 assert(!marked_empty()); 00040 assert(!y.marked_empty()); 00041 assert(congruences_are_minimized()); 00042 assert(y.congruences_are_minimized()); 00043 00044 // Note: row counters start at 0, to preserve the original order in 00045 // the selected congruences. 00046 for (dimension_type dim = con_sys.space_dimension(), x_row = 0, y_row = 0; 00047 dim > 0; --dim) { 00048 assert(dim_kinds[dim] == CON_VIRTUAL 00049 || dim_kinds[dim] == y.dim_kinds[dim]); 00050 switch (dim_kinds[dim]) { 00051 case PROPER_CONGRUENCE: 00052 { 00053 const Congruence& cg = con_sys[x_row]; 00054 const Congruence& y_cg = y.con_sys[y_row]; 00055 if (cg.is_equal_at_dimension(dim, y_cg)) 00056 // The leading diagonal entries are equal. 00057 cgs_selected.insert(cg); 00058 ++x_row; 00059 ++y_row; 00060 } 00061 break; 00062 case EQUALITY: 00063 cgs_selected.insert(con_sys[x_row]); 00064 ++x_row; 00065 ++y_row; 00066 break; 00067 case CON_VIRTUAL: 00068 y.dim_kinds[dim] == CON_VIRTUAL || ++y_row; 00069 break; 00070 } 00071 } 00072 }
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 229 of file Grid_widenings.cc.
References Parma_Polyhedra_Library::Grid_Generator::coefficient(), dim_kinds, gen_sys, GEN_VIRTUAL, generators_are_minimized(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Grid_Generator::is_equal_at_dimension(), LINE, marked_empty(), PARAMETER, space_dim, Parma_Polyhedra_Library::Grid_Generator::space_dimension(), and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().
Referenced by generator_widening_assign().
00230 { 00231 // Private method: the caller must ensure the following conditions 00232 // (beside the inclusion `y <= x'). 00233 assert(space_dim == y.space_dim); 00234 assert(!marked_empty()); 00235 assert(!y.marked_empty()); 00236 assert(generators_are_minimized()); 00237 assert(y.generators_are_minimized()); 00238 00239 // Note: row counters start at 0, to preserve the original order in 00240 // the selected generators. 00241 for (dimension_type dim = 0, x_row = 0, y_row = 0; 00242 dim <= gen_sys.space_dimension(); ++dim) { 00243 assert(dim_kinds[dim] == LINE 00244 || y.dim_kinds[dim] == GEN_VIRTUAL 00245 || dim_kinds[dim] == y.dim_kinds[dim]); 00246 switch (dim_kinds[dim]) { 00247 case PARAMETER: 00248 { 00249 const Grid_Generator& gg = gen_sys[x_row]; 00250 const Grid_Generator& y_gg = y.gen_sys[y_row]; 00251 if (gg.is_equal_at_dimension(dim, y_gg)) 00252 // The leading diagonal entry is equal. 00253 ggs_selected.insert(gg); 00254 else { 00255 Linear_Expression e; 00256 for (dimension_type i = gg.space_dimension(); i-- > 0; ) 00257 e += gg.coefficient(Variable(i)) * Variable(i); 00258 ggs_selected.insert(grid_line(e)); 00259 } 00260 ++x_row; 00261 ++y_row; 00262 } 00263 break; 00264 case LINE: 00265 ggs_selected.insert(gen_sys[x_row]); 00266 ++x_row; 00267 ++y_row; 00268 break; 00269 case GEN_VIRTUAL: 00270 y.dim_kinds[dim] == GEN_VIRTUAL || ++y_row; 00271 break; 00272 } 00273 } 00274 }
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.
cgs | A congruence system, to which columns are added; | |
gs | A generator system, to which rows and columns are added; | |
dims | The number of space dimensions to add. |
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(), Parma_Polyhedra_Library::Matrix::add_zero_columns(), CON_VIRTUAL, congruences_are_minimized(), dim_kinds, generators_are_minimized(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and Parma_Polyhedra_Library::Matrix::swap_columns().
Referenced by add_space_dimensions_and_embed(), and add_space_dimensions_and_project().
00036 { 00037 assert(cgs.num_columns() - 1 == gs.space_dimension() + 1); 00038 assert(dims > 0); 00039 00040 const dimension_type old_modulus_index = cgs.num_columns() - 1; 00041 cgs.add_zero_columns(dims); 00042 // Move the moduli. 00043 cgs.swap_columns(old_modulus_index, old_modulus_index + dims); 00044 00045 if (congruences_are_minimized() || generators_are_minimized()) 00046 dim_kinds.resize(old_modulus_index + dims, CON_VIRTUAL /* a.k.a. LINE */); 00047 00048 gs.add_universe_rows_and_columns(dims); 00049 }
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.
gs | A generator system, to which columns are added; | |
cgs | A congruence system, to which rows and columns are added; | |
dims | The number of space dimensions to add. |
add_space_dimensions_and_project()
.
Definition at line 53 of file Grid_chdims.cc.
References Parma_Polyhedra_Library::Congruence_System::add_unit_rows_and_columns(), dim_kinds, EQUALITY, Parma_Polyhedra_Library::Grid_Generator_System::insert(), normalize_divisors(), Parma_Polyhedra_Library::Matrix::num_columns(), space_dim, and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().
00055 { 00056 assert(cgs.num_columns() - 1 == gs.space_dimension() + 1); 00057 assert(dims > 0); 00058 00059 cgs.add_unit_rows_and_columns(dims); 00060 00061 // Add `dims' zero columns onto gs. 00062 gs.insert(parameter(0*Variable(space_dim + dims - 1))); 00063 00064 normalize_divisors(gs); 00065 00066 dim_kinds.resize(cgs.num_columns() - 1, EQUALITY /* a.k.a GEN_VIRTUAL */); 00067 }
void Parma_Polyhedra_Library::Grid::normalize_divisors | ( | Grid_Generator_System & | sys, | |
Coefficient & | divisor, | |||
const Grid_Generator * | first_point = NULL | |||
) | [static, private] |
Normalizes the divisors in sys
.
Converts sys
to an equivalent system in which the divisors are of equal value.
sys | The generator system to be normalized. It must have at least one row. | |
divisor | A reference to the initial value of the divisor. The resulting value of this object is the new system divisor. | |
first_point | If 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 519 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(), and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().
Referenced by add_grid_generator(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), add_space_dimensions(), add_space_dimensions_and_project(), affine_image(), construct(), generalized_affine_image(), generalized_affine_preimage(), Grid(), normalize_divisors(), time_elapse_assign(), and upper_bound_assign().
00521 { 00522 assert(divisor >= 0); 00523 if (sys.space_dimension() > 0 && divisor > 0) { 00524 dimension_type row = 0; 00525 dimension_type num_rows = sys.num_rows(); 00526 00527 if (first_point) 00528 lcm_assign(divisor, divisor, (*first_point).divisor()); 00529 else { 00530 assert(num_rows > 0); 00531 // Move to the first point or parameter. 00532 while (sys[row].is_line()) 00533 if (++row == num_rows) 00534 // All rows are lines. 00535 return; 00536 00537 // Calculate the LCM of the given divisor and the divisor of 00538 // every point or parameter. 00539 while (row < num_rows) { 00540 const Grid_Generator& g = sys[row]; 00541 if (g.is_parameter_or_point()) 00542 lcm_assign(divisor, divisor, g.divisor()); 00543 ++row; 00544 } 00545 } 00546 00547 // Represent every point and every parameter using the newly 00548 // calculated divisor. 00549 for (row = num_rows; row-- > 0; ) 00550 sys[row].scale_to_divisor(divisor); 00551 } 00552 }
void Parma_Polyhedra_Library::Grid::normalize_divisors | ( | Grid_Generator_System & | sys | ) | [inline, static, private] |
Normalizes the divisors in sys
.
Converts sys
to an equivalent system in which the divisors are of equal value.
sys | The generator system to be normalized. It must have at least one row. |
Definition at line 371 of file Grid.inlines.hh.
References normalize_divisors(), and TEMP_INTEGER.
00371 { 00372 TEMP_INTEGER(divisor); 00373 divisor = 1; 00374 normalize_divisors(sys, divisor); 00375 }
void Parma_Polyhedra_Library::Grid::normalize_divisors | ( | Grid_Generator_System & | sys, | |
Grid_Generator_System & | gen_sys | |||
) | [static, private] |
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.
sys | The first of the generator systems to be normalized. | |
gen_sys | The 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. |
std::runtime_error | Thrown if all rows in gen_sys are lines and/or parameters. |
Definition at line 479 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Grid_Generator::divisor(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), normalize_divisors(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), and TEMP_INTEGER.
00480 { 00481 #ifndef NDEBUG 00482 const dimension_type num_rows = gen_sys.num_rows(); 00483 #endif 00484 assert(num_rows > 0); 00485 00486 // Find the first point in gen_sys. 00487 dimension_type row = 0; 00488 while (gen_sys[row].is_line_or_parameter()) { 00489 ++row; 00490 // gen_sys should have at least one point. 00491 assert(row < num_rows); 00492 } 00493 Grid_Generator& first_point = gen_sys[row]; 00494 const Coefficient& gen_sys_divisor = first_point.divisor(); 00495 00496 #ifndef NDEBUG 00497 // Check that the divisors in gen_sys are equal. 00498 for (dimension_type i = row + 1; i < num_rows; ++i) { 00499 Grid_Generator& g = gen_sys[i]; 00500 if (g.is_parameter_or_point()) 00501 assert(gen_sys_divisor == g.divisor()); 00502 } 00503 #endif // !defined(NDEBUG) 00504 00505 TEMP_INTEGER(divisor); 00506 divisor = gen_sys_divisor; 00507 // Adjust sys to include the gen_sys divisor. 00508 normalize_divisors(sys, divisor); 00509 if (divisor != gen_sys_divisor) 00510 // Adjust gen_sys to use the new divisor. 00511 // 00512 // The points and parameters in gen_sys share a common divisor 00513 // value, so the new divisor will be the LCM of this common 00514 // divisor and `divisor', hence the third argument. 00515 normalize_divisors(gen_sys, divisor, &first_point); 00516 }
void Parma_Polyhedra_Library::Grid::conversion | ( | Congruence_System & | source, | |
Grid_Generator_System & | dest, | |||
Dimension_Kinds & | dim_kinds | |||
) | [static, private] |
Converts generator system dest
to be equivalent to congruence system source
.
Definition at line 313 of file Grid_conversion.cc.
References CON_VIRTUAL, EQUALITY, Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), GEN_VIRTUAL, Parma_Polyhedra_Library::lcm_assign(), LINE, lower_triangular(), multiply_grid(), Parma_Polyhedra_Library::Matrix::num_columns(), PARAMETER, PROPER_CONGRUENCE, Parma_Polyhedra_Library::Grid_Generator_System::resize_no_copy(), Parma_Polyhedra_Library::Grid_Generator_System::set_index_first_pending_row(), Parma_Polyhedra_Library::Grid_Generator::set_is_line(), Parma_Polyhedra_Library::Grid_Generator::set_is_parameter_or_point(), Parma_Polyhedra_Library::sub_mul_assign(), TEMP_INTEGER, and upper_triangular().
Referenced by update_generators().
00314 { 00315 // Quite similar to the generator to congruence version above. 00316 // Changes here may be needed there too. 00317 00318 assert(lower_triangular(source, dim_kinds)); 00319 00320 // Initialize matrix row number counters and compute the LCM of the 00321 // diagonal entries of the proper congruences in `source'. 00322 dimension_type source_num_rows = 0, dest_num_rows = 0; 00323 TEMP_INTEGER(diagonal_lcm); 00324 diagonal_lcm = 1; 00325 dimension_type dims = source.num_columns() - 1; 00326 for (dimension_type dim = dims; dim-- > 0; ) 00327 if (dim_kinds[dim] == CON_VIRTUAL) 00328 // Virtual congruences map to lines. 00329 ++dest_num_rows; 00330 else { 00331 if (dim_kinds[dim] == PROPER_CONGRUENCE) { 00332 // Dimension `dim' has a proper congruence row at 00333 // `source_num_rows' in `source', so include in `diagonal_lcm' 00334 // the `dim'th element of that row. 00335 lcm_assign(diagonal_lcm, diagonal_lcm, source[source_num_rows][dim]); 00336 // Proper congruences map to parameters. 00337 ++dest_num_rows; 00338 } 00339 // Equalities map to virtual generators. 00340 ++source_num_rows; 00341 } 00342 00343 // `source' must be regular. 00344 if (diagonal_lcm == 0) 00345 throw std::runtime_error("PPL internal error: Grid::conversion:" 00346 " source matrix is singular."); 00347 00348 dest.set_index_first_pending_row(dest_num_rows); 00349 dest.resize_no_copy(dest_num_rows, dims + 1 /* parameter divisor */); 00350 00351 // In `dest' initialize row types and elements, including setting 00352 // the diagonal elements to the inverse ratio of the `source' 00353 // diagonal elements. 00354 // 00355 // The top-down order of the congruence system rows corresponds to 00356 // the right-left order of the dimensions. 00357 dimension_type source_index = 0; 00358 // The generator system has a bottom-up ordering. 00359 dimension_type dest_index = dest_num_rows - 1; 00360 for (dimension_type dim = dims; dim-- > 0; ) { 00361 if (dim_kinds[dim] == EQUALITY) { 00362 ++source_index; 00363 } 00364 else { 00365 Grid_Generator& g = dest[dest_index]; 00366 for (dimension_type j = dim; j-- > 0; ) 00367 g[j] = 0; 00368 for (dimension_type j = dim + 1; j < dims; ++j) 00369 g[j] = 0; 00370 00371 if (dim_kinds[dim] == CON_VIRTUAL) { 00372 g.set_is_line(); 00373 g[dim] = 1; 00374 } 00375 else { 00376 assert(dim_kinds[dim] == PROPER_CONGRUENCE); 00377 g.set_is_parameter_or_point(); 00378 exact_div_assign(g[dim], diagonal_lcm, source[source_index][dim]); 00379 ++source_index; 00380 } 00381 --dest_index; 00382 } 00383 } 00384 00385 assert(upper_triangular(dest, dim_kinds)); 00386 00387 // Convert. 00388 // 00389 // `source_index' and `dest_index' hold the positions of pivot rows 00390 // in `source' and `dest'. The order of the rows in `dest' is the 00391 // reverse of the order in `source', so the rows are iterated from 00392 // last to first (index 0) in `source' and from first to last in 00393 // `dest'. 00394 source_index = source_num_rows; 00395 dest_index = 0; 00396 TEMP_INTEGER(reduced_source_dim); 00397 00398 for (dimension_type dim = 0; dim < dims; ++dim) { 00399 if (dim_kinds[dim] != CON_VIRTUAL) { 00400 --source_index; 00401 const Coefficient& source_dim = source[source_index][dim]; 00402 00403 // In the rows in `dest' above `dest_index' divide each element 00404 // at column `dim' by `source_dim'. 00405 for (dimension_type row = dest_index; row-- > 0; ) { 00406 Grid_Generator& g = dest[row]; 00407 00408 // Multiply the representation of `dest' such that entry `dim' 00409 // of `g' is a multiple of `source_dim'. This ensures that 00410 // the result of the division that follows is a whole number. 00411 gcd_assign(reduced_source_dim, g[dim], source_dim); 00412 exact_div_assign(reduced_source_dim, source_dim, reduced_source_dim); 00413 multiply_grid(reduced_source_dim, g, dest, dest_num_rows, 00414 dims + 1 /* parameter divisor */); 00415 00416 Coefficient& g_dim = g[dim]; 00417 exact_div_assign(g_dim, g_dim, source_dim); 00418 } 00419 } 00420 00421 // Invert and transpose the source row at `source_index' into the 00422 // destination row at `dest_index'. 00423 // 00424 // Consider each dimension `dim_fol' that follows `dim', as the 00425 // rows in `dest' that follow row `dest_index' are zero at index 00426 // `dim'. 00427 dimension_type tmp_source_index = source_index; 00428 if (dim_kinds[dim] != EQUALITY) 00429 ++dest_index; 00430 for (dimension_type dim_fol = dim + 1; dim_fol < dims; ++dim_fol) { 00431 if (dim_kinds[dim_fol] != CON_VIRTUAL) { 00432 --tmp_source_index; 00433 const Coefficient& source_dim = source[tmp_source_index][dim]; 00434 // In order to compute the transpose of the inverse of 00435 // `source', subtract source[tmp_source_index][dim] times the 00436 // column vector in `dest' at `dim' from the column vector in 00437 // `dest' at `dim_fol'. 00438 // 00439 // I.e., for each row `dest_index' in `dest' that is above the 00440 // row `dest_index', subtract dest[tmp_source_index][dim] 00441 // times the entry `dim' from the entry at `dim_fol'. 00442 for (dimension_type row = dest_index; row-- > 0; ) { 00443 assert(row < dest_num_rows); 00444 Grid_Generator& g = dest[row]; 00445 sub_mul_assign(g[dim_fol], source_dim, g[dim]); 00446 } 00447 } 00448 } 00449 } 00450 00451 assert(upper_triangular(dest, dim_kinds)); 00452 00453 #ifdef STRONG_REDUCTION 00454 for (dimension_type dim = 0, i = 0; dim < dims; ++dim) 00455 if (dim_kinds[dim] != GEN_VIRTUAL) 00456 // Factor the "diagonal" generator out of the preceding rows. 00457 reduce_reduced<Grid_Generator_System, Grid_Generator> 00458 (dest, dim, i++, dim, dims - 1, dim_kinds); 00459 #endif 00460 00461 // Ensure that the parameter divisors are the same as the divisor of 00462 // the point. 00463 const Coefficient& system_divisor = dest[0][0]; 00464 for (dimension_type row = dest.num_rows() - 1, dim = dims; 00465 dim-- > 1; ) 00466 switch (dim_kinds[dim]) { 00467 case PARAMETER: 00468 dest[row].set_divisor(system_divisor); 00469 case LINE: 00470 --row; 00471 case GEN_VIRTUAL: 00472 break; 00473 } 00474 }
void Parma_Polyhedra_Library::Grid::conversion | ( | Grid_Generator_System & | source, | |
Congruence_System & | dest, | |||
Dimension_Kinds & | dim_kinds | |||
) | [static, private] |
Converts congruence system dest
to be equivalent to generator system source
.
Definition at line 154 of file Grid_conversion.cc.
References CON_VIRTUAL, Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), GEN_VIRTUAL, Parma_Polyhedra_Library::lcm_assign(), LINE, lower_triangular(), multiply_grid(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), PARAMETER, Parma_Polyhedra_Library::Congruence_System::resize_no_copy(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), Parma_Polyhedra_Library::sub_mul_assign(), TEMP_INTEGER, and upper_triangular().
00155 { 00156 // Quite similar to the congruence to generator version below. 00157 // Changes here may be needed there too. 00158 00159 assert(upper_triangular(source, dim_kinds)); 00160 00161 // Initialize matrix row number counters and compute the LCM of the 00162 // diagonal entries of the parameters in `source'. 00163 // 00164 // The top-down order of the generator system rows corresponds to 00165 // the left-right order of the dimensions, while the congruence 00166 // system rows have a bottom-up ordering. 00167 dimension_type dest_num_rows = 0; 00168 TEMP_INTEGER(diagonal_lcm); 00169 diagonal_lcm = 1; 00170 const dimension_type dims = source.space_dimension() + 1; 00171 dimension_type source_index = source.num_rows(); 00172 for (dimension_type dim = dims; dim-- > 0; ) 00173 if (dim_kinds[dim] == GEN_VIRTUAL) 00174 // Virtual generators map to equalities. 00175 ++dest_num_rows; 00176 else { 00177 --source_index; 00178 if (dim_kinds[dim] == PARAMETER) { 00179 // Dimension `dim' has a parameter row at `source_index' in 00180 // `source', so include in `diagonal_lcm' the `dim'th element 00181 // of that row. 00182 lcm_assign(diagonal_lcm, diagonal_lcm, source[source_index][dim]); 00183 // Parameters map to proper congruences. 00184 ++dest_num_rows; 00185 } 00186 // Lines map to virtual congruences. 00187 } 00188 assert(source_index == 0); 00189 00190 // `source' must be regular. 00191 if (diagonal_lcm == 0) 00192 throw std::runtime_error("PPL internal error: Grid::conversion:" 00193 " source matrix is singular."); 00194 00195 dest.resize_no_copy(dest_num_rows, dims + 1 /* moduli */); 00196 00197 // In `dest' initialize row types and elements, including setting 00198 // the diagonal elements to the inverse ratio of the `source' 00199 // diagonal elements. 00200 dimension_type dest_index = 0; 00201 source_index = source.num_rows(); 00202 for (dimension_type dim = dims; dim-- > 0; ) { 00203 if (dim_kinds[dim] == LINE) 00204 --source_index; 00205 else { 00206 Congruence& cg = dest[dest_index]; 00207 for (dimension_type j = dim; j-- > 0; ) 00208 cg[j] = 0; 00209 for (dimension_type j = dim + 1; j < dims; ++j) 00210 cg[j] = 0; 00211 00212 if (dim_kinds[dim] == GEN_VIRTUAL) { 00213 cg[dims] = 0; // An equality. 00214 cg[dim] = 1; 00215 } 00216 else { 00217 assert(dim_kinds[dim] == PARAMETER); 00218 --source_index; 00219 cg[dims] = 1; // A proper congruence. 00220 exact_div_assign(cg[dim], diagonal_lcm, source[source_index][dim]); 00221 } 00222 ++dest_index; 00223 } 00224 } 00225 00226 assert(source_index == 0); 00227 assert(dest_index == dest_num_rows); 00228 assert(lower_triangular(dest, dim_kinds)); 00229 00230 // Convert. 00231 // 00232 // `source_index' and `dest_index' hold the positions of pivot rows 00233 // in `source' and `dest'. The order of the rows in `dest' is the 00234 // reverse of the order in `source', so the rows are iterated from 00235 // last to first (index 0) in `source' and from first to last in 00236 // `dest'. 00237 source_index = source.num_rows(); 00238 dest_index = 0; 00239 TEMP_INTEGER(multiplier); 00240 00241 for (dimension_type dim = dims; dim-- > 0; ) { 00242 if (dim_kinds[dim] != GEN_VIRTUAL) { 00243 --source_index; 00244 const Coefficient& source_dim = source[source_index][dim]; 00245 00246 // In the rows in `dest' above `dest_index' divide each element 00247 // at column `dim' by `source_dim'. 00248 for (dimension_type row = dest_index; row-- > 0; ) { 00249 Congruence& cg = dest[row]; 00250 00251 // Multiply the representation of `dest' such that entry `dim' 00252 // of `g' is a multiple of `source_dim'. This ensures that 00253 // the result of the division that follows is a whole number. 00254 gcd_assign(multiplier, cg[dim], source_dim); 00255 exact_div_assign(multiplier, source_dim, multiplier); 00256 multiply_grid(multiplier, cg, dest, dest_num_rows, dims); 00257 00258 Coefficient& cg_dim = cg[dim]; 00259 exact_div_assign(cg_dim, cg_dim, source_dim); 00260 } 00261 } 00262 00263 // Invert and transpose the source row at `source_index' into the 00264 // destination row at `dest_index'. 00265 // 00266 // Consider each dimension `dim_prec' that precedes `dim', as the 00267 // rows in `dest' that follow `dim_index' have zeroes at index 00268 // `dim'. 00269 dimension_type tmp_source_index = source_index; 00270 if (dim_kinds[dim] != LINE) 00271 ++dest_index; 00272 for (dimension_type dim_prec = dim; dim_prec-- > 0; ) { 00273 if (dim_kinds[dim_prec] != GEN_VIRTUAL) { 00274 --tmp_source_index; 00275 const Coefficient& source_dim = source[tmp_source_index][dim]; 00276 // In order to compute the transpose of the inverse of 00277 // `source', subtract source[tmp_source_index][dim] times the 00278 // column vector in `dest' at `dim' from the column vector in 00279 // `dest' at `dim_prec'. 00280 // 00281 // I.e., for each row `dest_index' in `dest' that is above the 00282 // row `dest_index', subtract dest[tmp_source_index][dim] 00283 // times the entry `dim' from the entry at `dim_prec'. 00284 for (dimension_type row = dest_index; row-- > 0; ) { 00285 assert(row < dest_num_rows); 00286 Congruence& cg = dest[row]; 00287 sub_mul_assign(cg[dim_prec], source_dim, cg[dim]); 00288 } 00289 } 00290 } 00291 } 00292 // Set the modulus in every congruence. 00293 const Coefficient& modulus = dest[dest_num_rows - 1][0]; 00294 for (dimension_type row = dest_num_rows; row-- > 0; ) { 00295 Congruence& cg = dest[row]; 00296 if (cg[dims] > 0) 00297 // `cg' is a proper congruence. 00298 cg[dims] = modulus; 00299 } 00300 00301 assert(lower_triangular(dest, dim_kinds)); 00302 00303 #ifdef STRONG_REDUCTION 00304 for (dimension_type dim = dims, i = 0; dim-- > 0; ) 00305 if (dim_kinds[dim] != CON_VIRTUAL) 00306 // Factor the "diagonal" congruence out of the preceding rows. 00307 reduce_reduced<Congruence_System, Congruence> 00308 (dest, dim, i++, 0, dim, dim_kinds, false); 00309 #endif 00310 }
bool Parma_Polyhedra_Library::Grid::simplify | ( | Congruence_System & | cgs, | |
Dimension_Kinds & | dim_kinds | |||
) | [static, private] |
Converts cgs
to upper triangular (i.e. minimized) form.
Returns true
if cgs
represents the empty set, otherwise returns false
.
Definition at line 375 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::Matrix::add_zero_rows(), CON_VIRTUAL, EQUALITY, Parma_Polyhedra_Library::Matrix::erase_to_end(), Parma_Polyhedra_Library::Congruence::inhomogeneous_term(), Parma_Polyhedra_Library::Congruence::is_equality(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::NECESSARILY_CLOSED, Parma_Polyhedra_Library::Congruence::negate(), Parma_Polyhedra_Library::Congruence_System::normalize_moduli(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::Congruence_System::OK(), PROPER_CONGRUENCE, Parma_Polyhedra_Library::Linear_Row::RAY_OR_POINT_OR_INEQUALITY, reduce_congruence_with_equality(), reduce_equality_with_equality(), reduce_pc_with_pc(), Parma_Polyhedra_Library::Matrix::rows, Parma_Polyhedra_Library::Congruence::set_is_equality(), and Parma_Polyhedra_Library::swap().
Referenced by congruence_widening_assign(), generator_widening_assign(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_empty(), max_min(), minimize(), minimized_congruences(), minimized_grid_generators(), OK(), and update_generators().
00375 { 00376 assert(sys.num_columns() > 2); 00377 00378 // Changes here may also be required in the generator version above. 00379 00380 // TODO: Consider normalizing the moduli only when congruences are 00381 // added to con_sys. 00382 sys.normalize_moduli(); 00383 00384 const dimension_type num_columns = sys.num_columns() - 1 /* modulus */; 00385 00386 if (dim_kinds.size() != num_columns) 00387 dim_kinds.resize(num_columns); 00388 00389 const dimension_type num_rows = sys.num_rows(); 00390 00391 // For each dimension `dim' move or construct a row into position 00392 // `pivot_index' such that the row has a value of zero in all 00393 // elements preceding column `dim' and some other value in column 00394 // `dim'. 00395 dimension_type pivot_index = 0; 00396 for (dimension_type dim = num_columns; dim-- > 0; ) { 00397 // Consider the pivot and following rows. 00398 dimension_type row_index = pivot_index; 00399 00400 // Move down over rows which have zero in column `dim'. 00401 while (row_index < num_rows && sys[row_index][dim] == 0) 00402 ++row_index; 00403 00404 if (row_index == num_rows) 00405 // Element in column `dim' is zero in all rows from the pivot, 00406 // or `sys' is empty of rows. 00407 dim_kinds[dim] = CON_VIRTUAL; 00408 else { 00409 // row_index != num_rows 00410 if (row_index != pivot_index) 00411 std::swap(sys[row_index], sys[pivot_index]); 00412 Congruence& pivot = sys[pivot_index]; 00413 bool pivot_is_equality = pivot.is_equality(); 00414 00415 // Change the matrix so that the value at `dim' in every row 00416 // following `pivot_index' is 0, leaving an equivalent grid. 00417 while (row_index < num_rows - 1) { 00418 ++row_index; 00419 00420 Congruence& row = sys[row_index]; 00421 00422 if (row[dim] == 0) 00423 continue; 00424 00425 if (row.is_equality()) 00426 if (pivot_is_equality) 00427 reduce_equality_with_equality(row, pivot, dim); 00428 else { 00429 assert(pivot.is_proper_congruence()); 00430 std::swap(row, pivot); 00431 pivot_is_equality = true; 00432 reduce_congruence_with_equality(row, pivot, dim, sys); 00433 } 00434 else { 00435 assert(row.is_proper_congruence()); 00436 if (pivot_is_equality) 00437 reduce_congruence_with_equality(row, pivot, dim, sys); 00438 else { 00439 assert(pivot.is_proper_congruence()); 00440 reduce_pc_with_pc(row, pivot, dim, 0, dim); 00441 } 00442 } 00443 } 00444 00445 if (pivot_is_equality) 00446 dim_kinds[dim] = EQUALITY; 00447 else { 00448 assert(pivot.is_proper_congruence()); 00449 dim_kinds[dim] = PROPER_CONGRUENCE; 00450 } 00451 00452 #ifdef STRONG_REDUCTION 00453 // Ensure a positive follows the leading zeros. 00454 if (pivot[dim] < 0) 00455 pivot.negate(0, dim); 00456 // Factor this row out of the preceding ones. 00457 reduce_reduced<Congruence_System, Congruence> 00458 (sys, dim, pivot_index, 0, dim, dim_kinds, false); 00459 #endif 00460 ++pivot_index; 00461 } 00462 } // end for (dimension_type dim = num_columns; dim-- > 0; ) 00463 00464 // For clearer naming. 00465 dimension_type& reduced_num_rows = pivot_index; 00466 00467 if (reduced_num_rows > 0) { 00468 // If the last row is false then make it the equality 1 = 0, and 00469 // make it the only row. 00470 Congruence& last_row = sys[reduced_num_rows - 1]; 00471 if (dim_kinds[0] == PROPER_CONGRUENCE) { 00472 if (last_row.inhomogeneous_term() % last_row.modulus() != 0) { 00473 // The last row is a false proper congruence. 00474 last_row.set_is_equality(); 00475 dim_kinds[0] = EQUALITY; 00476 goto return_empty; 00477 } 00478 } 00479 else if (dim_kinds[0] == EQUALITY) { 00480 // The last row is a false equality, as all the coefficient terms 00481 // are zero while the inhomogeneous term (as a result of the 00482 // reduced form) is some other value. 00483 return_empty: 00484 last_row[0] = 1; 00485 dim_kinds.resize(1); 00486 std::swap(sys.rows[0], sys.rows.back()); 00487 sys.erase_to_end(1); 00488 00489 assert(sys.OK()); 00490 return true; 00491 } 00492 } 00493 else { 00494 // Either sys is empty (it defines the universe) or every column 00495 // before the modulus column contains only zeroes. 00496 00497 // Set up the integrality congruence. 00498 dim_kinds[0] = PROPER_CONGRUENCE; 00499 if (num_rows == 0) { 00500 sys.add_zero_rows(1, 00501 Linear_Row::Flags(NECESSARILY_CLOSED, 00502 Linear_Row::RAY_OR_POINT_OR_INEQUALITY)); 00503 Congruence& cg = sys[0]; 00504 cg[num_columns] = 1; 00505 cg[0] = 1; 00506 00507 assert(sys.OK()); 00508 return false; 00509 } 00510 sys[0][num_columns] = 1; 00511 // Ensure that, after any zero row clipping below, a single row 00512 // will remain for the integrality congruence. 00513 reduced_num_rows = 1; 00514 } 00515 00516 // Clip any zero rows from the end of the matrix. 00517 if (num_rows > 1 && num_rows > reduced_num_rows) { 00518 #ifndef NDEBUG 00519 const bool ret = rows_are_zero<Congruence_System, Congruence> 00520 (sys, 00521 // index of first 00522 reduced_num_rows, 00523 // index of last 00524 num_rows - 1, 00525 // row size 00526 num_columns); 00527 assert(ret == true); 00528 #endif 00529 sys.erase_to_end(reduced_num_rows); 00530 } 00531 00532 assert(sys.num_rows() == reduced_num_rows); 00533 00534 // Ensure that the last row is the integrality congruence. 00535 const dimension_type mod_index = num_columns; 00536 if (dim_kinds[0] == CON_VIRTUAL) { 00537 // The last row is virtual, append the integrality congruence. 00538 dim_kinds[0] = PROPER_CONGRUENCE; 00539 sys.add_zero_rows(1, 00540 Linear_Row::Flags(NECESSARILY_CLOSED, 00541 Linear_Row::RAY_OR_POINT_OR_INEQUALITY)); 00542 Congruence& new_last_row = sys[reduced_num_rows]; 00543 new_last_row[mod_index] = 1; 00544 // Try use an existing modulus. 00545 dimension_type row_index = reduced_num_rows; 00546 while (row_index-- > 0) { 00547 Congruence& row = sys[row_index]; 00548 if (row[mod_index] > 0) { 00549 new_last_row[mod_index] = row[mod_index]; 00550 break; 00551 } 00552 } 00553 new_last_row[0] = new_last_row[mod_index]; 00554 #ifdef STRONG_REDUCTION 00555 ++reduced_num_rows; 00556 #endif 00557 } 00558 else { 00559 Congruence& last_row = sys[reduced_num_rows - 1]; 00560 last_row[0] = last_row[mod_index]; 00561 } 00562 00563 #ifdef STRONG_REDUCTION 00564 // Factor the modified integrality congruence out of the other rows. 00565 reduce_reduced<Congruence_System, Congruence> 00566 (sys, 0, reduced_num_rows - 1, 0, 0, dim_kinds, false); 00567 #endif 00568 00569 assert(sys.OK()); 00570 return false; 00571 }
void Parma_Polyhedra_Library::Grid::simplify | ( | Grid_Generator_System & | gs, | |
Dimension_Kinds & | dim_kinds | |||
) | [static, private] |
Converts gs
to lower triangular (i.e. minimized) form.
Expects gs
to contain at least one point.
Definition at line 249 of file Grid_simplify.cc.
References GEN_VIRTUAL, Parma_Polyhedra_Library::Matrix::has_no_rows(), Parma_Polyhedra_Library::Grid_Generator::is_line(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), LINE, Parma_Polyhedra_Library::Grid_Generator::negate(), Parma_Polyhedra_Library::Grid_Generator_System::num_columns(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), Parma_Polyhedra_Library::Grid_Generator_System::OK(), PARAMETER, reduce_line_with_line(), reduce_parameter_with_line(), reduce_pc_with_pc(), Parma_Polyhedra_Library::swap(), and Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows().
00249 { 00250 assert(!sys.has_no_rows()); 00251 // For reduce_pc_with_pc. 00252 assert(sys.num_columns() > 0); 00253 00254 // Changes here may also be required in the congruence version 00255 // below. 00256 00257 // Subtract one to allow for the parameter divisor column 00258 const dimension_type num_columns = sys.num_columns() - 1; 00259 00260 if (dim_kinds.size() != num_columns) 00261 dim_kinds.resize(num_columns); 00262 00263 const dimension_type num_rows = sys.num_rows(); 00264 00265 // For each dimension `dim' move or construct a row into position 00266 // `pivot_index' such that the row has zero in all elements 00267 // following column `dim' and a value other than zero in column 00268 // `dim'. 00269 dimension_type pivot_index = 0; 00270 for (dimension_type dim = 0; dim < num_columns; ++dim) { 00271 // Consider the pivot and following rows. 00272 dimension_type row_index = pivot_index; 00273 00274 // Move down over rows which have zero in column `dim'. 00275 while (row_index < num_rows && sys[row_index][dim] == 0) 00276 ++row_index; 00277 00278 if (row_index == num_rows) 00279 // Element in column `dim' is zero in all rows from the pivot. 00280 dim_kinds[dim] = GEN_VIRTUAL; 00281 else { 00282 if (row_index != pivot_index) 00283 std::swap(sys[row_index], sys[pivot_index]); 00284 Grid_Generator& pivot = sys[pivot_index]; 00285 bool pivot_is_line = pivot.is_line(); 00286 00287 // Change the matrix so that the value at `dim' in every row 00288 // following `pivot_index' is 0, leaving an equivalent grid. 00289 while (row_index < num_rows - 1) { 00290 ++row_index; 00291 00292 Grid_Generator& row = sys[row_index]; 00293 00294 if (row[dim] == 0) 00295 continue; 00296 00297 if (row.is_line()) 00298 if (pivot_is_line) 00299 reduce_line_with_line(row, pivot, dim); 00300 else { 00301 assert(pivot.is_parameter_or_point()); 00302 std::swap(row, pivot); 00303 pivot_is_line = true; 00304 reduce_parameter_with_line(row, pivot, dim, sys); 00305 } 00306 else { 00307 assert(row.is_parameter_or_point()); 00308 if (pivot_is_line) 00309 reduce_parameter_with_line(row, pivot, dim, sys); 00310 else { 00311 assert(pivot.is_parameter_or_point()); 00312 reduce_pc_with_pc(row, pivot, dim, dim + 1, num_columns); 00313 } 00314 } 00315 } 00316 00317 if (pivot_is_line) 00318 dim_kinds[dim] = LINE; 00319 else { 00320 assert(pivot.is_parameter_or_point()); 00321 dim_kinds[dim] = PARAMETER; 00322 } 00323 00324 #ifdef STRONG_REDUCTION 00325 // Ensure a positive follows the leading zeros. 00326 if (pivot[dim] < 0) 00327 pivot.negate(dim, num_columns - 1); 00328 00329 // Factor this row out of the preceding rows. 00330 reduce_reduced<Grid_Generator_System, Grid_Generator> 00331 (sys, dim, pivot_index, dim, num_columns - 1, dim_kinds); 00332 #endif 00333 00334 ++pivot_index; 00335 } 00336 } 00337 00338 // Clip any zero rows from the end of the matrix. 00339 if (num_rows > pivot_index) { 00340 #ifndef NDEBUG 00341 const bool ret = rows_are_zero<Grid_Generator_System, Grid_Generator> 00342 (sys, 00343 // index of first 00344 pivot_index, 00345 // index of last 00346 sys.num_rows() - 1, 00347 // row size 00348 sys.num_columns() - 1); 00349 assert(ret == true); 00350 #endif 00351 sys.erase_to_end(pivot_index); 00352 } 00353 00354 sys.unset_pending_rows(); 00355 00356 // Ensure that the parameter divisors are the same as the system 00357 // divisor. 00358 const Coefficient& system_divisor = sys[0][0]; 00359 for (dimension_type row = sys.num_rows() - 1, 00360 dim = sys.num_columns() - 2; 00361 dim > 0; --dim) 00362 switch (dim_kinds[dim]) { 00363 case PARAMETER: 00364 sys[row].set_divisor(system_divisor); 00365 case LINE: 00366 --row; 00367 case GEN_VIRTUAL: 00368 break; 00369 } 00370 00371 assert(sys.OK()); 00372 }
void Parma_Polyhedra_Library::Grid::reduce_line_with_line | ( | Grid_Generator & | row, | |
Grid_Generator & | pivot, | |||
dimension_type | col | |||
) | [static, private] |
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 col
of row
is zero.
Definition at line 31 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Grid_Generator::size(), Parma_Polyhedra_Library::sub_mul_assign(), and TEMP_INTEGER.
Referenced by simplify().
00032 { 00033 const Coefficient& pivot_column = pivot[column]; 00034 Coefficient& row_column = row[column]; 00035 TEMP_INTEGER(reduced_row_col); 00036 // Use reduced_row_col temporarily to hold the gcd. 00037 gcd_assign(reduced_row_col, pivot_column, row_column); 00038 // Store the reduced ratio between pivot[column] and row[column]. 00039 TEMP_INTEGER(reduced_pivot_col); 00040 exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col); 00041 exact_div_assign(reduced_row_col, row_column, reduced_row_col); 00042 // Multiply row, then subtract from it a multiple of pivot such that 00043 // the result in row[column] is zero. 00044 row_column = 0; 00045 // pivot.size() - 1 is the index for the parameter divisor so we 00046 // start reducing the line at index pivot.size() - 2. 00047 for (dimension_type col = pivot.size() - 2; 00048 col > column; 00049 --col) { 00050 Coefficient& row_col = row[col]; 00051 row_col *= reduced_pivot_col; 00052 sub_mul_assign(row_col, reduced_row_col, pivot[col]); 00053 } 00054 }
void Parma_Polyhedra_Library::Grid::reduce_equality_with_equality | ( | Congruence & | row, | |
const Congruence & | pivot, | |||
dimension_type | col | |||
) | [static, private] |
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 col
of row
is zero.
Definition at line 57 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::sub_mul_assign(), and TEMP_INTEGER.
Referenced by simplify().
00059 { 00060 // Assume two equalities. 00061 assert(row.modulus() == 0 && pivot.modulus() == 0); 00062 00063 const Coefficient& pivot_column = pivot[column]; 00064 Coefficient& row_column = row[column]; 00065 TEMP_INTEGER(reduced_row_col); 00066 // Use reduced_row_col temporarily to hold the gcd. 00067 gcd_assign(reduced_row_col, pivot_column, row_column); 00068 // Store the reduced ratio between pivot[column] and row[column]. 00069 TEMP_INTEGER(reduced_pivot_col); 00070 exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col); 00071 exact_div_assign(reduced_row_col, row_column, reduced_row_col); 00072 // Multiply row, then subtract from it a multiple of pivot such that 00073 // the result in row[column] is zero. 00074 row_column = 0; 00075 for (dimension_type col = column; col-- > 0; ) { 00076 Coefficient& row_col = row[col]; 00077 row_col *= reduced_pivot_col; 00078 sub_mul_assign(row_col, reduced_row_col, pivot[col]); 00079 } 00080 }
void Parma_Polyhedra_Library::Grid::reduce_pc_with_pc | ( | R & | row, | |
R & | pivot, | |||
dimension_type | col, | |||
dimension_type | start, | |||
dimension_type | end | |||
) | [inline, static, private] |
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 col
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).
Definition at line 84 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcdext_assign(), Parma_Polyhedra_Library::sub_mul_assign(), and TEMP_INTEGER.
Referenced by simplify().
00087 { 00088 Coefficient& pivot_column = pivot[column]; 00089 Coefficient& row_column = row[column]; 00090 00091 TEMP_INTEGER(s); 00092 TEMP_INTEGER(t); 00093 TEMP_INTEGER(reduced_row_col); 00094 // Use reduced_row_col temporarily to hold the gcd. 00095 gcdext_assign(reduced_row_col, s, t, pivot_column, row_column); 00096 // Now pivot[column] * s + row[column] * t == gcd. 00097 00098 // Store the reduced ratio between pivot[column] and row[column]. 00099 TEMP_INTEGER(reduced_pivot_col); 00100 exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col); 00101 pivot_column = reduced_row_col /* gcd */; 00102 exact_div_assign(reduced_row_col, row_column, reduced_row_col); 00103 00104 // Multiply row, then subtract from it a multiple of pivot such that 00105 // the result in row[column] is zero. Afterward, multiply pivot, 00106 // then add to it a (possibly negative) multiple of row such that 00107 // the result in pivot[column] is the smallest possible positive 00108 // integer. 00109 assert(pivot.size() > 0); 00110 assert(row.size() > 0); 00111 row_column = 0; 00112 TEMP_INTEGER(old_pivot_col); 00113 for (dimension_type col = start; col < end; ++col) { 00114 Coefficient& pivot_col = pivot[col]; 00115 old_pivot_col = pivot_col; 00116 pivot_col *= s; 00117 Coefficient& row_col = row[col]; 00118 add_mul_assign(pivot_col, t, row_col); 00119 row_col *= reduced_pivot_col; 00120 sub_mul_assign(row_col, reduced_row_col, old_pivot_col); 00121 } 00122 }
void Parma_Polyhedra_Library::Grid::reduce_parameter_with_line | ( | Grid_Generator & | row, | |
const Grid_Generator & | pivot, | |||
dimension_type | col, | |||
Grid_Generator_System & | sys | |||
) | [static, private] |
Reduce row
using pivot
.
Use the line pivot
to change the representation of the parameter row
such that the element at index col
of row
is zero.
Definition at line 125 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::Grid_Generator_System::num_columns(), Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), Parma_Polyhedra_Library::sub_mul_assign(), and TEMP_INTEGER.
Referenced by simplify().
00128 { 00129 // Very similar to reduce_congruence_with_equality below. Any 00130 // change here may be needed there too. 00131 00132 const Coefficient& pivot_column = pivot[column]; 00133 Coefficient& row_column = row[column]; 00134 00135 // Subtract one to allow for the parameter divisor column 00136 const dimension_type num_columns = sys.num_columns() - 1; 00137 00138 // If the elements at column in row and pivot are the same, then 00139 // just subtract pivot from row. 00140 if (row_column == pivot_column) { 00141 for (dimension_type col = num_columns; col-- > 0; ) 00142 row[col] -= pivot[col]; 00143 return; 00144 } 00145 00146 TEMP_INTEGER(reduced_row_col); 00147 // Use reduced_row_col temporarily to hold the gcd. 00148 gcd_assign(reduced_row_col, pivot_column, row_column); 00149 // Store the reduced ratio between pivot[column] and row[column]. 00150 TEMP_INTEGER(reduced_pivot_col); 00151 exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col); 00152 exact_div_assign(reduced_row_col, row_column, reduced_row_col); 00153 00154 // Multiply row such that a multiple of pivot can be subtracted from 00155 // it below to render row[column] zero. This requires multiplying 00156 // all other parameters to match. 00157 #ifdef STRONG_REDUCTION 00158 // Ensure that the multiplier is positive, so that the preceding 00159 // diagonals (including the divisor) remain positive. It's safe to 00160 // swap the signs as row[column] will still come out 0. 00161 if (reduced_pivot_col < 0) { 00162 neg_assign(reduced_pivot_col); 00163 neg_assign(reduced_row_col); 00164 } 00165 #endif 00166 for (dimension_type index = sys.num_rows(); index-- > 0; ) { 00167 Grid_Generator& gen = sys[index]; 00168 if (gen.is_parameter_or_point()) 00169 for (dimension_type col = num_columns; col-- > 0; ) 00170 gen[col] *= reduced_pivot_col; 00171 } 00172 // Subtract from row a multiple of pivot such that the result in 00173 // row[column] is zero. 00174 row_column = 0; 00175 for (dimension_type col = num_columns - 1; col > column; --col) 00176 sub_mul_assign(row[col], reduced_row_col, pivot[col]); 00177 }
void Parma_Polyhedra_Library::Grid::reduce_congruence_with_equality | ( | Congruence & | row, | |
const Congruence & | pivot, | |||
dimension_type | col, | |||
Congruence_System & | sys | |||
) | [static, private] |
Reduce row
using pivot
.
Use the equality pivot
to change the representation of the congruence row
such that element at index col
of row
is zero.
Definition at line 180 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::exact_div_assign(), Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Congruence::is_proper_congruence(), Parma_Polyhedra_Library::Congruence::modulus(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::Matrix::num_columns(), Parma_Polyhedra_Library::Matrix::num_rows(), Parma_Polyhedra_Library::sub_mul_assign(), and TEMP_INTEGER.
Referenced by simplify().
00183 { 00184 // Very similar to reduce_parameter_with_line above. Any change 00185 // here may be needed there too. 00186 assert(row.modulus() > 0 && pivot.modulus() == 0); 00187 00188 const Coefficient& pivot_column = pivot[column]; 00189 Coefficient& row_column = row[column]; 00190 00191 dimension_type num_columns = sys.num_columns(); 00192 00193 // If the elements at `column' in row and pivot are the same, then 00194 // just subtract `pivot' from `row'. 00195 if (row_column == pivot_column) { 00196 for (dimension_type col = num_columns; col-- > 0; ) 00197 row[col] -= pivot[col]; 00198 return; 00199 } 00200 00201 TEMP_INTEGER(reduced_row_col); 00202 // Use reduced_row_col temporarily to hold the gcd. 00203 gcd_assign(reduced_row_col, pivot_column, row_column); 00204 TEMP_INTEGER(reduced_pivot_col); 00205 exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col); 00206 exact_div_assign(reduced_row_col, row_column, reduced_row_col); 00207 // Ensure that `reduced_pivot_col' is positive, so that the modulus 00208 // remains positive when multiplying the proper congruences below. 00209 // It's safe to swap the signs as row[column] will still come out 0. 00210 if (reduced_pivot_col < 0) { 00211 neg_assign(reduced_pivot_col); 00212 neg_assign(reduced_row_col); 00213 } 00214 // Multiply `row', including the modulus, by reduced_pivot_col. To 00215 // keep all the moduli the same this requires multiplying all the 00216 // other proper congruences in the same way. 00217 for (dimension_type index = sys.num_rows(); index-- > 0; ) { 00218 Congruence& cg = sys[index]; 00219 if (cg.is_proper_congruence()) 00220 for (dimension_type col = num_columns; col-- > 0; ) 00221 cg[col] *= reduced_pivot_col; 00222 } 00223 // Column num_columns contains the modulus, so start at the next 00224 // column. 00225 --num_columns; 00226 row_column = 0; 00227 // Subtract from row a multiple of pivot such that the result in 00228 // row[column] is zero. 00229 for (dimension_type col = column; col-- > 0; ) 00230 sub_mul_assign(row[col], reduced_row_col, pivot[col]); 00231 }
static void Parma_Polyhedra_Library::Grid::reduce_reduced | ( | M & | sys, | |
dimension_type | dim, | |||
dimension_type | pivot_index, | |||
dimension_type | start, | |||
dimension_type | end, | |||
const Dimension_Kinds & | dim_kinds, | |||
bool | generators = true | |||
) | [inline, static, private] |
Reduce column dim
in rows preceding pivot_index
in sys
.
Only consider from index start
to index end
of the row at pivot_index
. Flag generators
indicates whether sys
is a congruence or generator system.
void Parma_Polyhedra_Library::Grid::multiply_grid | ( | const Coefficient & | multiplier, | |
Congruence & | cg, | |||
Congruence_System & | dest, | |||
dimension_type | num_rows, | |||
dimension_type | num_dims | |||
) | [static, private] |
Multiply the elements of dest
by multiplier
.
Definition at line 127 of file Grid_conversion.cc.
References Parma_Polyhedra_Library::Congruence::is_equality(), and Parma_Polyhedra_Library::Congruence::is_proper_congruence().
Referenced by conversion().
00129 { 00130 if (multiplier == 1) 00131 return; 00132 00133 if (cg.is_proper_congruence()) 00134 // Multiply every element of every congruence. 00135 for (dimension_type index = num_rows; index-- > 0; ) { 00136 Congruence& congruence = dest[index]; 00137 if (congruence.is_proper_congruence()) 00138 for (dimension_type column = num_dims; column-- > 0; ) 00139 congruence[column] *= multiplier; 00140 } 00141 else { 00142 assert(cg.is_equality()); 00143 // Multiply every element of the equality. 00144 for (dimension_type column = num_dims; column-- > 0; ) 00145 cg[column] *= multiplier; 00146 } 00147 }
void Parma_Polyhedra_Library::Grid::multiply_grid | ( | const Coefficient & | multiplier, | |
Grid_Generator & | gen, | |||
Grid_Generator_System & | dest, | |||
dimension_type | num_rows, | |||
dimension_type | num_dims | |||
) | [static, private] |
Multiply the elements of dest
by multiplier
.
Definition at line 104 of file Grid_conversion.cc.
References Parma_Polyhedra_Library::Grid_Generator::is_line(), and Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point().
00106 { 00107 if (multiplier == 1) 00108 return; 00109 00110 if (gen.is_line()) 00111 // Multiply every element of the line. 00112 for (dimension_type column = num_dims; column-- > 0; ) 00113 gen[column] *= multiplier; 00114 else { 00115 assert(gen.is_parameter_or_point()); 00116 // Multiply every element of every parameter. 00117 for (dimension_type index = num_rows; index-- > 0; ) { 00118 Grid_Generator& generator = dest[index]; 00119 if (generator.is_parameter_or_point()) 00120 for (dimension_type column = num_dims; column-- > 0; ) 00121 generator[column] *= multiplier; 00122 } 00123 } 00124 }
bool Parma_Polyhedra_Library::Grid::lower_triangular | ( | const Congruence_System & | sys, | |
const Dimension_Kinds & | dim_kinds | |||
) | [static, private] |
If sys
is lower triangular return true
, else return false
.
Definition at line 37 of file Grid_conversion.cc.
References CON_VIRTUAL, Parma_Polyhedra_Library::Matrix::num_columns(), and Parma_Polyhedra_Library::Matrix::num_rows().
Referenced by conversion(), and OK().
00038 { 00039 const dimension_type num_columns = sys.num_columns() - 1; 00040 00041 // Check for easy square failure case. 00042 if (sys.num_rows() > num_columns) 00043 return false; 00044 00045 // Check triangularity. 00046 00047 dimension_type row = 0; 00048 for (dimension_type dim = num_columns; dim-- > 0; ) { 00049 if (dim_kinds[dim] == CON_VIRTUAL) 00050 continue; 00051 const Congruence& cg = sys[row]; 00052 ++row; 00053 // Check diagonal. 00054 if (cg[dim] <= 0) 00055 return false; 00056 // Check elements following diagonal. 00057 dimension_type col = dim; 00058 while (++col < num_columns) 00059 if (cg[col] != 0) 00060 return false; 00061 } 00062 00063 // Check squareness. 00064 return row == sys.num_rows(); 00065 }
bool Parma_Polyhedra_Library::Grid::upper_triangular | ( | const Grid_Generator_System & | sys, | |
const Dimension_Kinds & | dim_kinds | |||
) | [static, private] |
If sys
is upper triangular return true
, else return false
.
Definition at line 74 of file Grid_conversion.cc.
References GEN_VIRTUAL, Parma_Polyhedra_Library::Grid_Generator_System::num_rows(), and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().
Referenced by conversion(), and OK().
00075 { 00076 dimension_type num_columns = sys.space_dimension() + 1; 00077 dimension_type row = sys.num_rows(); 00078 00079 // Check for easy square fail case. 00080 if (row > num_columns) 00081 return false; 00082 00083 // Check triangularity. 00084 while (num_columns > 0) { 00085 --num_columns; 00086 if (dim_kinds[num_columns] == GEN_VIRTUAL) 00087 continue; 00088 const Grid_Generator& gen = sys[--row]; 00089 // Check diagonal. 00090 if (gen[num_columns] <= 0) 00091 return false; 00092 // Check elements preceding diagonal. 00093 dimension_type col = num_columns; 00094 while (col-- > 0) 00095 if (gen[col] != 0) 00096 return false; 00097 } 00098 00099 // Check for squareness. 00100 return num_columns == row; 00101 }
bool Parma_Polyhedra_Library::Grid::rows_are_zero | ( | M & | system, | |
dimension_type | first, | |||
dimension_type | last, | |||
dimension_type | row_size | |||
) | [inline, static, private] |
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 236 of file Grid_simplify.cc.
00237 { 00238 while (first <= last) { 00239 const R& row = system[first++]; 00240 for (dimension_type col = 0; col < row_size; ++col) 00241 if (row[col] != 0) 00242 return false; 00243 } 00244 return true; 00245 }
void Parma_Polyhedra_Library::Grid::throw_runtime_error | ( | const char * | method | ) | const [protected] |
Definition at line 616 of file Grid_nonpublic.cc.
00616 { 00617 std::ostringstream s; 00618 s << "PPL::Grid::" << method << "." << std::endl; 00619 throw std::runtime_error(s.str()); 00620 }
void Parma_Polyhedra_Library::Grid::throw_invalid_argument | ( | const char * | method, | |
const char * | reason | |||
) | const [protected] |
Definition at line 623 of file Grid_nonpublic.cc.
Referenced by affine_image(), affine_preimage(), bounded_affine_image(), bounded_affine_preimage(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), Grid(), and map_space_dimensions().
00624 { 00625 std::ostringstream s; 00626 s << "PPL::Grid::" << method << ":" << std::endl 00627 << reason << "."; 00628 throw std::invalid_argument(s.str()); 00629 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | other_name, | |||
dimension_type | other_dim | |||
) | const [protected] |
Definition at line 632 of file Grid_nonpublic.cc.
References space_dimension().
Referenced by add_congruence(), add_congruences(), add_constraint(), add_constraints(), add_grid_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), affine_image(), affine_preimage(), bounded_affine_image(), bounded_affine_preimage(), bounds(), congruence_widening_assign(), constrains(), contains(), difference_assign(), expand_space_dimension(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), generator_widening_assign(), get_covering_box(), intersection_assign(), is_disjoint_from(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), refine_with_constraint(), refine_with_constraints(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), throw_dimension_incompatible(), time_elapse_assign(), unconstrain(), upper_bound_assign(), upper_bound_assign_if_exact(), and widening_assign().
00634 { 00635 std::ostringstream s; 00636 s << "PPL::Grid::" << method << ":\n" 00637 << "this->space_dimension() == " << space_dimension() << ", " 00638 << other_name << ".space_dimension() == " << other_dim << "."; 00639 throw std::invalid_argument(s.str()); 00640 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | gr_name, | |||
const Grid & | gr | |||
) | const [protected] |
Definition at line 643 of file Grid_nonpublic.cc.
References space_dimension(), and throw_dimension_incompatible().
00645 { 00646 throw_dimension_incompatible(method, gr_name, gr.space_dimension()); 00647 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | e_name, | |||
const Linear_Expression & | e | |||
) | const [protected] |
Definition at line 650 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Linear_Expression::space_dimension(), and throw_dimension_incompatible().
00652 { 00653 throw_dimension_incompatible(method, e_name, e.space_dimension()); 00654 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | cg_name, | |||
const Congruence & | cg | |||
) | const [protected] |
Definition at line 657 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Congruence::space_dimension(), and throw_dimension_incompatible().
00659 { 00660 throw_dimension_incompatible(method, cg_name, cg.space_dimension()); 00661 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | c_name, | |||
const Constraint & | c | |||
) | const [protected] |
Definition at line 664 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Constraint::space_dimension(), and throw_dimension_incompatible().
00666 { 00667 throw_dimension_incompatible(method, c_name, c.space_dimension()); 00668 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | g_name, | |||
const Grid_Generator & | g | |||
) | const [protected] |
Definition at line 671 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Grid_Generator::space_dimension(), and throw_dimension_incompatible().
00673 { 00674 throw_dimension_incompatible(method, g_name, g.space_dimension()); 00675 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | g_name, | |||
const Generator & | g | |||
) | const [protected] |
Definition at line 678 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Generator::space_dimension(), and throw_dimension_incompatible().
00680 { 00681 throw_dimension_incompatible(method, g_name, g.space_dimension()); 00682 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | cgs_name, | |||
const Congruence_System & | cgs | |||
) | const [protected] |
Definition at line 685 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Congruence_System::space_dimension(), and throw_dimension_incompatible().
00687 { 00688 throw_dimension_incompatible(method, cgs_name, cgs.space_dimension()); 00689 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | cs_name, | |||
const Constraint_System & | cs | |||
) | const [protected] |
Definition at line 692 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
00694 { 00695 throw_dimension_incompatible(method, cs_name, cs.space_dimension()); 00696 }
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 699 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and throw_dimension_incompatible().
00701 { 00702 throw_dimension_incompatible(method, gs_name, gs.space_dimension()); 00703 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | var_name, | |||
Variable | var | |||
) | const [protected] |
Definition at line 706 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Variable::space_dimension(), and space_dimension().
00708 { 00709 std::ostringstream s; 00710 s << "PPL::Grid::" << method << ":" << std::endl 00711 << "this->space_dimension() == " << space_dimension() << ", " 00712 << var_name << ".space_dimension() == " << var.space_dimension() << "."; 00713 throw std::invalid_argument(s.str()); 00714 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
dimension_type | required_space_dim | |||
) | const [protected] |
Definition at line 718 of file Grid_nonpublic.cc.
References space_dimension().
00719 { 00720 std::ostringstream s; 00721 s << "PPL::Grid::" << method << ":" << std::endl 00722 << "this->space_dimension() == " << space_dimension() 00723 << ", required space dimension == " << required_space_dim << "."; 00724 throw std::invalid_argument(s.str()); 00725 }
void Parma_Polyhedra_Library::Grid::throw_space_dimension_overflow | ( | const char * | method, | |
const char * | reason | |||
) | [static, protected] |
Definition at line 728 of file Grid_nonpublic.cc.
Referenced by add_space_dimensions_and_embed(), add_space_dimensions_and_project(), concatenate_assign(), expand_space_dimension(), and Grid().
00729 { 00730 std::ostringstream s; 00731 s << "PPL::Grid::" << method << ":" << std::endl 00732 << reason << "."; 00733 throw std::length_error(s.str()); 00734 }
void Parma_Polyhedra_Library::Grid::throw_invalid_constraint | ( | const char * | method, | |
const char * | c_name | |||
) | const [protected] |
Definition at line 737 of file Grid_nonpublic.cc.
Referenced by add_constraint_no_check(), and Grid().
00738 { 00739 std::ostringstream s; 00740 s << "PPL::Grid::" << method << ":" << std::endl 00741 << c_name << " is not an equality constraint."; 00742 throw std::invalid_argument(s.str()); 00743 }
void Parma_Polyhedra_Library::Grid::throw_invalid_constraints | ( | const char * | method, | |
const char * | cs_name | |||
) | const [protected] |
Definition at line 746 of file Grid_nonpublic.cc.
Referenced by Grid().
00747 { 00748 std::ostringstream s; 00749 s << "PPL::Grid::" << method << ":" << std::endl 00750 << "the constraint system " << cs_name 00751 << " contains inequalities."; 00752 throw std::invalid_argument(s.str()); 00753 }
void Parma_Polyhedra_Library::Grid::throw_invalid_generator | ( | const char * | method, | |
const char * | g_name | |||
) | const [protected] |
Definition at line 756 of file Grid_nonpublic.cc.
Referenced by add_grid_generator().
00757 { 00758 std::ostringstream s; 00759 s << "PPL::Grid::" << method << ":" << std::endl 00760 << "*this is an empty grid and " 00761 << g_name << " is not a point."; 00762 throw std::invalid_argument(s.str()); 00763 }
void Parma_Polyhedra_Library::Grid::throw_invalid_generators | ( | const char * | method, | |
const char * | gs_name | |||
) | const [protected] |
Definition at line 766 of file Grid_nonpublic.cc.
Referenced by add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), and construct().
00767 { 00768 std::ostringstream s; 00769 s << "PPL::Grid::" << method << ":" << std::endl 00770 << "*this is an empty grid and" << std::endl 00771 << "the non-empty generator system " << gs_name << " contains no points."; 00772 throw std::invalid_argument(s.str()); 00773 }
friend class Parma_Polyhedra_Library::Grid_Certificate [friend] |
Definition at line 2103 of file Grid.defs.hh.
friend class Parma_Polyhedra_Library::Box [friend] |
Definition at line 2105 of file Grid.defs.hh.
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.
Definition at line 2410 of file Grid_public.cc.
02410 { 02411 if (x.space_dim != y.space_dim) 02412 return false; 02413 02414 if (x.marked_empty()) 02415 return y.is_empty(); 02416 if (y.marked_empty()) 02417 return x.is_empty(); 02418 if (x.space_dim == 0) 02419 return true; 02420 02421 switch (x.quick_equivalence_test(y)) { 02422 case Grid::TVB_TRUE: 02423 return true; 02424 02425 case Grid::TVB_FALSE: 02426 return false; 02427 02428 default: 02429 if (x.is_included_in(y)) { 02430 if (x.marked_empty()) 02431 return y.is_empty(); 02432 return y.is_included_in(x); 02433 } 02434 return false; 02435 } 02436 }
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.
Definition at line 2574 of file Grid_public.cc.
References is_empty(), is_universe(), and minimized_congruences().
02574 { 02575 if (gr.is_empty()) 02576 s << "false"; 02577 else if (gr.is_universe()) 02578 s << "true"; 02579 else 02580 s << gr.minimized_congruences(); 02581 return s; 02582 }
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.
Definition at line 379 of file Grid.inlines.hh.
void swap | ( | Parma_Polyhedra_Library::Grid & | x, | |
Parma_Polyhedra_Library::Grid & | y | |||
) | [related] |
Specializes std::swap
.
Definition at line 400 of file Grid.inlines.hh.
References swap().
00401 { 00402 x.swap(y); 00403 }
The system of congruences.
Definition at line 2149 of file Grid.defs.hh.
Referenced by add_congruence_no_check(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_dimension(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), concatenate_assign(), congruence_widening_assign(), congruences(), constrains(), construct(), external_memory_in_bytes(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), intersection_assign(), is_empty(), is_included_in(), is_universe(), map_space_dimensions(), minimize(), minimized_congruences(), OK(), operator=(), quick_equivalence_test(), relation_with(), remove_higher_space_dimensions(), select_wider_congruences(), set_empty(), set_zero_dim_univ(), swap(), and update_generators().
The system of generators.
Definition at line 2152 of file Grid.defs.hh.
Referenced by add_grid_generator(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_dimension(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), bounds(), Parma_Polyhedra_Library::Box< ITV >::Box(), constrains(), construct(), external_memory_in_bytes(), generalized_affine_image(), generalized_affine_preimage(), generator_widening_assign(), get_covering_box(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), grid_generators(), is_bounded(), is_discrete(), map_space_dimensions(), max_min(), minimize(), minimized_grid_generators(), OK(), operator=(), quick_equivalence_test(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), select_wider_generators(), set_empty(), set_zero_dim_univ(), swap(), time_elapse_assign(), unconstrain(), update_congruences(), update_generators(), and upper_bound_assign().
Status Parma_Polyhedra_Library::Grid::status [private] |
The status flags to keep track of the grid's internal state.
Definition at line 2325 of file Grid.defs.hh.
Referenced by add_recycled_congruences_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), ascii_dump(), ascii_load(), clear_congruences_minimized(), clear_congruences_up_to_date(), clear_empty(), clear_generators_minimized(), clear_generators_up_to_date(), congruences_are_minimized(), congruences_are_up_to_date(), construct(), generators_are_minimized(), generators_are_up_to_date(), Grid(), marked_empty(), OK(), operator=(), set_congruences_minimized(), set_congruences_up_to_date(), set_empty(), set_generators_minimized(), set_generators_up_to_date(), set_zero_dim_univ(), and swap().
The number of dimensions of the enclosing vector space.
Definition at line 2328 of file Grid.defs.hh.
Referenced by add_congruence(), add_congruence_no_check(), add_congruences(), add_constraint(), add_constraint_no_check(), add_constraints(), add_grid_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_grid_generators(), add_recycled_grid_generators_and_minimize(), add_space_dimensions(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_dimension(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), bounded_affine_image(), bounded_affine_preimage(), bounds(), concatenate_assign(), congruence_widening_assign(), congruences(), constrains(), construct(), contains(), contains_integer_point(), difference_assign(), expand_space_dimension(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), generator_widening_assign(), get_covering_box(), Grid(), grid_generators(), intersection_assign(), is_bounded(), is_discrete(), is_disjoint_from(), is_empty(), is_included_in(), is_universe(), limited_congruence_extrapolation_assign(), limited_extrapolation_assign(), limited_generator_extrapolation_assign(), map_space_dimensions(), max_min(), minimize(), minimized_grid_generators(), OK(), operator=(), quick_equivalence_test(), refine_no_check(), refine_with_constraint(), refine_with_constraints(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), select_wider_congruences(), select_wider_generators(), set_empty(), set_zero_dim_univ(), space_dimension(), swap(), time_elapse_assign(), unconstrain(), update_congruences(), update_generators(), upper_bound_assign(), upper_bound_assign_if_exact(), and widening_assign().
Definition at line 2347 of file Grid.defs.hh.
Referenced by add_space_dimensions(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), ascii_dump(), ascii_load(), congruence_widening_assign(), construct(), generator_widening_assign(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_empty(), max_min(), minimize(), minimized_congruences(), minimized_grid_generators(), OK(), operator=(), remove_higher_space_dimensions(), select_wider_congruences(), select_wider_generators(), swap(), and update_generators().