#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 *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, const Variable var) const |
void | throw_dimension_incompatible (const char *method, dimension_type required_space_dim) 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 Member Functions | |
Grid (dimension_type num_dimensions=0, const 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) | |
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) | |
Builds a grid, recycling a system of constraints. | |
Grid (const Grid_Generator_System &const_gs) | |
Builds a grid, copying a system of generators. | |
Grid (Grid_Generator_System &gs) | |
Builds a grid, recycling a system of generators. | |
template<typename Box> | |
Grid (const Box &box, From_Bounding_Box dummy) | |
Builds a grid out of a generic, interval-based bounding box. | |
template<typename Box> | |
Grid (const Box &box, From_Covering_Box dummy) | |
Builds a grid out of a generic, interval-based covering box. | |
Grid (const Grid &y) | |
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 . | |
const Congruence_System & | congruences () const |
Returns the system of congruences. | |
const Congruence_System & | minimized_congruences () const |
Returns the system of congruences in reduced form. | |
const Grid_Generator_System & | generators () const |
Returns the system of generators. | |
const Grid_Generator_System & | minimized_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 . | |
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 | 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, Grid_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, Grid_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 Box> | |
void | shrink_bounding_box (Box &box) const |
Uses *this to shrink a generic, interval-based bounding box. | |
template<typename Box> | |
void | get_covering_box (Box &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 . | |
void | add_congruence (const Constraint &c) |
Adds constraint c 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. | |
bool | add_congruence_and_minimize (const Constraint &c) |
Adds a copy of constraint c to *this , reducing the result. | |
void | add_generator (const Grid_Generator &g) |
Adds a copy of generator g to the system of generators of this . | |
bool | add_generator_and_minimize (const Grid_Generator &g) |
Adds a copy of 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_congruences (const Constraint_System &cs) |
Adds a copy of each equality constraint in cs to *this . | |
void | add_recycled_congruences (Congruence_System &cgs) |
Adds the congruences in cgs to *this. | |
void | add_recycled_congruences (Constraint_System &cs) |
Adds the equality constraints in cs 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_congruences_and_minimize (const Constraint_System &cs) |
Adds a copy of each equality constraint in cs to *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. | |
bool | add_recycled_congruences_and_minimize (Constraint_System &cs) |
Adds the equalities in cs to *this , reducing the result. | |
void | add_constraint (const Constraint &c) |
Adds constraint c to *this . | |
bool | add_constraint_and_minimize (const Constraint &c) |
Adds constraint c to *this , reducing the result. | |
void | add_constraints (const Constraint_System &cs) |
Adds copies of the equality constraints in cs to *this . | |
bool | add_constraints_and_minimize (const Constraint_System &cs) |
Adds copies of the equality constraints in cs to *this , reducing the result. | |
void | add_recycled_constraints (Constraint_System &cs) |
Adds the equality constraints in cs to *this . | |
bool | add_recycled_constraints_and_minimize (Constraint_System &cs) |
void | add_generators (const Grid_Generator_System &gs) |
Adds a copy of the generators in gs to the system of generators of *this . | |
void | add_recycled_generators (Grid_Generator_System &gs) |
Adds the generators in gs to the system of generators of this . | |
bool | add_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_generators_and_minimize (Grid_Generator_System &gs) |
Adds the generators in gs to the system of generators of this , reducing the result. | |
void | intersection_assign (const Grid &y) |
Assigns to *this the intersection of *this and y . The result is not guaranteed to be reduced. | |
bool | intersection_assign_and_minimize (const Grid &y) |
Assigns to *this the intersection of *this and y , reducing the result. | |
void | join_assign (const Grid &y) |
Assigns to *this the join of *this and y . | |
bool | join_assign_and_minimize (const Grid &y) |
Assigns to *this the join of *this and y , reducing the result. | |
void | upper_bound_assign (const Grid &y) |
Same as join_assign(y). | |
bool | join_assign_if_exact (const Grid &y) |
If the join of *this and y is exact it is assigned to this and true is returned, otherwise false is returned. | |
bool | upper_bound_assign_if_exact (const Grid &y) |
Same as join_assign_if_exact(y). | |
void | grid_difference_assign (const Grid &y) |
Assigns to *this the grid-difference of *this and y . | |
void | difference_assign (const Grid &y) |
Same as grid_difference_assign(y). | |
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, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one(), Coefficient_traits::const_reference modulus=Coefficient_one()) |
Assigns to *this the image of *this with respect to the generalized affine relation ![]() | |
void | generalized_affine_preimage (Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one(), Coefficient_traits::const_reference modulus=Coefficient_one()) |
Assigns to *this the preimage of *this with respect to the generalized affine relation ![]() | |
void | generalized_affine_image (const Linear_Expression &lhs, const Linear_Expression &rhs, Coefficient_traits::const_reference modulus=Coefficient_one()) |
Assigns to *this the image of *this with respect to the generalized affine relation ![]() | |
void | generalized_affine_preimage (const Linear_Expression &lhs, const Linear_Expression &rhs, Coefficient_traits::const_reference modulus=Coefficient_one()) |
Assigns to *this the preimage of *this with respect to the generalized 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 | widening_assign (const Grid &y, unsigned *tp=NULL) |
Assigns to *this the result of computing the Grid widening between *this and y . | |
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) and sets *this accordingly. | |
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 . | |
Static Public Member Functions | |
static dimension_type | max_space_dimension () |
Returns the maximum space dimension all kinds of Grid can handle. | |
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 (const Congruence_System &cgs) |
Builds a grid from a system of congruences. | |
void | construct (const Grid_Generator_System &gs) |
Builds a grid from a system of 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, char *method_call, Coefficient &ext_n, Coefficient &ext_d, bool &included, Grid_Generator *point=NULL) const |
Maximizes or minimizes expr subject to *this . | |
void | add_space_dimensions (Congruence_System &cgs, Grid_Generator_System &gs, const dimension_type dims) |
Adds new space dimensions to the given systems. | |
void | add_space_dimensions (Grid_Generator_System &gs, Congruence_System &cgs, const 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 parameters 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 | |
bool | 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 . | |
Static Private Member Functions | |
Minimization-related Static Member Functions | |
static Coefficient | normalize_divisors (Grid_Generator_System &sys, Coefficient_traits::const_reference divisor=Coefficient_one(), Grid_Generator *first_point=NULL) |
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, 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, Grid_Generator &pivot, dimension_type col, Grid_Generator_System &sys) |
Reduce row using pivot . | |
static void | reduce_congruence_with_equality (Congruence &row, 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, 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, const dimension_type num_rows, const 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, const dimension_type num_rows, const 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 |
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 the 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. Most operators on grids are provided with two implementations: one of these, denoted <operator-name>_and_minimize
, also enforces the minimization of the representations, and returns the boolean value false
whenever the resulting grid turns out to be empty.
A key attributes 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_generator(grid_point(0*x + 0*y)); gr.add_generator(grid_point(4*x + 0*y)); gr.add_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_generator(grid_point(0*x + 0*y)); gr.add_generator(grid_point(4*x + 0*y)); gr.add_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 362 of file Grid.defs.hh.
typedef std::vector<Dimension_Kind> Parma_Polyhedra_Library::Grid::Dimension_Kinds [private] |
Definition at line 2142 of file Grid.defs.hh.
enum Parma_Polyhedra_Library::Grid::Dimension_Kind [private] |
Definition at line 2133 of file Grid.defs.hh.
enum Parma_Polyhedra_Library::Grid::Three_Valued_Boolean [private] |
Parma_Polyhedra_Library::Grid::Grid | ( | dimension_type | num_dimensions = 0 , |
|
const Degenerate_Element | kind = UNIVERSE | |||
) | [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 34 of file Grid_public.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().
00036 : con_sys(), 00037 gen_sys(num_dimensions > max_space_dimension() 00038 ? (throw_space_dimension_overflow("Grid(n, k)", 00039 "n exceeds the maximum " 00040 "allowed space dimension"), 00041 0) 00042 : num_dimensions) { 00043 00044 space_dim = num_dimensions; 00045 00046 if (kind == EMPTY) { 00047 // Set emptiness directly instead of with set_empty, as gen_sys is 00048 // already correctly initialized. 00049 00050 status.set_empty(); 00051 00052 // Extend the zero dim false congruence system to the appropriate 00053 // dimension and then store it in `con_sys'. 00054 Congruence_System cgs(Congruence::zero_dim_false()); 00055 cgs.increase_space_dimension(space_dim); 00056 const_cast<Congruence_System&>(con_sys).swap(cgs); 00057 00058 assert(OK()); 00059 return; 00060 } 00061 00062 if (num_dimensions > 0) { 00063 con_sys.increase_space_dimension(num_dimensions); 00064 00065 // Initialise both systems to universe representations. 00066 00067 set_congruences_minimized(); 00068 set_generators_minimized(); 00069 dim_kinds.resize(num_dimensions + 1); 00070 00071 // Extend the zero dim integrality congruence system to the 00072 // appropriate dimension and then store it in `con_sys'. 00073 Congruence_System cgs(Congruence::zero_dim_integrality()); 00074 cgs.increase_space_dimension(space_dim); 00075 cgs[0][0] = 1; // Recover minimal form after cgs(zdi) normalization. 00076 con_sys.swap(cgs); 00077 00078 dim_kinds[0] = PROPER_CONGRUENCE /* a.k.a. PARAMETER */; 00079 00080 // Trivially true point. 00081 gen_sys.insert(grid_point(0*(Variable(0)))); 00082 00083 // A line for each dimension. 00084 dimension_type dim = 0; 00085 while (dim < num_dimensions) { 00086 gen_sys.insert(grid_line(Variable(dim++))); 00087 dim_kinds[dim] = CON_VIRTUAL /* a.k.a. LINE */; 00088 } 00089 } 00090 else 00091 set_zero_dim_univ(); 00092 00093 assert(OK()); 00094 }
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 50 of file Grid.inlines.hh.
References construct(), max_space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), and throw_space_dimension_overflow().
00050 { 00051 if (ccgs.space_dimension() > max_space_dimension()) 00052 throw_space_dimension_overflow("Grid(ccgs)", 00053 "the space dimension of ccgs " 00054 "exceeds the maximum allowed " 00055 "space dimension"); 00056 construct(ccgs); 00057 }
Parma_Polyhedra_Library::Grid::Grid | ( | Congruence_System & | cgs | ) | [inline, explicit] |
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 will be recycled to build the grid. |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 60 of file Grid.inlines.hh.
References construct(), max_space_dimension(), Parma_Polyhedra_Library::Congruence_System::space_dimension(), and throw_space_dimension_overflow().
00060 { 00061 if (cgs.space_dimension() > max_space_dimension()) 00062 throw_space_dimension_overflow("Grid(cgs)", 00063 "the space dimension of cgs " 00064 "exceeds the maximum allowed " 00065 "space dimension"); 00066 construct(cgs); 00067 }
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::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 118 of file Grid_public.cc.
References Parma_Polyhedra_Library::Constraint_System::begin(), construct(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Congruence_System::insert(), max_space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_space_dimension_overflow().
00118 { 00119 if (ccs.space_dimension() > max_space_dimension()) 00120 throw_space_dimension_overflow("Grid(ccs)", 00121 "the space dimension of ccs " 00122 "exceeds the maximum allowed " 00123 "space dimension"); 00124 Congruence_System cgs; 00125 cgs.insert(0*Variable(ccs.space_dimension() - 1) %= 1); 00126 for (Constraint_System::const_iterator i = ccs.begin(), 00127 ccs_end = ccs.end(); i != ccs_end; ++i) 00128 if (i->is_equality()) 00129 cgs.insert(*i); 00130 construct(cgs); 00131 }
Parma_Polyhedra_Library::Grid::Grid | ( | Constraint_System & | cs | ) | [explicit] |
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. |
std::length_error | Thrown if num_dimensions exceeds the maximum allowed space dimension. |
Definition at line 133 of file Grid_public.cc.
References Parma_Polyhedra_Library::Constraint_System::begin(), construct(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Congruence_System::insert(), max_space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_space_dimension_overflow().
00133 { 00134 if (cs.space_dimension() > max_space_dimension()) 00135 throw_space_dimension_overflow("Grid(cs)", 00136 "the space dimension of cs " 00137 "exceeds the maximum allowed " 00138 "space dimension"); 00139 // FIXME: Adapt and use cs instead of using a copy. 00140 Congruence_System cgs; 00141 cgs.insert(0*Variable(cs.space_dimension() - 1) %= 1); 00142 for (Constraint_System::const_iterator i = cs.begin(), 00143 cs_end = cs.end(); i != cs_end; ++i) 00144 if (i->is_equality()) 00145 cgs.insert(*i); 00146 construct(cgs); 00147 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Grid_Generator_System & | const_gs | ) | [inline, explicit] |
Builds a grid, copying a system of 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 70 of file Grid.inlines.hh.
References construct(), max_space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and throw_space_dimension_overflow().
00070 { 00071 if (gs.space_dimension() > max_space_dimension()) 00072 throw_space_dimension_overflow("Grid(gs)", 00073 "the space dimension of gs " 00074 "exceeds the maximum allowed " 00075 "space dimension"); 00076 construct(gs); 00077 }
Parma_Polyhedra_Library::Grid::Grid | ( | Grid_Generator_System & | gs | ) | [inline, explicit] |
Builds a grid, recycling a system of generators.
The grid inherits the space dimension of the generator system.
gs | The system of generators defining the grid. Its data-structures will be recycled to build 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 80 of file Grid.inlines.hh.
References construct(), max_space_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and throw_space_dimension_overflow().
00080 { 00081 if (gs.space_dimension() > max_space_dimension()) 00082 throw_space_dimension_overflow("Grid(gs)", 00083 "the space dimension of gs " 00084 "exceeds the maximum allowed " 00085 "space dimension"); 00086 construct(gs); 00087 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Box & | box, | |
From_Bounding_Box | dummy | |||
) | [inline] |
Builds a grid out of a generic, interval-based bounding box.
box | The bounding box representing the grid to be built. The box can contain only point and universe intervals; | |
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 at least one interval with: a topologically open bound, a single bound, or two bounds which have space between them. |
dimension_type space_dimension() const
bool is_empty() const
true
if and only if the bounding 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 35 of file Grid.templates.hh.
References con_sys, gen_sys, Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), Parma_Polyhedra_Library::Congruence_System::insert(), max_space_dimension(), OK(), set_congruences_up_to_date(), set_empty(), Parma_Polyhedra_Library::Grid_Generator_System::set_sorted(), set_zero_dim_univ(), space_dim, TEMP_INTEGER, throw_invalid_argument(), throw_space_dimension_overflow(), and Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows().
00036 : con_sys(), 00037 gen_sys(NECESSARILY_CLOSED) { 00038 used(dummy); 00039 00040 if (box.space_dimension() > max_space_dimension()) 00041 throw_space_dimension_overflow("Grid(box, from_bounding_box)", 00042 "the space dimension of box " 00043 "exceeds the maximum allowed " 00044 "space dimension"); 00045 00046 space_dim = box.space_dimension(); 00047 00048 TEMP_INTEGER(l_n); 00049 TEMP_INTEGER(l_d); 00050 00051 // Check that all bounds are closed. This must be done before the 00052 // empty check below, in case an open bound makes the grid empty. 00053 for (dimension_type k = space_dim; k-- > 0; ) { 00054 bool closed; 00055 // FIXME: Perhaps introduce box::is_bounded_and_closed. 00056 if (box.get_lower_bound(k, closed, l_n, l_d) && !closed) 00057 throw_invalid_argument("Grid(box, from_bounding_box)", "box"); 00058 if (box.get_upper_bound(k, closed, l_n, l_d) && !closed) 00059 throw_invalid_argument("Grid(box, from_bounding_box)", "box"); 00060 } 00061 00062 if (box.is_empty()) { 00063 // Empty grid. 00064 set_empty(); 00065 assert(OK()); 00066 return; 00067 } 00068 00069 if (space_dim == 0) 00070 set_zero_dim_univ(); 00071 else { 00072 // Initialize the space dimension as indicated by the box. 00073 con_sys.increase_space_dimension(space_dim); 00074 // Add congruences according to `box'. 00075 TEMP_INTEGER(u_n); 00076 TEMP_INTEGER(u_d); 00077 for (dimension_type k = space_dim; k-- > 0; ) { 00078 bool closed; 00079 // TODO: Consider producing the system(s) in minimized form. 00080 // FIXME: Also create the generator system. 00081 if (box.get_lower_bound(k, closed, l_n, l_d)) { 00082 if (box.get_upper_bound(k, closed, u_n, u_d)) 00083 if (l_n * u_d == u_n * l_d) { 00084 // A point interval sets dimension k of every point to a 00085 // single value. 00086 con_sys.insert(l_d * Variable(k) == l_n); 00087 continue; 00088 } 00089 // The only valid bounded interval is a point interval. 00090 throw_invalid_argument("Grid(box, from_bounding_box)", "box"); 00091 } 00092 else if (box.get_upper_bound(k, closed, u_n, u_d)) 00093 // An interval can only be a point or the universe. 00094 throw_invalid_argument("Grid(box, from_covering_box)", 00095 "box"); 00096 // A universe interval allows any value in dimension k. 00097 } 00098 set_congruences_up_to_date(); 00099 gen_sys.unset_pending_rows(); 00100 gen_sys.set_sorted(false); 00101 } 00102 00103 assert(OK()); 00104 }
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 107 of file Grid.templates.hh.
References con_sys, Parma_Polyhedra_Library::gcd_assign(), gen_sys, Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), Parma_Polyhedra_Library::Congruence_System::insert(), max_space_dimension(), OK(), set_congruences_up_to_date(), set_empty(), Parma_Polyhedra_Library::Grid_Generator_System::set_sorted(), set_zero_dim_univ(), space_dim, TEMP_INTEGER, throw_invalid_argument(), throw_space_dimension_overflow(), and Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows().
00108 : con_sys(), 00109 gen_sys(NECESSARILY_CLOSED) { 00110 used(dummy); 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 must be done before the 00124 // empty check below, in case an open bound makes the grid empty. 00125 for (dimension_type k = space_dim; k-- > 0; ) { 00126 bool closed; 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 for (dimension_type k = space_dim; k-- > 0; ) { 00151 bool closed; 00152 // TODO: Consider producing the system(s) in minimized form. 00153 // FIXME: Also create the generator system. 00154 if (box.get_lower_bound(k, closed, l_n, l_d)) { 00155 if (box.get_upper_bound(k, closed, u_n, u_d)) { 00156 if (l_n * u_d == u_n * l_d) 00157 // A point interval allows any point along the dimension 00158 // k axis. 00159 continue; 00160 gcd_assign(d, l_d, u_d); 00161 // `d' is the gcd of the divisors. 00162 l_n *= (u_d / d); 00163 d = l_d / d; 00164 // `d' is now the smallest integer expression of the size 00165 // of l_d relative to u_d. `d * u_d' is the lcm of the 00166 // divisors. 00167 con_sys.insert((d * u_d * Variable(k) %= l_n) / ((u_n * d) - l_n)); 00168 } 00169 else 00170 // An interval bounded only from below produces an 00171 // equality. 00172 con_sys.insert(l_d * Variable(k) == l_n); 00173 } 00174 else 00175 if (box.get_upper_bound(k, closed, u_n, u_d)) 00176 // An interval bounded only from above produces an equality. 00177 con_sys.insert(u_d * Variable(k) == u_n); 00178 else { 00179 // Any universe interval produces an empty grid. 00180 set_empty(); 00181 assert(OK()); 00182 return; 00183 } 00184 } 00185 set_congruences_up_to_date(); 00186 gen_sys.set_sorted(false); 00187 gen_sys.unset_pending_rows(); 00188 } 00189 00190 assert(OK()); 00191 }
Parma_Polyhedra_Library::Grid::Grid | ( | const Grid & | y | ) |
Ordinary copy-constructor.
Definition at line 96 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.
00097 : con_sys(), 00098 gen_sys(), 00099 status(y.status), 00100 space_dim(y.space_dim), 00101 dim_kinds(y.dim_kinds) { 00102 if (space_dim == 0) { 00103 con_sys = y.con_sys; 00104 gen_sys = y.gen_sys; 00105 } 00106 else { 00107 if (y.congruences_are_up_to_date()) 00108 con_sys = y.con_sys; 00109 else 00110 con_sys.increase_space_dimension(space_dim); 00111 if (y.generators_are_up_to_date()) 00112 gen_sys = y.gen_sys; 00113 else 00114 gen_sys = Grid_Generator_System(y.space_dim); 00115 } 00116 }
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 33 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().
00033 { 00034 using std::min; 00035 // One dimension is reserved to have a value of type dimension_type 00036 // that does not represent a legal dimension. 00037 return min(std::numeric_limits<dimension_type>::max() - 1, 00038 min(Congruence_System::max_space_dimension(), 00039 Grid_Generator_System::max_space_dimension() 00040 ) 00041 ); 00042 }
The assignment operator. (*this
and y
can be dimension-incompatible.).
Definition at line 150 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.
00150 { 00151 space_dim = y.space_dim; 00152 dim_kinds = y.dim_kinds; 00153 if (y.marked_empty()) 00154 set_empty(); 00155 else if (space_dim == 0) 00156 set_zero_dim_univ(); 00157 else { 00158 status = y.status; 00159 if (y.congruences_are_up_to_date()) 00160 con_sys = y.con_sys; 00161 if (y.generators_are_up_to_date()) 00162 gen_sys = y.gen_sys; 00163 } 00164 return *this; 00165 }
dimension_type Parma_Polyhedra_Library::Grid::space_dimension | ( | ) | const [inline] |
Returns the dimension of the vector space enclosing *this
.
Definition at line 99 of file Grid.inlines.hh.
References space_dim.
Referenced by add_space_dimensions_and_embed(), add_space_dimensions_and_project(), concatenate_assign(), expand_space_dimension(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), and throw_dimension_incompatible().
00099 { 00100 return space_dim; 00101 }
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 168 of file Grid_public.cc.
References is_empty(), minimized_congruences(), Parma_Polyhedra_Library::Matrix::num_rows(), and space_dim.
00168 { 00169 if (space_dim == 0 || is_empty()) 00170 return 0; 00171 00172 // FIXME: Use the minimized congruence system, or the generator 00173 // system in any form. 00174 00175 const Congruence_System& cgs = minimized_congruences(); 00176 dimension_type d = space_dim; 00177 for (dimension_type i = cgs.num_rows(); i-- > 0; ) 00178 if (cgs[i].is_equality()) 00179 --d; 00180 return d; 00181 }
const PPL::Congruence_System & Parma_Polyhedra_Library::Grid::congruences | ( | ) | const |
Returns the system of congruences.
Definition at line 184 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 concatenate_assign(), expand_space_dimension(), grid_difference_assign(), and minimized_congruences().
00184 { 00185 if (marked_empty()) 00186 return con_sys; 00187 00188 if (space_dim == 0) { 00189 // Zero-dimensional universe. 00190 assert(con_sys.num_columns() == 2 && con_sys.num_rows() == 0); 00191 return con_sys; 00192 } 00193 00194 congruences_are_up_to_date() || update_congruences(); 00195 00196 return con_sys; 00197 }
const PPL::Congruence_System & Parma_Polyhedra_Library::Grid::minimized_congruences | ( | ) | const |
Returns the system of congruences in reduced form.
Definition at line 200 of file Grid_public.cc.
References con_sys, congruences(), congruences_are_minimized(), congruences_are_up_to_date(), dim_kinds, Parma_Polyhedra_Library::Congruence_System::increase_space_dimension(), marked_empty(), set_congruences_minimized(), set_empty(), simplify(), space_dim, swap(), and Parma_Polyhedra_Library::Congruence::zero_dim_integrality().
Referenced by affine_dimension(), and operator<<().
00200 { 00201 if (space_dim == 0) { 00202 if (!marked_empty()) { 00203 // Ensure the congruences are minimal by extending a zero dim 00204 // universe congruence system to the appropriate dimension and 00205 // then storing it in `con_sys'. 00206 Congruence_System cgs(Congruence::zero_dim_integrality()); 00207 cgs.increase_space_dimension(space_dim); 00208 cgs[0][0] = 1; // Recover minimal form after cgs(zdi) normalization. 00209 const_cast<Congruence_System&>(con_sys).swap(cgs); 00210 } 00211 return con_sys; 00212 } 00213 if (congruences_are_up_to_date() && !congruences_are_minimized()) { 00214 // Minimize the congruences. 00215 Grid& gr = const_cast<Grid&>(*this); 00216 if (gr.simplify(gr.con_sys, gr.dim_kinds)) 00217 gr.set_empty(); 00218 else 00219 gr.set_congruences_minimized(); 00220 } 00221 return congruences(); 00222 }
const PPL::Grid_Generator_System & Parma_Polyhedra_Library::Grid::generators | ( | ) | const |
Returns the system of generators.
Definition at line 225 of file Grid_public.cc.
References gen_sys, generators_are_up_to_date(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and update_generators().
Referenced by map_space_dimensions().
00225 { 00226 if (space_dim == 0) { 00227 assert(gen_sys.space_dimension() == 0 00228 && gen_sys.num_generators() == (marked_empty() ? 0 : 1)); 00229 return gen_sys; 00230 } 00231 00232 if (marked_empty()) { 00233 assert(gen_sys.num_generators() == 0); 00234 return gen_sys; 00235 } 00236 00237 if (!generators_are_up_to_date() && !update_generators()) { 00238 // Updating found the grid empty. 00239 const_cast<Grid&>(*this).set_empty(); 00240 return gen_sys; 00241 } 00242 00243 return gen_sys; 00244 }
const PPL::Grid_Generator_System & Parma_Polyhedra_Library::Grid::minimized_generators | ( | ) | const |
Returns the minimized system of generators.
Definition at line 247 of file Grid_public.cc.
References dim_kinds, gen_sys, generators_are_minimized(), generators_are_up_to_date(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), set_generators_minimized(), simplify(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and update_generators().
00247 { 00248 if (space_dim == 0) { 00249 assert(gen_sys.space_dimension() == 0 00250 && gen_sys.num_generators() == (marked_empty() ? 0 : 1)); 00251 return gen_sys; 00252 } 00253 00254 if (marked_empty()) { 00255 assert(gen_sys.num_generators() == 0); 00256 return gen_sys; 00257 } 00258 00259 if (generators_are_up_to_date()) { 00260 if (!generators_are_minimized()) { 00261 // Minimize the generators. 00262 Grid& gr = const_cast<Grid&>(*this); 00263 gr.simplify(gr.gen_sys, gr.dim_kinds); 00264 gr.set_generators_minimized(); 00265 } 00266 } 00267 else if (!update_generators()) { 00268 // Updating found the grid empty. 00269 const_cast<Grid&>(*this).set_empty(); 00270 return gen_sys; 00271 } 00272 00273 return gen_sys; 00274 }
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 277 of file Grid_public.cc.
References Parma_Polyhedra_Library::Scalar_Products::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_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, 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 grid_difference_assign(), and limited_extrapolation_assign().
00277 { 00278 // Dimension-compatibility check. 00279 if (space_dim < cg.space_dimension()) 00280 throw_dimension_incompatible("relation_with(cg)", "cg", cg); 00281 00282 if (marked_empty()) 00283 return Poly_Con_Relation::is_included() 00284 && Poly_Con_Relation::is_disjoint(); 00285 00286 if (space_dim == 0) 00287 // FIXME: Confirm that the relation with the false cg is correct. 00288 // Does the false congruence define the empty grid? If so, 00289 // is the empty grid disjoint from the universe grid? 00290 if (cg.inhomogeneous_term() == 0) 00291 return Poly_Con_Relation::is_included(); 00292 else if (cg.is_equality()) 00293 return Poly_Con_Relation::is_disjoint(); 00294 else if (cg.inhomogeneous_term() % cg.modulus() == 0) 00295 return Poly_Con_Relation::is_included(); 00296 else 00297 // cg is false. 00298 return Poly_Con_Relation::is_disjoint(); 00299 00300 if (!generators_are_up_to_date() && !update_generators()) 00301 // Updating found the grid empty. 00302 return Poly_Con_Relation::is_included() 00303 && Poly_Con_Relation::is_disjoint(); 00304 00305 // Return one of the relations 00306 // 'strictly_intersects' a strict subset of the grid points satisfy cg 00307 // 'is_included' every grid point satisfies cg 00308 // 'is_disjoint' cg and the grid occupy seperate spaces. 00309 00310 // There is always a point. 00311 00312 // Scalar product of the congruence and the first point that 00313 // satisfies the congruence. 00314 TEMP_INTEGER(point_sp); 00315 point_sp = 0; 00316 00317 TEMP_INTEGER(modulus); 00318 modulus = cg.modulus(); 00319 00320 TEMP_INTEGER(div); 00321 div = 0; 00322 00323 bool known_to_intersect = false; 00324 00325 for (Grid_Generator_System::const_iterator g = gen_sys.begin(), 00326 gen_sys_end = gen_sys.end(); g != gen_sys_end; ++g) { 00327 TEMP_INTEGER(sp); 00328 Scalar_Products::assign(sp, cg, *g); 00329 00330 switch (g->type()) { 00331 00332 case Grid_Generator::POINT: 00333 if (cg.is_proper_congruence()) 00334 sp %= modulus; 00335 if (sp == 0) 00336 // The point satisfies the congruence. 00337 if (point_sp == 0) 00338 // Any previous points satisfied the congruence. 00339 known_to_intersect = true; 00340 else 00341 return Poly_Con_Relation::strictly_intersects(); 00342 else 00343 if (point_sp == 0) { 00344 if (known_to_intersect) 00345 return Poly_Con_Relation::strictly_intersects(); 00346 // Assign `sp' to `point_sp' as `sp' is the scalar product 00347 // of cg and a point g and is non-zero. 00348 point_sp = sp; 00349 } 00350 else { 00351 // A previously considered point p failed to satisfy cg such that 00352 // `point_sp' = `scalar_prod(p,cg)' 00353 // so, if we consider the parameter g-p instead of g, we have 00354 // scalar_prod(g-p, cg) = scalar_prod(g,cg) - scalar_prod(p,cg) 00355 // = sp - point_sp 00356 sp -= point_sp; 00357 00358 if (sp != 0) { 00359 // Find the GCD between sp and the previous GCD. 00360 gcd_assign(div, div, sp); 00361 if (point_sp % div == 0) 00362 // There is a point in the grid satisfying cg. 00363 return Poly_Con_Relation::strictly_intersects(); 00364 } 00365 } 00366 break; 00367 00368 case Grid_Generator::PARAMETER: 00369 if (cg.is_proper_congruence()) 00370 sp %= (modulus * g->divisor()); 00371 if (sp == 0) 00372 // Parameter g satisfies the cg so the relation depends 00373 // entirely on the other generators. 00374 break; 00375 00376 if (known_to_intersect) 00377 // At least one point satisfies cg. However, the sum of such 00378 // a point and the parameter g fails to satisfy cg (due to g). 00379 return Poly_Con_Relation::strictly_intersects(); 00380 00381 // Find the GCD between sp and the previous GCD. 00382 gcd_assign(div, div, sp); 00383 if (point_sp != 0) 00384 // At least one of any previously encountered points fails to 00385 // satisfy cg. 00386 if (point_sp == div) 00387 // There is also a grid point that satisfies cg. 00388 return Poly_Con_Relation::strictly_intersects(); 00389 00390 break; 00391 00392 case Grid_Generator::LINE: 00393 if (sp == 0) 00394 // Line g satisfies the cg so the relation depends entirely on 00395 // the other generators. 00396 break; 00397 00398 // Line g intersects the congruence. 00399 // 00400 // There is a point p in the grid. Suppose <p*cg> = p_sp. Then 00401 // (-p_sp/sp)*g + p is a point that satisfies cg: <((-p_sp/sp)*g 00402 // + p).cg> = -(p_sp/sp)*sp + p_sp) = 0. If p does not satisfy 00403 // `cg' and hence is not in the grid defined by `cg', the grid 00404 // `*this' strictly intersects the `cg' grid. On the other 00405 // hand, if `p' is in the grid defined by `cg' so that p_sp = 0, 00406 // then <p+g.cg> = p_sp + sp != 0; thus `p+g' is a point in 00407 // *this that does not satisfy `cg' and hence `p+g' is a point 00408 // in *this not in the grid defined by `cg'; therefore `*this' 00409 // strictly intersects the `cg' grid. 00410 00411 return Poly_Con_Relation::strictly_intersects(); 00412 } 00413 } 00414 00415 if (point_sp == 0) 00416 // Every generator satisfied the cg. 00417 return Poly_Con_Relation::is_included(); 00418 00419 assert(!known_to_intersect); 00420 return Poly_Con_Relation::is_disjoint(); 00421 }
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 424 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().
00424 { 00425 // Dimension-compatibility check. 00426 if (space_dim < g.space_dimension()) 00427 throw_dimension_incompatible("relation_with(g)", "g", g); 00428 00429 // The empty grid cannot subsume a generator. 00430 if (marked_empty()) 00431 return Poly_Gen_Relation::nothing(); 00432 00433 // A universe grid in a zero-dimensional space subsumes all the 00434 // generators of a zero-dimensional space. 00435 if (space_dim == 0) 00436 return Poly_Gen_Relation::subsumes(); 00437 00438 congruences_are_up_to_date() || update_congruences(); 00439 00440 return 00441 con_sys.satisfies_all_congruences(g) 00442 ? Poly_Gen_Relation::subsumes() 00443 : Poly_Gen_Relation::nothing(); 00444 }
bool Parma_Polyhedra_Library::Grid::is_empty | ( | ) | const |
Returns true
if and only if *this
is an empty grid.
Definition at line 447 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(), contains(), generalized_affine_image(), generalized_affine_preimage(), and operator<<().
00447 { 00448 if (marked_empty()) 00449 return true; 00450 // Try a fast-fail test: if generators are up-to-date then the 00451 // generator system (since it is well formed) contains a point. 00452 if (generators_are_up_to_date()) 00453 return false; 00454 if (space_dim == 0) 00455 return false; 00456 if (congruences_are_minimized()) 00457 // If the grid was empty it would be marked empty. 00458 return false; 00459 // Minimize the congruences to check if the grid is empty. 00460 Grid& gr = const_cast<Grid&>(*this); 00461 if (gr.simplify(gr.con_sys, gr.dim_kinds)) { 00462 gr.set_empty(); 00463 return true; 00464 } 00465 gr.set_congruences_minimized(); 00466 return false; 00467 }
bool Parma_Polyhedra_Library::Grid::is_universe | ( | ) | const |
Returns true
if and only if *this
is a universe grid.
Definition at line 470 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<<().
00470 { 00471 if (marked_empty()) 00472 return false; 00473 00474 if (space_dim == 0) 00475 return true; 00476 00477 if (congruences_are_up_to_date()) { 00478 if (congruences_are_minimized()) 00479 // The minimized universe congruence system has only one row, 00480 // the integrality congruence. 00481 return con_sys.num_rows() == 1 && con_sys[0].is_trivial_true(); 00482 } 00483 else { 00484 update_congruences(); 00485 return con_sys.num_rows() == 1 && con_sys[0].is_trivial_true(); 00486 } 00487 00488 // Test con_sys's inclusion in a universe generator system. 00489 00490 // The zero dimension cases are handled above. 00491 Variable var(space_dim - 1); 00492 for (dimension_type i = space_dim; i-- > 0; ) 00493 if (!con_sys.satisfies_all_congruences(grid_line(Variable(i) + var))) 00494 return false; 00495 assert(con_sys.satisfies_all_congruences(grid_point(0*var))); 00496 return true; 00497 }
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.
Definition at line 564 of file Grid_public.cc.
References con_sys, congruences_are_minimized(), dim_kinds, gen_sys, generators_are_minimized(), generators_are_up_to_date(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), Parma_Polyhedra_Library::Matrix::num_rows(), set_congruences_minimized(), set_empty(), set_generators_minimized(), simplify(), and space_dim.
00564 { 00565 // Any empty or zero-dimensional grid is closed. 00566 if (marked_empty() || space_dim == 0) 00567 return true; 00568 00569 if (generators_are_minimized()) { 00570 param_search: 00571 // Search for a parameter in the minimized generator system. 00572 for (dimension_type row = gen_sys.num_generators(); row-- > 1; ) 00573 if (gen_sys[row].is_parameter()) 00574 return false; 00575 return true; 00576 } 00577 00578 if (congruences_are_minimized()) { 00579 proper_cg_search: 00580 // Search for a proper congruence following the integrality 00581 // congruence, in the minimized congruence system. 00582 for (dimension_type row = con_sys.num_rows() - 1; row-- > 0; ) 00583 if (con_sys[row].is_proper_congruence()) 00584 return false; 00585 return true; 00586 } 00587 00588 Grid& gr = const_cast<Grid&>(*this); 00589 if (generators_are_up_to_date()) { 00590 gr.simplify(gr.gen_sys, gr.dim_kinds); 00591 gr.set_generators_minimized(); 00592 goto param_search; 00593 } 00594 00595 // Minimize the congruence system. 00596 if (gr.simplify(gr.con_sys, gr.dim_kinds)) { 00597 // The congruence system reduced to the empty grid. 00598 gr.set_empty(); 00599 return true; 00600 } 00601 gr.set_congruences_minimized(); 00602 goto proper_cg_search; 00603 }
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 2094 of file Grid_public.cc.
References intersection_assign_and_minimize(), space_dim, and throw_dimension_incompatible().
02094 { 02095 // Dimension-compatibility check. 02096 if (space_dim != y.space_dim) 02097 throw_dimension_incompatible("is_disjoint_from(y)", "y", y); 02098 Grid z = *this; 02099 return !z.intersection_assign_and_minimize(y); 02100 }
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 524 of file Grid_public.cc.
References con_sys, congruences_are_minimized(), dim_kinds, gen_sys, generators_are_minimized(), generators_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::has_a_free_dimension(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), set_congruences_minimized(), set_empty(), set_generators_minimized(), simplify(), and space_dim.
00524 { 00525 // A zero-dimensional or empty grid is discrete. 00526 if (space_dim == 0 || marked_empty()) 00527 return true; 00528 00529 if (generators_are_minimized()) { 00530 line_search: 00531 // Search for lines in the minimized generator system. 00532 for (dimension_type row = gen_sys.num_generators(); row-- > 1; ) 00533 if (gen_sys[row].is_line()) 00534 return false; 00535 return true; 00536 } 00537 00538 if (congruences_are_minimized()) 00539 return con_sys.has_a_free_dimension(); 00540 00541 Grid& gr = const_cast<Grid&>(*this); 00542 if (generators_are_up_to_date()) { 00543 // Minimize the generator system. 00544 gr.simplify(gr.gen_sys, gr.dim_kinds); 00545 gr.set_generators_minimized(); 00546 00547 goto line_search; 00548 } 00549 00550 // Generators are out of date. 00551 00552 // Minimize the congruence system to find out whether it is empty. 00553 if (gr.simplify(gr.con_sys, gr.dim_kinds)) { 00554 // The congruence system reduced to the empty grid. 00555 gr.set_empty(); 00556 return true; 00557 } 00558 gr.set_congruences_minimized(); 00559 00560 return gr.con_sys.has_a_free_dimension(); 00561 }
bool Parma_Polyhedra_Library::Grid::is_bounded | ( | ) | const |
Returns true
if and only if *this
is bounded.
Definition at line 500 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_generators(), space_dim, and update_generators().
00500 { 00501 // A zero-dimensional or empty grid is bounded. 00502 if (space_dim == 0 00503 || marked_empty() 00504 || (!generators_are_up_to_date() && !update_generators())) 00505 return true; 00506 00507 // TODO: Consider using con_sys when gen_sys is out of date. 00508 00509 if (gen_sys.num_generators() > 1) { 00510 // Check if all generators are the same point. 00511 const Grid_Generator& first_point = gen_sys[0]; 00512 if (first_point.is_line_or_parameter()) 00513 return false; 00514 for (dimension_type row = gen_sys.num_generators(); row-- > 0; ) { 00515 const Grid_Generator& gen = gen_sys[row]; 00516 if (gen.is_line_or_parameter() || gen != first_point) 00517 return false; 00518 } 00519 } 00520 return true; 00521 }
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 210 of file Grid.inlines.hh.
References bounds().
00210 { 00211 return bounds(expr, "bounds_from_above(e)"); 00212 }
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 215 of file Grid.inlines.hh.
References bounds().
00215 { 00216 return bounds(expr, "bounds_from_below(e)"); 00217 }
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 220 of file Grid.inlines.hh.
References max_min().
00221 { 00222 return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum); 00223 }
bool Parma_Polyhedra_Library::Grid::maximize | ( | const Linear_Expression & | expr, | |
Coefficient & | sup_n, | |||
Coefficient & | sup_d, | |||
bool & | maximum, | |||
Grid_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 226 of file Grid.inlines.hh.
References max_min().
00228 { 00229 return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum, &point); 00230 }
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 233 of file Grid.inlines.hh.
References max_min().
Referenced by is_included_in().
00234 { 00235 return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum); 00236 }
bool Parma_Polyhedra_Library::Grid::minimize | ( | const Linear_Expression & | expr, | |
Coefficient & | inf_n, | |||
Coefficient & | inf_d, | |||
bool & | minimum, | |||
Grid_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 239 of file Grid.inlines.hh.
References max_min().
00241 { 00242 return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum, &point); 00243 }
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 2075 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 grid_difference_assign(), limited_extrapolation_assign(), strictly_contains(), and widening_assign().
02075 { 02076 const Grid& x = *this; 02077 02078 // Dimension-compatibility check. 02079 if (x.space_dim != y.space_dim) 02080 throw_dimension_incompatible("contains(y)", "y", y); 02081 02082 if (y.marked_empty()) 02083 return true; 02084 if (x.marked_empty()) 02085 return y.is_empty(); 02086 if (y.space_dim == 0) 02087 return true; 02088 if (x.quick_equivalence_test(y) == Grid::TVB_TRUE) 02089 return true; 02090 return y.is_included_in(x); 02091 }
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 252 of file Grid.inlines.hh.
References contains().
00252 { 00253 const Grid& x = *this; 00254 return x.contains(y) && !y.contains(x); 00255 }
void Parma_Polyhedra_Library::Grid::shrink_bounding_box | ( | Box & | box | ) | const [inline] |
Uses *this
to shrink a generic, interval-based bounding box.
box | The bounding box to be shrunk. |
std::invalid_argument | Thrown if *this and box are dimension-incompatible, or if box contains any topologically open bounds. |
dimension_type space_dimension() const
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 raise_lower_bound(dimension_type k, bool closed, Coefficient_traits::const_reference n, Coefficient_traits::const_reference d)
k
-th space dimension with closed
is always passed as true
. lower_upper_bound(dimension_type k, bool closed, Coefficient_traits::const_reference n, Coefficient_traits::const_reference d)
k
-th space dimension with closed
is always passed as true
.
The function raise_lower_bound(k, closed, n, d)
will be called at most once for each possible value for k
and for all such calls the fraction will be in canonical form, that is,
and
have no common factors and
is positive,
being the unique representation for zero. The same guarantee is offered for the function
lower_upper_bound(k, closed, n, d)
.
Definition at line 195 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::Grid_Generator::is_point(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_columns(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), space_dim, TEMP_INTEGER, throw_dimension_incompatible(), throw_invalid_argument(), and update_generators().
00195 { 00196 // Dimension-compatibility check. 00197 if (space_dim > box.space_dimension()) 00198 throw_dimension_incompatible("shrink_bounding_box(box)", "box", 00199 box.space_dimension()); 00200 00201 TEMP_INTEGER(l_n); 00202 TEMP_INTEGER(l_d); 00203 00204 // Check that all bounds are closed. 00205 for (dimension_type k = space_dim; k-- > 0; ) { 00206 bool closed; 00207 // FIXME: Perhaps introduce box::is_bounded_and_closed. 00208 if (box.get_lower_bound(k, closed, l_n, l_d) && !closed) 00209 throw_invalid_argument("shrink_bounding_box(box)", "box"); 00210 if (box.get_upper_bound(k, closed, l_n, l_d) && !closed) 00211 throw_invalid_argument("shrink_bounding_box(box)", "box"); 00212 } 00213 00214 if (marked_empty()) { 00215 box.set_empty(); 00216 return; 00217 } 00218 if (space_dim == 0) 00219 return; 00220 if (!generators_are_up_to_date() && !update_generators()) { 00221 // Updating found the grid empty. 00222 box.set_empty(); 00223 return; 00224 } 00225 00226 assert(gen_sys.num_generators() > 0); 00227 00228 dimension_type num_dims = gen_sys.num_columns() - 2 /* parameter divisor */; 00229 dimension_type num_rows = gen_sys.num_generators(); 00230 00231 // Create a vector to record which dimensions are bounded. 00232 std::vector<bool> bounded_interval(num_dims, true); 00233 00234 const Grid_Generator *first_point = NULL; 00235 // Clear the bound flag in `bounded_interval' for all dimensions in 00236 // which a line or sequence of points extends away from a single 00237 // value in the dimension. 00238 for (dimension_type row = 0; row < num_rows; ++row) { 00239 Grid_Generator& gen = const_cast<Grid_Generator&>(gen_sys[row]); 00240 if (gen.is_point()) { 00241 if (first_point == NULL) { 00242 first_point = &gen_sys[row]; 00243 continue; 00244 } 00245 const Grid_Generator& point = *first_point; 00246 // Convert the point `gen' to a parameter. 00247 for (dimension_type dim = 0; dim < num_dims; ++dim) 00248 gen[dim] -= point[dim]; 00249 gen.divisor() = point.divisor(); 00250 } 00251 for (dimension_type col = num_dims; col > 0; ) 00252 if (gen[col--] != 0) 00253 bounded_interval[col] = false; 00254 } 00255 00256 // Attempt to set both bounds of each boundable interval to the 00257 // value of the associated coefficient in the point. 00258 const Grid_Generator& point = *first_point; 00259 TEMP_INTEGER(divisor); 00260 TEMP_INTEGER(gcd); 00261 TEMP_INTEGER(bound); 00262 TEMP_INTEGER(reduced_divisor); 00263 divisor = point.divisor(); 00264 for (dimension_type dim = 0; dim < num_dims; ++dim) 00265 if (bounded_interval[dim]) { 00266 // Reduce the bound fraction first. 00267 gcd_assign(gcd, point[dim+1], divisor); 00268 exact_div_assign(bound, point[dim+1], gcd); 00269 exact_div_assign(reduced_divisor, divisor, gcd); 00270 box.raise_lower_bound(dim, true, bound, reduced_divisor); 00271 box.lower_upper_bound(dim, true, bound, reduced_divisor); 00272 } 00273 }
void Parma_Polyhedra_Library::Grid::get_covering_box | ( | Box & | 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. |
dimension_type space_dimension() const
raise_lower_bound(dimension_type k, bool closed, Coefficient_traits::const_reference n, Coefficient_traits::const_reference d)
k
-th space dimension with closed
is always passed as true
. lower_upper_bound(dimension_type k, bool closed, Coefficient_traits::const_reference n, Coefficient_traits::const_reference d)
k
-th space dimension with closed
is always passed as true
.
The function raise_lower_bound(k, closed, n, d)
will be called at most once for each possible value for k
and for all such calls the fraction will be in canonical form, that is,
and
have no common factors and
is positive,
being the unique representation for zero. The same guarantee is offered for the function
lower_upper_bound(k, closed, n, d)
.
Definition at line 277 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::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_generators(), space_dim, TEMP_INTEGER, throw_dimension_incompatible(), and update_generators().
00277 { 00278 // Dimension-compatibility check. 00279 if (space_dim > box.space_dimension()) 00280 throw_dimension_incompatible("get_covering_box(box)", "box", 00281 box.space_dimension()); 00282 00283 Box new_box(box.space_dimension()); 00284 00285 if (marked_empty()) { 00286 box = new_box; 00287 box.set_empty(); 00288 return; 00289 } 00290 if (space_dim == 0) { 00291 return; 00292 } 00293 if (!generators_are_up_to_date() && !update_generators()) { 00294 // Updating found the grid empty. 00295 box = new_box; 00296 box.set_empty(); 00297 return; 00298 } 00299 00300 assert(gen_sys.num_generators() > 0); 00301 00302 dimension_type num_dims = gen_sys.num_columns() - 2 /* parameter divisor */; 00303 dimension_type num_rows = gen_sys.num_generators(); 00304 00305 TEMP_INTEGER(divisor); 00306 TEMP_INTEGER(gcd); 00307 TEMP_INTEGER(bound); 00308 TEMP_INTEGER(reduced_divisor); 00309 00310 if (num_rows > 1) { 00311 Row interval_sizes(num_dims, Row::Flags()); 00312 std::vector<bool> interval_emptiness(num_dims, false); 00313 00314 // Store in `interval_sizes', for each column (that is, for each 00315 // dimension), the GCD of all the values in that column where the 00316 // row is of type parameter. 00317 00318 for (dimension_type dim = num_dims; dim-- > 0; ) 00319 interval_sizes[dim] = 0; 00320 const Grid_Generator *first_point = NULL; 00321 for (dimension_type row = 0; row < num_rows; ++row) { 00322 Grid_Generator& gen = const_cast<Grid_Generator&>(gen_sys[row]); 00323 if (gen.is_line()) { 00324 for (dimension_type dim = 0; dim < num_dims; ++dim) 00325 if (!interval_emptiness[dim] && gen[dim+1] != 0) { 00326 // Empty interval, set both bounds for associated 00327 // dimension to zero. 00328 new_box.lower_upper_bound(dim, true, 0, 1); 00329 new_box.raise_lower_bound(dim, true, 0, 1); 00330 interval_emptiness[dim] = true; 00331 } 00332 continue; 00333 } 00334 if (gen.is_point()) { 00335 if (first_point == NULL) { 00336 first_point = &gen_sys[row]; 00337 continue; 00338 } 00339 const Grid_Generator& point = *first_point; 00340 // Convert the point `gen' to a parameter. 00341 for (dimension_type dim = 0; dim <= num_dims; ++dim) 00342 gen[dim] -= point[dim]; 00343 gen.divisor() = point.divisor(); 00344 } 00345 for (dimension_type dim = 0; dim < num_dims; ++dim) 00346 if (!interval_emptiness[dim]) 00347 gcd_assign(interval_sizes[dim], interval_sizes[dim], gen[dim+1]); 00348 } 00349 00350 // For each dimension set the lower bound of the interval to the 00351 // grid value closest to the origin, and the upper bound to the 00352 // addition of the lower bound and the shortest distance in the 00353 // given dimension between any two grid points. 00354 const Grid_Generator& point = *first_point; 00355 divisor = point.divisor(); 00356 TEMP_INTEGER(lower_bound); 00357 for (dimension_type dim = 0; dim < num_dims; ++dim) { 00358 if (interval_emptiness[dim]) 00359 continue; 00360 00361 lower_bound = point[dim+1]; 00362 00363 // If the interval size is zero then all points have the same 00364 // value in this dimension, so set only the lower bound. 00365 if (interval_sizes[dim] != 0) { 00366 // Make the lower bound as close as possible to the origin, 00367 // leaving the sign the same. 00368 lower_bound %= interval_sizes[dim]; 00369 // Check if the lowest value the other side of the origin is 00370 // closer to the origin, prefering the lowest positive if they 00371 // are equal. 00372 if (lower_bound > 0) { 00373 if (interval_sizes[dim] - lower_bound < lower_bound) 00374 lower_bound -= interval_sizes[dim]; 00375 } 00376 else if (lower_bound < 0 00377 && interval_sizes[dim] + lower_bound < - lower_bound) 00378 lower_bound += interval_sizes[dim]; 00379 00380 // Reduce the bound fraction first. 00381 bound = interval_sizes[dim] + lower_bound; 00382 gcd_assign(gcd, bound, divisor); 00383 exact_div_assign(bound, bound, gcd); 00384 exact_div_assign(reduced_divisor, divisor, gcd); 00385 new_box.lower_upper_bound(dim, true, bound, reduced_divisor); 00386 } 00387 00388 // Reduce the bound fraction first. 00389 gcd_assign(gcd, lower_bound, divisor); 00390 exact_div_assign(lower_bound, lower_bound, gcd); 00391 exact_div_assign(reduced_divisor, divisor, gcd); 00392 new_box.raise_lower_bound(dim, true, lower_bound, reduced_divisor); 00393 } 00394 } 00395 else { 00396 const Grid_Generator& point = gen_sys[0]; 00397 divisor = point.divisor(); 00398 // The covering box of a single point has only lower bounds. 00399 for (dimension_type dim = 0; dim < num_dims; ++dim) { 00400 // Reduce the bound fraction first. 00401 gcd_assign(gcd, point[dim+1], divisor); 00402 exact_div_assign(bound, point[dim+1], gcd); 00403 exact_div_assign(reduced_divisor, divisor, gcd); 00404 new_box.raise_lower_bound(dim, true, bound, reduced_divisor); 00405 } 00406 } 00407 00408 box = new_box; 00409 }
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 606 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::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_generators(), Parma_Polyhedra_Library::Matrix::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, update_generators(), and upper_triangular().
Referenced by add_congruence(), add_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_generators(), add_recycled_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_load(), concatenate_assign(), construct(), expand_space_dimension(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), Grid(), grid_difference_assign(), intersection_assign(), is_included_in(), join_assign(), limited_extrapolation_assign(), map_space_dimensions(), minimize(), remove_higher_space_dimensions(), remove_space_dimensions(), time_elapse_assign(), and widening_assign().
00606 { 00607 #ifndef NDEBUG 00608 using std::endl; 00609 using std::cerr; 00610 #endif 00611 00612 // Check whether the status information is legal. 00613 if (!status.OK()) 00614 goto fail; 00615 00616 if (marked_empty()) { 00617 if (check_not_empty) { 00618 // The caller does not want the grid to be empty. 00619 #ifndef NDEBUG 00620 cerr << "Empty grid!" << endl; 00621 #endif 00622 goto fail; 00623 } 00624 00625 if (con_sys.space_dimension() != space_dim) { 00626 #ifndef NDEBUG 00627 cerr << "The grid is in a space of dimension " << space_dim 00628 << " while the system of congruences is in a space of dimension " 00629 << con_sys.space_dimension() 00630 << endl; 00631 #endif 00632 goto fail; 00633 } 00634 return true; 00635 } 00636 00637 // A zero-dimensional universe grid is legal only if the system of 00638 // congruences `con_sys' is empty, and the generator system contains 00639 // one point. 00640 if (space_dim == 0) { 00641 if (con_sys.num_rows() == 0) 00642 if (gen_sys.num_generators() == 1 && gen_sys[0].is_point()) 00643 return true; 00644 #ifndef NDEBUG 00645 cerr << "Zero-dimensional grid should have an empty congruence" << endl 00646 << "system and a generator system of a single point." << endl; 00647 #endif 00648 goto fail; 00649 } 00650 00651 // A grid is defined by a system of congruences or a system of 00652 // generators. At least one of them must be up to date. 00653 if (!congruences_are_up_to_date() && !generators_are_up_to_date()) { 00654 #ifndef NDEBUG 00655 cerr << "Grid not empty, not zero-dimensional" << endl 00656 << "and with neither congruences nor generators up-to-date!" 00657 << endl; 00658 #endif 00659 goto fail; 00660 } 00661 00662 { 00663 // This block is to limit the scope of num_columns, at least for 00664 // GCC < 3.4. 00665 00666 // The expected number of columns in the congruence and generator 00667 // systems, if they are not empty. 00668 const dimension_type num_columns = space_dim + 1; 00669 00670 // Here we check if the size of the matrices is consistent. 00671 // Let us suppose that all the matrices are up-to-date; this means: 00672 // `con_sys' : number of congruences x poly_num_columns 00673 // `gen_sys' : number of generators x poly_num_columns 00674 if (congruences_are_up_to_date()) 00675 if (con_sys.num_columns() != num_columns + 1 /* moduli */) { 00676 #ifndef NDEBUG 00677 cerr << "Incompatible size! (con_sys and space_dim)" 00678 << endl; 00679 #endif 00680 goto fail; 00681 } 00682 00683 if (generators_are_up_to_date()) { 00684 if (gen_sys.space_dimension() + 1 != num_columns) { 00685 #ifndef NDEBUG 00686 cerr << "Incompatible size! (gen_sys and space_dim)" 00687 << endl; 00688 #endif 00689 goto fail; 00690 } 00691 00692 // Check if the system of generators is well-formed. 00693 if (!gen_sys.OK()) { 00694 #ifndef NDEBUG 00695 cerr << "gen_sys OK failed." << endl; 00696 #endif 00697 goto fail; 00698 } 00699 // Check each generator in the system. 00700 for (dimension_type i = gen_sys.num_generators(); i-- > 0; ) { 00701 const Grid_Generator& g = gen_sys[i]; 00702 00703 if (g.size() < 1) { 00704 #ifndef NDEBUG 00705 cerr << "Parameter should have coefficients." << endl; 00706 #endif 00707 goto fail; 00708 } 00709 } 00710 00711 // A non-empty system of generators describing a grid is valid iff 00712 // it contains a point. 00713 if (gen_sys.num_generators() > 0 && !gen_sys.has_points()) { 00714 #ifndef NDEBUG 00715 cerr << "Non-empty generator system declared up-to-date " 00716 << "has no points!" 00717 << endl; 00718 #endif 00719 goto fail; 00720 } 00721 00722 if (generators_are_minimized()) { 00723 Grid_Generator_System gs = gen_sys; 00724 00725 if (dim_kinds.size() != num_columns) { 00726 #ifndef NDEBUG 00727 cerr << "Size of dim_kinds should equal the number of columns." 00728 << endl; 00729 #endif 00730 goto fail; 00731 } 00732 00733 if (!upper_triangular(gs, dim_kinds)) { 00734 #ifndef NDEBUG 00735 cerr << "Reduced generators should be upper triangular." 00736 << endl; 00737 #endif 00738 goto fail; 00739 } 00740 00741 // Check that dim_kinds corresponds to the row kinds in gen_sys. 00742 for (dimension_type dim = 0, row = 0; 00743 dim < space_dim + 1; 00744 ++dim, assert(row <= dim)) { 00745 if (dim_kinds[dim] == GEN_VIRTUAL 00746 || (gen_sys[row++].is_parameter_or_point() 00747 && dim_kinds[dim] == PARAMETER) 00748 || (assert(gen_sys[row-1].is_line()), dim_kinds[dim] == LINE)) 00749 continue; 00750 #ifndef NDEBUG 00751 cerr << "Kinds in dim_kinds should match those in gen_sys." 00752 << endl; 00753 #endif 00754 goto fail; 00755 } 00756 00757 // A reduced generator system must be the same as a temporary 00758 // reduced copy. 00759 Dimension_Kinds dk = dim_kinds; 00760 // `gs' is minimized and marked_empty returned false, so `gs' 00761 // should contain rows. 00762 assert(gs.num_generators() > 0); 00763 simplify(gs, dk); 00764 // gs contained rows before being reduced, so it should 00765 // contain at least a single point afterwards. 00766 assert(gs.num_generators() > 0); 00767 for (dimension_type row = 0; row < gen_sys.num_generators(); ++row) { 00768 Grid_Generator& g = gs[row]; 00769 const Grid_Generator& g_copy = gen_sys[row]; 00770 if (g.is_equal_to(g_copy)) 00771 continue; 00772 #ifndef NDEBUG 00773 cerr << "Generators are declared minimized," 00774 " but they change under reduction.\n" 00775 << "Here is the generator system:\n"; 00776 gen_sys.ascii_dump(cerr); 00777 cerr << "and here is the minimized form of the temporary copy:\n"; 00778 gs.ascii_dump(cerr); 00779 #endif 00780 goto fail; 00781 } 00782 } 00783 00784 } // if (congruences_are_up_to_date()) 00785 } // scope block 00786 00787 if (congruences_are_up_to_date()) { 00788 // Check if the system of congruences is well-formed. 00789 if (!con_sys.OK()) { 00790 #ifndef NDEBUG 00791 cerr << "con_sys OK failed." << endl; 00792 #endif 00793 goto fail; 00794 } 00795 00796 Grid tem_gr = *this; 00797 Congruence_System cs_copy = tem_gr.con_sys; 00798 00799 // Clear the generators in tem_gr. 00800 Grid_Generator_System gs(space_dim); 00801 std::swap(tem_gr.gen_sys, gs); 00802 tem_gr.clear_generators_up_to_date(); 00803 00804 if (!tem_gr.update_generators()) { 00805 if (check_not_empty) { 00806 // Want to know the satisfiability of the congruences. 00807 #ifndef NDEBUG 00808 cerr << "Unsatisfiable system of congruences!" 00809 << endl; 00810 #endif 00811 goto fail; 00812 } 00813 // The grid is empty, all checks are done. 00814 return true; 00815 } 00816 00817 if (congruences_are_minimized()) { 00818 // A reduced congruence system must be lower triangular. 00819 if (!lower_triangular(con_sys, dim_kinds)) { 00820 #ifndef NDEBUG 00821 cerr << "Reduced congruences should be lower triangular." << endl; 00822 #endif 00823 goto fail; 00824 } 00825 00826 // If the congruences are minimized, all the elements in the 00827 // congruence system must be the same as those in the temporary, 00828 // minimized system `cs_copy'. 00829 if (!con_sys.is_equal_to(cs_copy)) { 00830 #ifndef NDEBUG 00831 cerr << "Congruences are declared minimized, but they change under reduction!" 00832 << endl 00833 << "Here is the minimized form of the congruence system:" 00834 << endl; 00835 cs_copy.ascii_dump(cerr); 00836 cerr << endl; 00837 #endif 00838 goto fail; 00839 } 00840 00841 if (dim_kinds.size() != con_sys.num_columns() - 1 /* modulus */) { 00842 #ifndef NDEBUG 00843 cerr << "Size of dim_kinds should equal the number of columns." 00844 << endl; 00845 #endif 00846 goto fail; 00847 } 00848 00849 // Check that dim_kinds corresponds to the row kinds in con_sys. 00850 for (dimension_type dim = 0, row = con_sys.num_rows() - 1; 00851 dim < space_dim + 1; 00852 ++dim) { 00853 if (dim_kinds[dim] == CON_VIRTUAL 00854 || (con_sys[row--].is_proper_congruence() 00855 && dim_kinds[dim] == PROPER_CONGRUENCE) 00856 || (assert(con_sys[row+1].is_equality()), 00857 dim_kinds[dim] == EQUALITY)) 00858 continue; 00859 #ifndef NDEBUG 00860 cerr << "Kinds in dim_kinds should match those in con_sys." << endl; 00861 #endif 00862 goto fail; 00863 } 00864 } 00865 } 00866 00867 return true; 00868 00869 fail: 00870 #ifndef NDEBUG 00871 cerr << "Here is the grid under check:" << endl; 00872 ascii_dump(cerr); 00873 #endif 00874 return false; 00875 }
void Parma_Polyhedra_Library::Grid::add_congruence | ( | const Congruence & | cg | ) |
Adds a copy of congruence cg
to *this
.
std::invalid_argument | Thrown if *this and congruence cg are dimension-incompatible. |
Definition at line 878 of file Grid_public.cc.
References clear_congruences_minimized(), clear_generators_up_to_date(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), Parma_Polyhedra_Library::Congruence::is_trivial_true(), marked_empty(), OK(), set_congruences_up_to_date(), set_empty(), space_dim, Parma_Polyhedra_Library::Congruence::space_dimension(), throw_dimension_incompatible(), and update_congruences().
Referenced by add_constraint(), generalized_affine_image(), generalized_affine_preimage(), and grid_difference_assign().
00878 { 00879 // Dimension-compatibility check: the dimension of `cg' can not be 00880 // greater than space_dim. 00881 if (space_dim < cg.space_dimension()) 00882 throw_dimension_incompatible("add_congruence(cg)", "cg", cg); 00883 00884 // Adding a new congruence to an empty grid results in an empty 00885 // grid. 00886 if (marked_empty()) 00887 return; 00888 00889 // Dealing with a zero-dimensional space grid first. 00890 if (space_dim == 0) { 00891 if (!cg.is_trivial_true()) 00892 set_empty(); 00893 return; 00894 } 00895 00896 congruences_are_up_to_date() || update_congruences(); 00897 00898 con_sys.insert(cg); 00899 00900 clear_congruences_minimized(); 00901 set_congruences_up_to_date(); 00902 clear_generators_up_to_date(); 00903 00904 // Note: the congruence system may have become unsatisfiable, thus 00905 // we do not check for satisfiability. 00906 assert(OK()); 00907 }
void Parma_Polyhedra_Library::Grid::add_congruence | ( | const Constraint & | c | ) |
Adds constraint c
to *this
.
The addition can only affect *this
if c
is an equality.
std::invalid_argument | Thrown if *this and constraint c are dimension-incompatible. |
Definition at line 910 of file Grid_public.cc.
References add_recycled_congruences(), and Parma_Polyhedra_Library::Constraint::is_equality().
00910 { 00911 // TODO: this is just an executable specification. 00912 if (c.is_equality()) { 00913 Congruence_System cgs(c); 00914 add_recycled_congruences(cgs); 00915 } 00916 }
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 919 of file Grid_public.cc.
References add_recycled_congruences_and_minimize().
Referenced by add_constraint_and_minimize().
00919 { 00920 // TODO: this is just an executable specification. 00921 Congruence_System cgs(cg); 00922 return add_recycled_congruences_and_minimize(cgs); 00923 }
bool Parma_Polyhedra_Library::Grid::add_congruence_and_minimize | ( | const Constraint & | c | ) |
Adds a copy of constraint c
to *this
, reducing the result.
The addition can only affect *this
if c
is an equality.
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and constraint c are dimension-incompatible. |
Definition at line 926 of file Grid_public.cc.
References add_recycled_congruences_and_minimize(), Parma_Polyhedra_Library::Constraint::is_equality(), and minimize().
00926 { 00927 // TODO: this is just an executable specification. 00928 if (c.is_equality()) { 00929 Congruence_System cgs(c); 00930 return add_recycled_congruences_and_minimize(cgs); 00931 } 00932 return minimize(); 00933 }
void Parma_Polyhedra_Library::Grid::add_generator | ( | const Grid_Generator & | g | ) |
Adds a copy of 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 936 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_preimage().
00936 { 00937 // The dimension of `g' must be at most space_dim. 00938 const dimension_type g_space_dim = g.space_dimension(); 00939 if (space_dim < g_space_dim) 00940 throw_dimension_incompatible("add_generator(g)", "g", g); 00941 00942 // Deal with zero-dimension case first. 00943 if (space_dim == 0) { 00944 // Points and parameters are the only zero-dimension generators 00945 // that can be created. 00946 if (marked_empty()) { 00947 if (g.is_parameter()) 00948 throw_invalid_generator("add_generator(g)", "g"); 00949 set_zero_dim_univ(); 00950 } 00951 assert(OK()); 00952 return; 00953 } 00954 00955 if (marked_empty() 00956 || (!generators_are_up_to_date() && !update_generators())) { 00957 // Here the grid is empty: the specification says we can only 00958 // insert a point. 00959 if (g.is_line_or_parameter()) 00960 throw_invalid_generator("add_generator(g)", "g"); 00961 gen_sys.insert(g); 00962 clear_empty(); 00963 } 00964 else { 00965 assert(generators_are_up_to_date()); 00966 gen_sys.insert(g); 00967 if (g.is_parameter_or_point()) 00968 normalize_divisors(gen_sys); 00969 } 00970 00971 // With the added generator, congruences are out of date. 00972 clear_congruences_up_to_date(); 00973 00974 clear_generators_minimized(); 00975 set_generators_up_to_date(); 00976 assert(OK()); 00977 }
bool Parma_Polyhedra_Library::Grid::add_generator_and_minimize | ( | const Grid_Generator & | g | ) |
Adds a copy of 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 980 of file Grid_public.cc.
References add_recycled_generators_and_minimize().
00980 { 00981 // TODO: this is just an executable specification. 00982 Grid_Generator_System gs(g); 00983 return add_recycled_generators_and_minimize(gs); 00984 }
void Parma_Polyhedra_Library::Grid::add_congruences | ( | const Congruence_System & | cgs | ) |
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 1040 of file Grid_public.cc.
References add_recycled_congruences(), space_dim, Parma_Polyhedra_Library::Congruence_System::space_dimension(), and throw_dimension_incompatible().
Referenced by expand_space_dimension(), and limited_extrapolation_assign().
01040 { 01041 // TODO: this is just an executable specification. 01042 // The dimension of `cgs' must be at most `space_dim'. 01043 if (space_dim < cgs.space_dimension()) 01044 throw_dimension_incompatible("add_congruences(cgs)", "cgs", cgs); 01045 Congruence_System cgs_copy = cgs; 01046 add_recycled_congruences(cgs_copy); 01047 }
void Parma_Polyhedra_Library::Grid::add_congruences | ( | const Constraint_System & | cs | ) |
Adds a copy of each equality constraint in cs
to *this
.
cs | The congruences that will be considered for addition to the system of congruences of *this . |
std::invalid_argument | Thrown if *this and cgs are dimension-incompatible. |
Definition at line 1050 of file Grid_public.cc.
References add_recycled_congruences(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01050 { 01051 // TODO: this is just an executable specification. 01052 // The dimension of `cs' must be at most `space_dim'. 01053 if (space_dim < cs.space_dimension()) 01054 throw_dimension_incompatible("add_congruences(cs)", "cs", cs); 01055 Congruence_System cgs(cs); 01056 add_recycled_congruences(cgs); 01057 }
void Parma_Polyhedra_Library::Grid::add_recycled_congruences | ( | Congruence_System & | cgs | ) |
Adds the congruences in cgs
to *this.
cgs | The congruence system that will be recycled, adding its congruences to the system of congruences of *this . |
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 987 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(), marked_empty(), Parma_Polyhedra_Library::Matrix::num_rows(), 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(), and update_congruences().
Referenced by add_congruence(), add_congruences(), add_constraints(), add_recycled_congruences(), add_recycled_constraints(), generalized_affine_image(), generalized_affine_preimage(), and widening_assign().
00987 { 00988 // Dimension-compatibility check: the dimension of `cgs' can not be 00989 // greater than space_dim. 00990 const dimension_type cgs_space_dim = cgs.space_dimension(); 00991 if (space_dim < cgs_space_dim) 00992 throw_dimension_incompatible("add_recycled_congruences(cgs)", "cgs", cgs); 00993 00994 if (cgs.num_rows() == 0) 00995 return; 00996 00997 if (space_dim == 0) { 00998 // In a 0-dimensional space the congruences are trivial (e.g., 0 00999 // == 0 or 1 %= 0) or false (e.g., 1 == 0). In a system of 01000 // congruences `begin()' and `end()' are equal if and only if the 01001 // system contains only trivial congruences. 01002 if (cgs.begin() != cgs.end()) 01003 // There is a congruence, it must be false, the grid is empty. 01004 if (status.test_zero_dim_univ()) 01005 set_empty(); 01006 return; 01007 } 01008 01009 if (marked_empty()) { 01010 assert(OK()); 01011 return; 01012 } 01013 01014 // The congruences are required. 01015 congruences_are_up_to_date() || update_congruences(); 01016 01017 // Swap (instead of copying) the coefficients of `cgs' (which is 01018 // writable). 01019 con_sys.recycling_insert(cgs); 01020 01021 // Congruences may not be minimized and generators are out of date. 01022 clear_congruences_minimized(); 01023 clear_generators_up_to_date(); 01024 // Note: the congruence system may have become unsatisfiable, thus 01025 // we do not check for satisfiability. 01026 assert(OK()); 01027 }
void Parma_Polyhedra_Library::Grid::add_recycled_congruences | ( | Constraint_System & | cs | ) |
Adds the equality constraints in cs
to *this
.
cs | The constraint system from which constraints will be considered for addition to the system of congruences of *this . |
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 1030 of file Grid_public.cc.
References add_recycled_congruences(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01030 { 01031 // TODO: this is just an executable specification. 01032 // The dimension of `cs' must be at most `space_dim'. 01033 if (space_dim < cs.space_dimension()) 01034 throw_dimension_incompatible("add_recycled_congruences(cs)", "cs", cs); 01035 Congruence_System cgs(cs); 01036 add_recycled_congruences(cgs); 01037 }
bool Parma_Polyhedra_Library::Grid::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.
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 1116 of file Grid_public.cc.
References add_recycled_congruences_and_minimize().
01116 { 01117 // TODO: this is just an executable specification. 01118 Congruence_System cgs_copy = cgs; 01119 return add_recycled_congruences_and_minimize(cgs_copy); 01120 }
bool Parma_Polyhedra_Library::Grid::add_congruences_and_minimize | ( | const Constraint_System & | cs | ) |
Adds a copy of each equality constraint in cs
to *this
, reducing the result.
false
if and only if the result is empty.cs | Contains the constraints that will be added to the system of congruences of *this . |
std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
Definition at line 1123 of file Grid_public.cc.
References add_recycled_congruences_and_minimize(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01123 { 01124 // TODO: this is just an executable specification. 01125 // The dimension of `cs' must be at most `space_dim'. 01126 if (space_dim < cs.space_dimension()) 01127 throw_dimension_incompatible("add_congruences_and_minimize(cs)", "cs", cs); 01128 Congruence_System cgs(cs); 01129 return add_recycled_congruences_and_minimize(cgs); 01130 }
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 that will be recycled, adding its congruences to the system of congruences of *this . |
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 1060 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(), marked_empty(), minimize(), Parma_Polyhedra_Library::Matrix::num_rows(), 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(), add_congruences_and_minimize(), add_constraints_and_minimize(), add_recycled_congruences_and_minimize(), add_recycled_constraints_and_minimize(), generalized_affine_image(), and generalized_affine_preimage().
01060 { 01061 // Dimension-compatibility check: the dimension of `cgs' can not be 01062 // greater than space_dim. 01063 const dimension_type cgs_space_dim = cgs.space_dimension(); 01064 if (space_dim < cgs_space_dim) 01065 throw_dimension_incompatible("add_recycled_congruences_and_minimize(cgs)", 01066 "cgs", cgs); 01067 01068 // Adding no congruences: just minimize. 01069 if (cgs.num_rows() == 0) 01070 return minimize(); 01071 01072 // Dealing with zero-dimensional space grids first. 01073 if (space_dim == 0) { 01074 // In a 0-dimensional space the congruences are trivial (e.g., 0 01075 // == 0 or 1 %= 0) or false (e.g., 1 == 0). In a system of 01076 // congruences `begin()' and `end()' are equal if and only if the 01077 // system contains only trivial congruences. 01078 if (cgs.begin() == cgs.end()) 01079 return true; 01080 // There is a congruence, it must be false, the grid is empty. 01081 if (status.test_zero_dim_univ()) 01082 set_empty(); 01083 return false; 01084 } 01085 01086 if (marked_empty()) 01087 return false; 01088 01089 congruences_are_up_to_date() || update_congruences(); 01090 01091 con_sys.recycling_insert(cgs); 01092 01093 clear_congruences_minimized(); 01094 01095 #ifndef NDEBUG 01096 bool ret = update_generators(); 01097 assert(OK()); 01098 return ret; 01099 #else 01100 return update_generators(); 01101 #endif 01102 }
bool Parma_Polyhedra_Library::Grid::add_recycled_congruences_and_minimize | ( | Constraint_System & | cs | ) |
Adds the equalities in cs
to *this
, reducing the result.
false
if and only if the result is empty.cs | The constraint system that will be recycled, adding its equalities to the system of congruences of *this . |
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 1105 of file Grid_public.cc.
References add_recycled_congruences_and_minimize(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01105 { 01106 // TODO: this is just an executable specification. 01107 // The dimension of `cs' must be at most `space_dim'. 01108 if (space_dim < cs.space_dimension()) 01109 throw_dimension_incompatible("add_recycled_congruences_and_minimize(cs)", 01110 "cs", cs); 01111 Congruence_System cgs(cs); 01112 return add_recycled_congruences_and_minimize(cgs); 01113 }
void Parma_Polyhedra_Library::Grid::add_constraint | ( | const Constraint & | c | ) |
Adds constraint c
to *this
.
The addition can only affect *this
if c
is an equality.
std::invalid_argument | Thrown if *this and c are dimension-incompatible. |
Definition at line 1133 of file Grid_public.cc.
References add_congruence(), Parma_Polyhedra_Library::Constraint::is_equality(), space_dim, Parma_Polyhedra_Library::Constraint::space_dimension(), and throw_dimension_incompatible().
01133 { 01134 // The dimension of `c' must be at most `space_dim'. 01135 if (space_dim < c.space_dimension()) 01136 throw_dimension_incompatible("add_constraint(c)", "c", c); 01137 if (c.is_equality()) { 01138 Congruence cg(c); 01139 add_congruence(cg); 01140 } 01141 }
bool Parma_Polyhedra_Library::Grid::add_constraint_and_minimize | ( | const Constraint & | c | ) |
Adds constraint c
to *this
, reducing the result.
The addition can only affect *this
if c
is an equality.
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and c are dimension-incompatible. |
Definition at line 1144 of file Grid_public.cc.
References add_congruence_and_minimize(), Parma_Polyhedra_Library::Constraint::is_equality(), minimize(), space_dim, Parma_Polyhedra_Library::Constraint::space_dimension(), and throw_dimension_incompatible().
01144 { 01145 // The dimension of `c' must be at most `space_dim'. 01146 if (space_dim < c.space_dimension()) 01147 throw_dimension_incompatible("add_constraint_and_minimize(c)", "c", c); 01148 if (c.is_equality()) { 01149 Congruence cg(c); 01150 return add_congruence_and_minimize(cg); 01151 } 01152 return minimize(); 01153 }
void Parma_Polyhedra_Library::Grid::add_constraints | ( | const Constraint_System & | cs | ) |
Adds copies of the equality constraints in cs
to *this
.
std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
Definition at line 1156 of file Grid_public.cc.
References add_recycled_congruences(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01156 { 01157 // The dimension of `cs' must be at most `space_dim'. 01158 if (space_dim < cs.space_dimension()) 01159 throw_dimension_incompatible("add_constraints(cs)", "cs", cs); 01160 Congruence_System cgs(cs); 01161 add_recycled_congruences(cgs); 01162 }
bool Parma_Polyhedra_Library::Grid::add_constraints_and_minimize | ( | const Constraint_System & | cs | ) |
Adds copies of the equality constraints in cs
to *this
, reducing the result.
false
if and only if the result is empty.std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
Definition at line 1165 of file Grid_public.cc.
References add_recycled_congruences_and_minimize(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01165 { 01166 // The dimension of `cs' must be at most `space_dim'. 01167 if (space_dim < cs.space_dimension()) 01168 throw_dimension_incompatible("add_constraints_and_minimize(cs)", 01169 "cs", cs); 01170 Congruence_System cgs(cs); 01171 return add_recycled_congruences_and_minimize(cgs); 01172 }
void Parma_Polyhedra_Library::Grid::add_recycled_constraints | ( | Constraint_System & | cs | ) |
Adds the equality constraints in cs
to *this
.
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 1175 of file Grid_public.cc.
References add_recycled_congruences(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01175 { 01176 // The dimension of `cs' must be at most `space_dim'. 01177 if (space_dim < cs.space_dimension()) 01178 throw_dimension_incompatible("add_recycled_constraints(cs)", 01179 "cs", cs); 01180 Congruence_System cgs(cs); 01181 add_recycled_congruences(cgs); 01182 }
bool Parma_Polyhedra_Library::Grid::add_recycled_constraints_and_minimize | ( | Constraint_System & | cs | ) |
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 1185 of file Grid_public.cc.
References add_recycled_congruences_and_minimize(), space_dim, Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
01185 { 01186 // The dimension of `cs' must be at most `space_dim'. 01187 if (space_dim < cs.space_dimension()) 01188 throw_dimension_incompatible("add_recycled_constraints_and_minimize(cs)", 01189 "cs", cs); 01190 Congruence_System cgs(cs); 01191 return add_recycled_congruences_and_minimize(cgs); 01192 }
void Parma_Polyhedra_Library::Grid::add_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 1255 of file Grid_public.cc.
References add_recycled_generators().
01255 { 01256 // TODO: this is just an executable specification. 01257 Grid_Generator_System gs_copy = gs; 01258 add_recycled_generators(gs_copy); 01259 }
void Parma_Polyhedra_Library::Grid::add_recycled_generators | ( | Grid_Generator_System & | gs | ) |
Adds the generators in gs
to the system of generators of this
.
gs | The generator system that will be recycled, adding its generators 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. |
gs
upon successful or exceptional return is that it can be safely destroyed. Definition at line 1195 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::has_points(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), marked_empty(), normalize_divisors(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), 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(), throw_dimension_incompatible(), throw_invalid_generators(), and update_generators().
Referenced by add_generators(), generalized_affine_image(), and generalized_affine_preimage().
01195 { 01196 // Dimension-compatibility check: 01197 // the dimension of `gs' can not be greater than space_dim. 01198 const dimension_type gs_space_dim = gs.space_dimension(); 01199 if (space_dim < gs_space_dim) 01200 throw_dimension_incompatible("add_recycled_generators(gs)", "gs", gs); 01201 01202 // Adding no generators leaves the grid the same. 01203 if (gs.num_generators() == 0) 01204 return; 01205 01206 // Adding valid generators to a zero-dimensional grid transforms it 01207 // to the zero-dimensional universe grid. 01208 if (space_dim == 0) { 01209 if (marked_empty()) 01210 if (gs.has_points()) 01211 set_zero_dim_univ(); 01212 else 01213 throw_invalid_generators("add_recycled_generators(gs)", "gs"); 01214 assert(OK(true)); 01215 return; 01216 } 01217 01218 if (!marked_empty() 01219 && (generators_are_up_to_date() || update_generators())) { 01220 // The grid contains at least one point. 01221 01222 normalize_divisors(gs, gen_sys); 01223 01224 gen_sys.recycling_insert(gs); 01225 01226 // Congruences are out of date and generators are not minimized. 01227 clear_congruences_up_to_date(); 01228 clear_generators_minimized(); 01229 01230 assert(OK(true)); 01231 return; 01232 } 01233 01234 // The grid is empty. 01235 01236 // `gs' must contain at least one point. 01237 if (!gs.has_points()) 01238 throw_invalid_generators("add_recycled_generators(gs)", "gs"); 01239 01240 // Adjust `gs' to the right dimension. 01241 gs.insert(parameter(0*Variable(space_dim-1))); 01242 01243 std::swap(gen_sys, gs); 01244 01245 normalize_divisors(gen_sys); 01246 01247 // The grid is no longer empty and generators are up-to-date. 01248 set_generators_up_to_date(); 01249 clear_empty(); 01250 01251 assert(OK()); 01252 }
bool Parma_Polyhedra_Library::Grid::add_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 1315 of file Grid_public.cc.
References add_recycled_generators_and_minimize().
01315 { 01316 // TODO: this is just an executable specification. 01317 Grid_Generator_System gs_copy = gs; 01318 return add_recycled_generators_and_minimize(gs_copy); 01319 }
bool Parma_Polyhedra_Library::Grid::add_recycled_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 that will be recycled, adding its generators 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. |
gs
upon successful or exceptional return is that it can be safely destroyed. Definition at line 1262 of file Grid_public.cc.
References clear_empty(), clear_generators_minimized(), gen_sys, generators_are_up_to_date(), 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_generators(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), throw_dimension_incompatible(), throw_invalid_generators(), update_congruences(), and update_generators().
Referenced by add_generator_and_minimize(), and add_generators_and_minimize().
01262 { 01263 // Dimension-compatibility check: the dimension of `gs' must be less 01264 // than or equal to that of space_dim. 01265 const dimension_type gs_space_dim = gs.space_dimension(); 01266 if (space_dim < gs_space_dim) 01267 throw_dimension_incompatible("add_recycled_generators_and_minimize(gs)", 01268 "gs", gs); 01269 01270 // Adding no generators is equivalent to just requiring reduction. 01271 if (gs.num_generators() == 0) 01272 return minimize(); 01273 01274 // Adding valid generators to a zero-dimensional grid produces the 01275 // zero-dimensional universe grid. 01276 if (space_dim == 0) { 01277 if (marked_empty()) 01278 if (gs.has_points()) 01279 set_zero_dim_univ(); 01280 else 01281 throw_invalid_generators("add_recycled_generators_and_minimize(gs)", 01282 "gs"); 01283 assert(OK(true)); 01284 return true; 01285 } 01286 01287 // Adjust `gs' to the right dimension. 01288 gs.insert(parameter(0*Variable(space_dim-1))); 01289 01290 if (!marked_empty() 01291 && (generators_are_up_to_date() || update_generators())) { 01292 // The grid contains at least one point. 01293 normalize_divisors(gs, gen_sys); 01294 01295 for (dimension_type row = 0; row < gs.num_generators(); ++row) 01296 gen_sys.recycling_insert(gs[row]); 01297 } 01298 else { 01299 // The grid is empty: check if `gs' contains a point. 01300 if (!gs.has_points()) 01301 throw_invalid_generators("add_recycled_generators_and_minimize(gs)", 01302 "gs"); 01303 std::swap(gen_sys, gs); 01304 normalize_divisors(gen_sys); 01305 clear_empty(); 01306 } 01307 clear_generators_minimized(); 01308 update_congruences(); 01309 01310 assert(OK(true)); 01311 return true; 01312 }
void Parma_Polyhedra_Library::Grid::intersection_assign | ( | const Grid & | y | ) |
Assigns to *this
the intersection of *this
and y
. The result is not guaranteed to be reduced.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1322 of file Grid_public.cc.
References clear_congruences_minimized(), clear_generators_up_to_date(), con_sys, congruences_are_up_to_date(), Parma_Polyhedra_Library::Congruence_System::insert(), marked_empty(), Parma_Polyhedra_Library::Matrix::num_rows(), OK(), set_empty(), space_dim, throw_dimension_incompatible(), and update_congruences().
Referenced by intersection_assign_and_minimize().
01322 { 01323 Grid& x = *this; 01324 // Dimension-compatibility check. 01325 if (x.space_dim != y.space_dim) 01326 throw_dimension_incompatible("intersection_assign(y)", "y", y); 01327 01328 // If one of the two grids is empty, the intersection is empty. 01329 if (x.marked_empty()) 01330 return; 01331 if (y.marked_empty()) { 01332 x.set_empty(); 01333 return; 01334 } 01335 01336 // If both grids are zero-dimensional, then at this point they are 01337 // necessarily universe, so the intersection is also universe. 01338 if (x.space_dim == 0) 01339 return; 01340 01341 // The congruences must be up-to-date. 01342 x.congruences_are_up_to_date() || x.update_congruences(); 01343 y.congruences_are_up_to_date() || y.update_congruences(); 01344 01345 if (y.con_sys.num_rows() > 0 ) { 01346 x.con_sys.insert(y.con_sys); 01347 // Grid_Generators may be out of date and congruences may have changed 01348 // from minimal form. 01349 x.clear_generators_up_to_date(); 01350 x.clear_congruences_minimized(); 01351 } 01352 01353 // `y' should still contain a point. 01354 assert(x.OK() && y.OK(true)); 01355 }
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 1358 of file Grid_public.cc.
References intersection_assign(), and minimize().
Referenced by is_disjoint_from().
01358 { 01359 intersection_assign(y); 01360 return minimize(); 01361 }
void Parma_Polyhedra_Library::Grid::join_assign | ( | const Grid & | y | ) |
Assigns to *this
the join of *this
and y
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Definition at line 1364 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 fold_space_dimensions(), grid_difference_assign(), join_assign_and_minimize(), join_assign_if_exact(), and upper_bound_assign().
01364 { 01365 Grid& x = *this; 01366 // Dimension-compatibility check. 01367 if (x.space_dim != y.space_dim) 01368 throw_dimension_incompatible("join_assign(y)", "y", y); 01369 01370 // The join of a grid `gr' with an empty grid is `gr'. 01371 if (y.marked_empty()) 01372 return; 01373 if (x.marked_empty()) { 01374 x = y; 01375 return; 01376 } 01377 01378 // If both grids are zero-dimensional, then they are necessarily 01379 // universe grids, and so is their join. 01380 if (x.space_dim == 0) 01381 return; 01382 01383 // The generators must be up-to-date. 01384 if (!x.generators_are_up_to_date() && !x.update_generators()) { 01385 // Discovered `x' empty when updating generators. 01386 x = y; 01387 return; 01388 } 01389 if (!y.generators_are_up_to_date() && !y.update_generators()) 01390 // Discovered `y' empty when updating generators. 01391 return; 01392 01393 // Match the divisors of the x and y generator systems. 01394 Grid_Generator_System gs(y.gen_sys); 01395 normalize_divisors(x.gen_sys, gs); 01396 x.gen_sys.recycling_insert(gs); 01397 // Congruences may be out of date and generators may have lost 01398 // minimal form. 01399 x.clear_congruences_up_to_date(); 01400 x.clear_generators_minimized(); 01401 01402 // At this point both `x' and `y' are not empty. 01403 assert(x.OK(true) && y.OK(true)); 01404 }
bool Parma_Polyhedra_Library::Grid::join_assign_and_minimize | ( | const Grid & | y | ) |
Assigns to *this
the join 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 1407 of file Grid_public.cc.
References join_assign(), and minimize().
01407 { 01408 join_assign(y); 01409 return minimize(); 01410 }
void Parma_Polyhedra_Library::Grid::upper_bound_assign | ( | const Grid & | y | ) | [inline] |
Same as join_assign(y).
Definition at line 104 of file Grid.inlines.hh.
References join_assign().
00104 { 00105 join_assign(y); 00106 }
bool Parma_Polyhedra_Library::Grid::join_assign_if_exact | ( | const Grid & | y | ) |
If the join 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 1413 of file Grid_public.cc.
References grid_difference_assign(), is_included_in(), join_assign(), marked_empty(), space_dim, and throw_dimension_incompatible().
Referenced by upper_bound_assign_if_exact().
01413 { 01414 Grid& x = *this; 01415 01416 // Dimension-compatibility check. 01417 if (x.space_dim != y.space_dim) 01418 throw_dimension_incompatible("join_assign_if_exact(y)", "y", y); 01419 01420 if (x.marked_empty() 01421 || y.marked_empty() 01422 || x.space_dim == 0 01423 || x.is_included_in(y) 01424 || y.is_included_in(x)) { 01425 join_assign(y); 01426 return true; 01427 } 01428 01429 Grid x_copy = x; 01430 x_copy.join_assign(y); 01431 x_copy.grid_difference_assign(y); 01432 if (x_copy.is_included_in(x)) { 01433 join_assign(y); 01434 return true; 01435 } 01436 01437 return false; 01438 }
bool Parma_Polyhedra_Library::Grid::upper_bound_assign_if_exact | ( | const Grid & | y | ) | [inline] |
Same as join_assign_if_exact(y).
Definition at line 109 of file Grid.inlines.hh.
References join_assign_if_exact().
00109 { 00110 return join_assign_if_exact(y); 00111 }
void Parma_Polyhedra_Library::Grid::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 1441 of file Grid_public.cc.
References add_congruence(), 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(), join_assign(), marked_empty(), Parma_Polyhedra_Library::Congruence::modulus(), OK(), relation_with(), set_empty(), space_dim, and throw_dimension_incompatible().
Referenced by difference_assign(), and join_assign_if_exact().
01441 { 01442 Grid& x = *this; 01443 // Dimension-compatibility check. 01444 if (x.space_dim != y.space_dim) 01445 throw_dimension_incompatible("poly_difference_assign(y)", "y", y); 01446 01447 if (y.marked_empty() || x.marked_empty()) 01448 return; 01449 01450 // If both grids are zero-dimensional, then they are necessarily 01451 // universe grids, so the result is empty. 01452 if (x.space_dim == 0) { 01453 x.set_empty(); 01454 return; 01455 } 01456 01457 if (y.contains(x)) { 01458 x.set_empty(); 01459 return; 01460 } 01461 01462 Grid new_grid(x.space_dim, EMPTY); 01463 01464 const Congruence_System& y_cgs = y.congruences(); 01465 for (Congruence_System::const_iterator i = y_cgs.begin(), 01466 y_cgs_end = y_cgs.end(); i != y_cgs_end; ++i) { 01467 const Congruence& cg = *i; 01468 01469 // The 2-complement cg2 of cg = ((e %= 0) / m) is the congruence 01470 // defining the sets of points exactly half-way between successive 01471 // hyperplanes e = km and e = (k+1)m, for any integer k; that is, 01472 // the hyperplanes defined by 2e = (2k + 1)m, for any integer k. 01473 // Thus `cg2' is the congruence ((2e %= m) / 2m). 01474 01475 // As the grid difference must be a grid, only add the 01476 // 2-complement congruence to x if the resulting grid includes all 01477 // the points in x that did not satisfy `cg'. 01478 01479 // The 2-complement of cg can be included in the result only if x 01480 // holds points other than those in cg. 01481 if (x.relation_with(cg).implies(Poly_Con_Relation::is_included())) 01482 continue; 01483 01484 if (cg.is_proper_congruence()) { 01485 const Linear_Expression e = Linear_Expression(cg); 01486 // Congruence cg is ((e %= 0) / m). 01487 Coefficient_traits::const_reference m = cg.modulus(); 01488 // If x is included in the grid defined by the congruences cg 01489 // and its 2-complement (i.e. the grid defined by the congruence 01490 // (2e %= 0) / m) then add the 2-complement to the potential 01491 // result. 01492 if (x.relation_with((2*e %= 0) / m) 01493 .implies(Poly_Con_Relation::is_included())) { 01494 Grid z = x; 01495 z.add_congruence((2*e %= m) / (2*m)); 01496 new_grid.join_assign(z); 01497 continue; 01498 } 01499 } 01500 return; 01501 } 01502 01503 *this = new_grid; 01504 01505 assert(OK()); 01506 }
void Parma_Polyhedra_Library::Grid::difference_assign | ( | const Grid & | y | ) | [inline] |
Same as grid_difference_assign(y).
Definition at line 114 of file Grid.inlines.hh.
References grid_difference_assign().
00114 { 00115 grid_difference_assign(y); 00116 }
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 1509 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().
01511 { 01512 // The denominator cannot be zero. 01513 if (denominator == 0) 01514 throw_invalid_argument("affine_image(v, e, d)", "d == 0"); 01515 01516 // Dimension-compatibility checks. 01517 // The dimension of `expr' must be at most the dimension of `*this'. 01518 const dimension_type expr_space_dim = expr.space_dimension(); 01519 if (space_dim < expr_space_dim) 01520 throw_dimension_incompatible("affine_image(v, e, d)", "e", expr); 01521 // `var' must be one of the dimensions of the grid. 01522 const dimension_type var_space_dim = var.space_dimension(); 01523 if (space_dim < var_space_dim) 01524 throw_dimension_incompatible("affine_image(v, e, d)", "v", var); 01525 01526 if (marked_empty()) 01527 return; 01528 01529 if (var_space_dim <= expr_space_dim && expr[var_space_dim] != 0) { 01530 // The transformation is invertible. 01531 if (generators_are_up_to_date()) { 01532 // Grid_Generator_System::affine_image() requires the third argument 01533 // to be a positive Coefficient. 01534 if (denominator > 0) 01535 gen_sys.affine_image(var_space_dim, expr, denominator); 01536 else 01537 gen_sys.affine_image(var_space_dim, -expr, -denominator); 01538 clear_generators_minimized(); 01539 // Strong normalization in gs::affine_image may have modified 01540 // divisors. 01541 normalize_divisors(gen_sys); 01542 } 01543 if (congruences_are_up_to_date()) { 01544 // To build the inverse transformation, 01545 // after copying and negating `expr', 01546 // we exchange the roles of `expr[var_space_dim]' and `denominator'. 01547 Linear_Expression inverse; 01548 if (expr[var_space_dim] > 0) { 01549 inverse = -expr; 01550 inverse[var_space_dim] = denominator; 01551 con_sys.affine_preimage(var_space_dim, inverse, expr[var_space_dim]); 01552 } 01553 else { 01554 // The new denominator is negative: 01555 // we negate everything once more, as Congruence_System::affine_preimage() 01556 // requires the third argument to be positive. 01557 inverse = expr; 01558 inverse[var_space_dim] = denominator; 01559 neg_assign(inverse[var_space_dim]); 01560 con_sys.affine_preimage(var_space_dim, inverse, -expr[var_space_dim]); 01561 } 01562 clear_congruences_minimized(); 01563 } 01564 } 01565 else { 01566 // The transformation is not invertible. 01567 // We need an up-to-date system of generators. 01568 if (!generators_are_up_to_date()) 01569 minimize(); 01570 if (!marked_empty()) { 01571 // Grid_Generator_System::affine_image() requires the third argument 01572 // to be a positive Coefficient. 01573 if (denominator > 0) 01574 gen_sys.affine_image(var_space_dim, expr, denominator); 01575 else 01576 gen_sys.affine_image(var_space_dim, -expr, -denominator); 01577 01578 clear_congruences_up_to_date(); 01579 clear_generators_minimized(); 01580 // Strong normalization in gs::affine_image may have modified 01581 // divisors. 01582 normalize_divisors(gen_sys); 01583 } 01584 } 01585 assert(OK()); 01586 }
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 1590 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().
01592 { 01593 // The denominator cannot be zero. 01594 if (denominator == 0) 01595 throw_invalid_argument("affine_preimage(v, e, d)", "d == 0"); 01596 01597 // Dimension-compatibility checks. 01598 // The dimension of `expr' should not be greater than the dimension 01599 // of `*this'. 01600 const dimension_type expr_space_dim = expr.space_dimension(); 01601 if (space_dim < expr_space_dim) 01602 throw_dimension_incompatible("affine_preimage(v, e, d)", "e", expr); 01603 // `var' should be one of the dimensions of the polyhedron. 01604 const dimension_type var_space_dim = var.space_dimension(); 01605 if (space_dim < var_space_dim) 01606 throw_dimension_incompatible("affine_preimage(v, e, d)", "v", var); 01607 01608 if (marked_empty()) 01609 return; 01610 01611 if (var_space_dim <= expr_space_dim && expr[var_space_dim] != 0) { 01612 // The transformation is invertible. 01613 if (congruences_are_up_to_date()) { 01614 // Congruence_System::affine_preimage() requires the third argument 01615 // to be a positive Coefficient. 01616 if (denominator > 0) 01617 con_sys.affine_preimage(var_space_dim, expr, denominator); 01618 else 01619 con_sys.affine_preimage(var_space_dim, -expr, -denominator); 01620 clear_congruences_minimized(); 01621 } 01622 if (generators_are_up_to_date()) { 01623 // To build the inverse transformation, 01624 // after copying and negating `expr', 01625 // we exchange the roles of `expr[var_space_dim]' and `denominator'. 01626 Linear_Expression inverse; 01627 if (expr[var_space_dim] > 0) { 01628 inverse = -expr; 01629 inverse[var_space_dim] = denominator; 01630 gen_sys.affine_image(var_space_dim, inverse, expr[var_space_dim]); 01631 } 01632 else { 01633 // The new denominator is negative: 01634 // we negate everything once more, as Grid_Generator_System::affine_image() 01635 // requires the third argument to be positive. 01636 inverse = expr; 01637 inverse[var_space_dim] = denominator; 01638 neg_assign(inverse[var_space_dim]); 01639 gen_sys.affine_image(var_space_dim, inverse, -expr[var_space_dim]); 01640 } 01641 clear_generators_minimized(); 01642 } 01643 } 01644 else { 01645 // The transformation is not invertible. 01646 // We need an up-to-date system of congruences. 01647 if (!congruences_are_up_to_date()) 01648 minimize(); 01649 // Congruence_System::affine_preimage() requires the third argument 01650 // to be a positive Coefficient. 01651 if (denominator > 0) 01652 con_sys.affine_preimage(var_space_dim, expr, denominator); 01653 else 01654 con_sys.affine_preimage(var_space_dim, -expr, -denominator); 01655 01656 clear_generators_up_to_date(); 01657 clear_congruences_minimized(); 01658 } 01659 assert(OK()); 01660 }
void Parma_Polyhedra_Library::Grid::generalized_affine_image | ( | Variable | var, | |
const Linear_Expression & | expr, | |||
Coefficient_traits::const_reference | denominator = Coefficient_one() , |
|||
Coefficient_traits::const_reference | modulus = Coefficient_one() | |||
) |
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; | |
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 one. |
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 1664 of file Grid_public.cc.
References affine_image(), clear_congruences_up_to_date(), clear_generators_minimized(), 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 generalized_affine_preimage().
01667 { 01668 // The denominator cannot be zero. 01669 if (denominator == 0) 01670 throw_invalid_argument("generalized_affine_image(v, r, e, d)", "d == 0"); 01671 01672 // Dimension-compatibility checks. 01673 // The dimension of `expr' should not be greater than the dimension 01674 // of `*this'. 01675 const dimension_type expr_space_dim = expr.space_dimension(); 01676 if (space_dim < expr_space_dim) 01677 throw_dimension_incompatible("generalized_affine_image(v, r, e, d)", 01678 "e", expr); 01679 // `var' should be one of the dimensions of the grid. 01680 const dimension_type var_space_dim = var.space_dimension(); 01681 if (space_dim < var_space_dim) 01682 throw_dimension_incompatible("generalized_affine_image(v, r, e, d)", 01683 "v", var); 01684 01685 // Any image of an empty grid is empty. 01686 if (marked_empty()) 01687 return; 01688 01689 affine_image(var, expr, denominator); 01690 01691 if (modulus == 0) 01692 return; 01693 01694 // Modulate dimension `var' according to `modulus'. 01695 01696 generators_are_up_to_date() || minimize(); 01697 01698 // Test if minimization, possibly in affine_image, found an empty 01699 // grid. 01700 if (marked_empty()) 01701 return; 01702 01703 if (modulus < 0) 01704 gen_sys.insert(parameter(-modulus * var)); 01705 else 01706 gen_sys.insert(parameter(modulus * var)); 01707 01708 normalize_divisors(gen_sys); 01709 01710 clear_generators_minimized(); 01711 clear_congruences_up_to_date(); 01712 01713 assert(OK()); 01714 }
void Parma_Polyhedra_Library::Grid::generalized_affine_preimage | ( | Variable | var, | |
const Linear_Expression & | expr, | |||
Coefficient_traits::const_reference | denominator = Coefficient_one() , |
|||
Coefficient_traits::const_reference | modulus = Coefficient_one() | |||
) |
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; | |
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 one. |
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 1717 of file Grid_public.cc.
References add_congruence(), add_generator(), affine_preimage(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), generalized_affine_image(), is_empty(), OK(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), Parma_Polyhedra_Library::Linear_Expression::space_dimension(), throw_dimension_incompatible(), and throw_invalid_argument().
01720 { 01721 // The denominator cannot be zero. 01722 if (denominator == 0) 01723 throw_invalid_argument("generalized_affine_preimage(v, e, d, m)", 01724 "d == 0"); 01725 01726 // The dimension of `expr' should be at most the dimension of 01727 // `*this'. 01728 const dimension_type expr_space_dim = expr.space_dimension(); 01729 if (space_dim < expr_space_dim) 01730 throw_dimension_incompatible("generalized_affine_preimage(v, e, d, m)", 01731 "e", expr); 01732 // `var' should be one of the dimensions of the grid. 01733 const dimension_type var_space_dim = var.space_dimension(); 01734 if (space_dim < var_space_dim) 01735 throw_dimension_incompatible("generalized_affine_preimage(v, e, d, m)", 01736 "v", var); 01737 01738 // Check whether the affine relation is an affine function. 01739 if (modulus == 0) { 01740 affine_preimage(var, expr, denominator); 01741 return; 01742 } 01743 01744 // Check whether the preimage of this affine relation can be easily 01745 // computed as the image of its inverse relation. 01746 Coefficient_traits::const_reference var_coefficient = expr.coefficient(var); 01747 if (var_space_dim <= expr_space_dim && var_coefficient != 0) { 01748 Linear_Expression inverse_expr 01749 = expr - (denominator + var_coefficient) * var; 01750 Coefficient inverse_denominator = - var_coefficient; 01751 if (modulus < 0) 01752 generalized_affine_image(var, inverse_expr, inverse_denominator, 01753 - modulus); 01754 else 01755 generalized_affine_image(var, inverse_expr, inverse_denominator, 01756 modulus); 01757 return; 01758 } 01759 01760 // Here `var_coefficient == 0', so that the preimage cannot be 01761 // easily computed by inverting the affine relation. Add the 01762 // congruence induced by the affine relation. 01763 if (modulus < 0) 01764 add_congruence((denominator*var %= expr) / denominator /= - modulus); 01765 else 01766 add_congruence((denominator*var %= expr) / denominator /= modulus); 01767 01768 // If the resulting grid is empty, its preimage is empty too. 01769 // Note: DO check for emptyness here, as we will later add a line. 01770 if (is_empty()) 01771 return; 01772 add_generator(grid_line(var)); 01773 assert(OK()); 01774 }
void Parma_Polyhedra_Library::Grid::generalized_affine_image | ( | const Linear_Expression & | lhs, | |
const Linear_Expression & | rhs, | |||
Coefficient_traits::const_reference | modulus = Coefficient_one() | |||
) |
Assigns to *this
the image of *this
with respect to the generalized affine relation .
lhs | The left hand side affine expression. | |
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 one. |
std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs . |
Definition at line 1778 of file Grid_public.cc.
References add_congruence(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_generators(), add_space_dimensions_and_embed(), clear_congruences_up_to_date(), clear_generators_minimized(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), gen_sys, Parma_Polyhedra_Library::Grid_Generator_System::insert(), is_empty(), Parma_Polyhedra_Library::Grid_Generator::line(), marked_empty(), 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, and throw_dimension_incompatible().
01780 { 01781 // Dimension-compatibility checks. 01782 // The dimension of `lhs' should be at most the dimension of 01783 // `*this'. 01784 dimension_type lhs_space_dim = lhs.space_dimension(); 01785 if (space_dim < lhs_space_dim) 01786 throw_dimension_incompatible("generalized_affine_image(e1, r, e2)", 01787 "e1", lhs); 01788 // The dimension of `rhs' should be at most the dimension of 01789 // `*this'. 01790 const dimension_type rhs_space_dim = rhs.space_dimension(); 01791 if (space_dim < rhs_space_dim) 01792 throw_dimension_incompatible("generalized_affine_image(e1, r, e2)", 01793 "e2", rhs); 01794 01795 // Any image of an empty grid is empty. 01796 if (marked_empty()) 01797 return; 01798 01799 TEMP_INTEGER(mod); 01800 if (modulus < 0) 01801 mod = -modulus; 01802 else 01803 mod = modulus; 01804 01805 // Compute the actual space dimension of `lhs', 01806 // i.e., the highest dimension having a non-zero coefficient in `lhs'. 01807 do { 01808 if (lhs_space_dim == 0) { 01809 // All variables have zero coefficients, so `lhs' is a constant. 01810 add_congruence((lhs %= rhs) / mod); 01811 return; 01812 } 01813 } 01814 while (lhs.coefficient(Variable(--lhs_space_dim)) == 0); 01815 01816 // Gather in `new_lines' the collections of all the lines having the 01817 // direction of variables occurring in `lhs'. While at it, check 01818 // whether there exists a variable occurring in both `lhs' and 01819 // `rhs'. 01820 Grid_Generator_System new_lines; 01821 bool lhs_vars_intersect_rhs_vars = false; 01822 for (dimension_type i = lhs_space_dim + 1; i-- > 0; ) 01823 if (lhs.coefficient(Variable(i)) != 0) { 01824 new_lines.insert(Grid_Generator::line(Variable(i))); 01825 if (rhs.coefficient(Variable(i)) != 0) 01826 lhs_vars_intersect_rhs_vars = true; 01827 } 01828 01829 if (lhs_vars_intersect_rhs_vars) { 01830 // Some variables in `lhs' also occur in `rhs'. 01831 // To ease the computation, add an additional dimension. 01832 const Variable new_var = Variable(space_dim); 01833 add_space_dimensions_and_embed(1); 01834 01835 // Constrain the new dimension to be equal to the right hand side. 01836 // TODO: Use add_congruence_and_minimize() when it has been updated. 01837 Congruence_System new_cgs1(new_var == rhs); 01838 if (add_recycled_congruences_and_minimize(new_cgs1)) { 01839 // The grid still contains points. 01840 01841 // Cylindrificate on all the variables occurring in the left 01842 // hand side expression. 01843 01844 // Ajust `new_lines' to the right dimension. 01845 new_lines.insert(parameter(0*Variable(space_dim-1))); 01846 // Add the lines to `gen_sys'. 01847 gen_sys.recycling_insert(new_lines); 01848 normalize_divisors(gen_sys); 01849 // Update the flags. 01850 clear_congruences_up_to_date(); 01851 clear_generators_minimized(); 01852 01853 // Constrain the new dimension so that it is congruent to the left 01854 // hand side expression modulo `mod'. 01855 // TODO: Use add_congruence() when it has been updated. 01856 Congruence_System new_cgs2((lhs %= new_var) / mod); 01857 add_recycled_congruences(new_cgs2); 01858 } 01859 01860 // Remove the temporarily added dimension. 01861 remove_higher_space_dimensions(space_dim-1); 01862 } 01863 else { 01864 // `lhs' and `rhs' variables are disjoint: 01865 // there is no need to add a further dimension. 01866 01867 // Only add the lines and congruence if there are points. 01868 if (is_empty()) 01869 return; 01870 01871 // Cylindrificate on all the variables occurring in the left hand 01872 // side expression. 01873 add_recycled_generators(new_lines); 01874 01875 // Constrain the left hand side expression so that it is congruent to 01876 // the right hand side expression modulo `mod'. 01877 add_congruence((lhs %= rhs) / mod); 01878 } 01879 01880 assert(OK()); 01881 }
void Parma_Polyhedra_Library::Grid::generalized_affine_preimage | ( | const Linear_Expression & | lhs, | |
const Linear_Expression & | rhs, | |||
Coefficient_traits::const_reference | modulus = Coefficient_one() | |||
) |
Assigns to *this
the preimage of *this
with respect to the generalized affine relation .
lhs | The left hand side affine expression; | |
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 one. |
std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs . |
Definition at line 1884 of file Grid_public.cc.
References add_congruence(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_generators(), add_space_dimensions_and_embed(), clear_congruences_up_to_date(), clear_generators_minimized(), Parma_Polyhedra_Library::Linear_Expression::coefficient(), gen_sys, Parma_Polyhedra_Library::Grid_Generator_System::insert(), is_empty(), Parma_Polyhedra_Library::Grid_Generator::line(), marked_empty(), 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, and throw_dimension_incompatible().
01886 { 01887 // The dimension of `lhs' must be at most the dimension of `*this'. 01888 dimension_type lhs_space_dim = lhs.space_dimension(); 01889 if (space_dim < lhs_space_dim) 01890 throw_dimension_incompatible("generalized_affine_preimage(e1, e2, m)", 01891 "lhs", lhs); 01892 // The dimension of `rhs' must be at most the dimension of `*this'. 01893 const dimension_type rhs_space_dim = rhs.space_dimension(); 01894 if (space_dim < rhs_space_dim) 01895 throw_dimension_incompatible("generalized_affine_preimage(e1, e2, m)", 01896 "e2", rhs); 01897 01898 // Any preimage of an empty polyhedron is empty. 01899 if (marked_empty()) 01900 return; 01901 01902 TEMP_INTEGER(mod); 01903 if (modulus < 0) 01904 mod = -modulus; 01905 else 01906 mod = modulus; 01907 01908 // Compute the actual space dimension of `lhs', 01909 // i.e., the highest dimension having a non-zero coefficient in `lhs'. 01910 do { 01911 if (lhs_space_dim == 0) { 01912 // All variables have zero coefficients, so `lhs' is a constant. 01913 // In this case, preimage and image happen to be the same. 01914 add_congruence((lhs %= rhs) / mod); 01915 return; 01916 } 01917 } 01918 while (lhs.coefficient(Variable(--lhs_space_dim)) == 0); 01919 01920 // Gather in `new_lines' the collections of all the lines having 01921 // the direction of variables occurring in `lhs'. 01922 // While at it, check whether or not there exists a variable 01923 // occurring in both `lhs' and `rhs'. 01924 Grid_Generator_System new_lines; 01925 bool lhs_vars_intersect_rhs_vars = false; 01926 for (dimension_type i = lhs_space_dim + 1; i-- > 0; ) 01927 if (lhs.coefficient(Variable(i)) != 0) { 01928 new_lines.insert(Grid_Generator::line(Variable(i))); 01929 if (rhs.coefficient(Variable(i)) != 0) 01930 lhs_vars_intersect_rhs_vars = true; 01931 } 01932 01933 if (lhs_vars_intersect_rhs_vars) { 01934 // Some variables in `lhs' also occur in `rhs'. 01935 // To ease the computation, add an additional dimension. 01936 const Variable new_var = Variable(space_dim); 01937 add_space_dimensions_and_embed(1); 01938 01939 // Constrain the new dimension to be equal to `lhs' 01940 // TODO: Use add_congruence_and_minimize() when it has been updated. 01941 Congruence_System new_cgs1(new_var == lhs); 01942 if (add_recycled_congruences_and_minimize(new_cgs1)) { 01943 // The grid still contains points. 01944 01945 // Cylindrificate on all the variables occurring in the left 01946 // hand side 01947 01948 // Ajust `new_lines' to the right dimension. 01949 new_lines.insert(parameter(0*Variable(space_dim-1))); 01950 // Add the lines to `gen_sys'. 01951 gen_sys.recycling_insert(new_lines); 01952 normalize_divisors(gen_sys); 01953 // Update the flags. 01954 clear_congruences_up_to_date(); 01955 clear_generators_minimized(); 01956 01957 // Constrain the new dimension so that it is related to 01958 // the right hand side modulo `mod'. 01959 // TODO: Use add_congruence() when it has been updated. 01960 Congruence_System new_cgs2((rhs %= new_var) / mod); 01961 add_recycled_congruences(new_cgs2); 01962 } 01963 01964 // Remove the temporarily added dimension. 01965 remove_higher_space_dimensions(space_dim-1); 01966 } 01967 else { 01968 // `lhs' and `rhs' variables are disjoint: 01969 // there is no need to add a further dimension. 01970 01971 // Constrain the left hand side expression so that it is congruent to 01972 // the right hand side expression modulo `mod'. 01973 add_congruence((lhs %= rhs) / mod); 01974 01975 // Any image of an empty grid is empty. 01976 if (is_empty()) 01977 return; 01978 01979 // FIXME: Confirm that it is OK for this to follow the 01980 // add_congruence, whereas in the branch above (and in 01981 // affine_image, and in Polyhedron) it comes first. 01982 // Cylindrificate on all the variables occurring in `lhs'. 01983 add_recycled_generators(new_lines); 01984 } 01985 assert(OK()); 01986 }
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 1989 of file Grid_public.cc.
References clear_congruences_up_to_date(), clear_generators_minimized(), Parma_Polyhedra_Library::Grid_Generator::divisor(), 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_generators(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::recycling_insert(), set_empty(), space_dim, TEMP_INTEGER, throw_dimension_incompatible(), and update_generators().
01989 { 01990 Grid& x = *this; 01991 // Check dimension-compatibility. 01992 if (x.space_dim != y.space_dim) 01993 throw_dimension_incompatible("time_elapse_assign(y)", "y", y); 01994 01995 // Deal with the zero-dimensional case. 01996 if (x.space_dim == 0) { 01997 if (y.marked_empty()) 01998 x.set_empty(); 01999 return; 02000 } 02001 02002 // If either one of `x' or `y' is empty, the result is empty too. 02003 if (x.marked_empty()) 02004 return; 02005 if (y.marked_empty() 02006 || (!x.generators_are_up_to_date() && !x.update_generators()) 02007 || (!y.generators_are_up_to_date() && !y.update_generators())) { 02008 x.set_empty(); 02009 return; 02010 } 02011 02012 // At this point both generator systems are up-to-date. 02013 Grid_Generator_System gs = y.gen_sys; 02014 dimension_type gs_num_rows = gs.num_generators(); 02015 02016 normalize_divisors(gs, gen_sys); 02017 02018 for (dimension_type i = gs_num_rows; i-- > 0; ) { 02019 Grid_Generator& g = gs[i]; 02020 if (g.is_point()) { 02021 // Transform the point into a parameter. 02022 TEMP_INTEGER(div); 02023 div = g.divisor(); 02024 g.divisor() = 0; 02025 g.divisor() = div; 02026 } 02027 } 02028 02029 if (gs_num_rows == 0) 02030 // `y' was the grid containing a single point at the origin, so 02031 // the result is `x'. 02032 return; 02033 02034 // Append `gs' to the generators of `x'. 02035 02036 gen_sys.recycling_insert(gs); 02037 02038 x.clear_congruences_up_to_date(); 02039 x.clear_generators_minimized(); 02040 02041 assert(x.OK(true) && y.OK(true)); 02042 }
void Parma_Polyhedra_Library::Grid::topological_closure_assign | ( | ) | [inline] |
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
.
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, throw_dimension_incompatible(), and update_congruences().
Referenced by limited_extrapolation_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 // As noted in definitions.dox, stable behaviour is only garaunteed 00083 // if y is contained in or equal 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::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 159 of file Grid_widenings.cc.
References add_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().
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 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.widening_assign(y, tp); 00219 x.add_congruences(new_cgs); 00220 } 00221 else 00222 // There are tokens, so widening will leave the grid the same. 00223 x.widening_assign(y, tp); 00224 00225 assert(OK()); 00226 }
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 79 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().
00079 { 00080 if (m == 0) 00081 return; 00082 00083 // The space dimension of the resulting grid must be at most the 00084 // maximum allowed space dimension. 00085 if (m > max_space_dimension() - space_dimension()) 00086 throw_space_dimension_overflow("add_space_dimensions_and_embed(m)", 00087 "adding m new space dimensions exceeds " 00088 "the maximum allowed space dimension"); 00089 00090 // Adding dimensions to an empty grid is obtained by adjusting 00091 // `space_dim' and clearing `con_sys' (since it can contain the 00092 // integrality congruence of the current dimension). 00093 if (marked_empty()) { 00094 space_dim += m; 00095 set_empty(); 00096 return; 00097 } 00098 00099 // The case of a zero-dimension space grid. 00100 if (space_dim == 0) { 00101 // Since it is not empty, it has to be the universe grid. 00102 assert(status.test_zero_dim_univ()); 00103 // Swap *this with a newly created `m'-dimensional universe grid. 00104 Grid gr(m, UNIVERSE); 00105 swap(gr); 00106 return; 00107 } 00108 00109 // To embed an n-dimension space grid in a (n+m)-dimension space, we 00110 // add `m' zero-columns to the rows in the system of congruences; in 00111 // contrast, the system of generators needs additional rows, 00112 // corresponding to the vectors of the canonical basis for the added 00113 // dimensions. That is, for each new dimension we add the line 00114 // having that direction. This is done by invoking the function 00115 // add_space_dimensions(). 00116 if (congruences_are_up_to_date()) 00117 if (generators_are_up_to_date()) 00118 // Adds rows and/or columns to both matrices. 00119 add_space_dimensions(con_sys, gen_sys, m); 00120 else { 00121 // Only congruences are up-to-date, so modify only them. 00122 con_sys.add_zero_columns(m); 00123 dimension_type size = con_sys.num_columns() - 1; 00124 // Move the moduli. 00125 con_sys.swap_columns(size - m, size); 00126 if (congruences_are_minimized()) 00127 dim_kinds.resize(size, CON_VIRTUAL); 00128 } 00129 else { 00130 // Only generators are up-to-date, so modify only them. 00131 assert(generators_are_up_to_date()); 00132 gen_sys.add_universe_rows_and_columns(m); 00133 if (generators_are_minimized()) 00134 dim_kinds.resize(gen_sys.space_dimension() + 1, LINE); 00135 } 00136 // Update the space dimension. 00137 space_dim += m; 00138 00139 // Note: we do not check for satisfiability, because the system of 00140 // congruences may be unsatisfiable. 00141 assert(OK()); 00142 }
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 153 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.
00153 { 00154 if (m == 0) 00155 return; 00156 00157 // The space dimension of the resulting grid should be at most the 00158 // maximum allowed space dimension. 00159 if (m > max_space_dimension() - space_dimension()) 00160 throw_space_dimension_overflow("add_space_dimensions_and_project(m)", 00161 "adding m new space dimensions exceeds " 00162 "the maximum allowed space dimension"); 00163 00164 // Adding dimensions to an empty grid is obtained by merely 00165 // adjusting `space_dim'. 00166 if (marked_empty()) { 00167 space_dim += m; 00168 set_empty(); 00169 return; 00170 } 00171 00172 if (space_dim == 0) { 00173 assert(status.test_zero_dim_univ()); 00174 // Swap *this with a newly created `n'-dimensional universe grid. 00175 Grid gr(m, UNIVERSE); 00176 swap(gr); 00177 return; 00178 } 00179 00180 // To project an n-dimension space grid in a (n+m)-dimension space, 00181 // we just add to the system of generators `m' zero-columns; in 00182 // contrast, in the system of congruences, new rows are needed in 00183 // order to avoid embedding the old grid in the new space. Thus, 00184 // for each new dimensions `x[k]', we add the constraint x[k] = 0; 00185 // this is done by invoking the function add_space_dimensions() 00186 // giving the system of constraints as the second argument. 00187 if (congruences_are_up_to_date()) 00188 if (generators_are_up_to_date()) 00189 // Add rows and/or columns to both matrices. 00190 add_space_dimensions(gen_sys, con_sys, m); 00191 else { 00192 // Only congruences are up-to-date so modify only them. 00193 con_sys.add_unit_rows_and_columns(m); 00194 if (congruences_are_minimized()) 00195 dim_kinds.resize(con_sys.num_columns() - 1, EQUALITY); 00196 } 00197 else { 00198 // Only generators are up-to-date so modify only them. 00199 assert(generators_are_up_to_date()); 00200 00201 // Add m zero columns onto gs. 00202 gen_sys.insert(parameter(0*Variable(space_dim + m - 1))); 00203 00204 normalize_divisors(gen_sys); 00205 00206 if (generators_are_minimized()) 00207 dim_kinds.resize(gen_sys.space_dimension() + 1, EQUALITY); 00208 } 00209 // Now update the space dimension. 00210 space_dim += m; 00211 00212 // Note: we do not check for satisfiability, because the system of 00213 // congruences may be unsatisfiable. 00214 assert(OK()); 00215 }
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 218 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().
00218 { 00219 // The space dimension of the resulting grid must be at most the 00220 // maximum allowed space dimension. 00221 if (y.space_dim > max_space_dimension() - space_dimension()) 00222 throw_space_dimension_overflow("concatenate_assign(y)", 00223 "concatenation exceeds the maximum " 00224 "allowed space dimension"); 00225 00226 const dimension_type added_columns = y.space_dim; 00227 00228 // If `*this' or `y' are empty grids just adjust the space 00229 // dimension. 00230 if (marked_empty() || y.marked_empty()) { 00231 space_dim += added_columns; 00232 set_empty(); 00233 return; 00234 } 00235 00236 // If `y' is a universe 0-dim grid, the result is `*this'. 00237 if (added_columns == 0) 00238 return; 00239 00240 // If `*this' is a universe 0-dim space grid, the result is `y'. 00241 if (space_dim == 0) { 00242 *this = y; 00243 return; 00244 } 00245 00246 congruences_are_up_to_date() || 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: the variable having maximum space 00271 // dimension is the one occurring last in the set. 00272 const dimension_type 00273 min_space_dim = to_be_removed.rbegin()->space_dimension(); 00274 if (space_dim < min_space_dim) 00275 throw_dimension_incompatible("remove_space_dimensions(vs)", min_space_dim); 00276 00277 const dimension_type new_space_dim = space_dim - to_be_removed.size(); 00278 00279 if (marked_empty() 00280 || (!generators_are_up_to_date() && !update_generators())) { 00281 // Update the space dimension. 00282 space_dim = new_space_dim; 00283 set_empty(); 00284 assert(OK()); 00285 return; 00286 } 00287 00288 // Removing _all_ dimensions from a non-empty grid obtains the 00289 // zero-dimensional universe grid. 00290 if (new_space_dim == 0) { 00291 set_zero_dim_univ(); 00292 return; 00293 } 00294 00295 // FIXME: Can this operate on the congruence system if only the 00296 // congruence system is up to date? 00297 00298 gen_sys.remove_space_dimensions(to_be_removed); 00299 00300 clear_congruences_up_to_date(); 00301 clear_generators_minimized(); 00302 00303 // Update the space dimension. 00304 space_dim = new_space_dim; 00305 00306 assert(OK(true)); 00307 }
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 310 of file Grid_chdims.cc.
References clear_congruences_up_to_date(), clear_generators_minimized(), dim_kinds, Parma_Polyhedra_Library::Grid_Generator_System::erase_to_end(), gen_sys, generators_are_minimized(), generators_are_up_to_date(), marked_empty(), OK(), Parma_Polyhedra_Library::Grid_Generator_System::remove_higher_space_dimensions(), set_empty(), set_zero_dim_univ(), space_dim, throw_dimension_incompatible(), and update_generators().
Referenced by generalized_affine_image(), and generalized_affine_preimage().
00310 { 00311 // Dimension-compatibility check. 00312 if (new_dimension > space_dim) 00313 throw_dimension_incompatible("remove_higher_space_dimensions(nd)", 00314 new_dimension); 00315 00316 // The removal of no dimensions from any grid is a no-op. 00317 // Note that this case also captures the only legal removal of 00318 // dimensions from a grid in a 0-dim space. 00319 if (new_dimension == space_dim) { 00320 assert(OK()); 00321 return; 00322 } 00323 00324 if (marked_empty() 00325 || (!generators_are_up_to_date() && !update_generators())) { 00326 // Removing dimensions from the empty grid just updates the space 00327 // dimension. 00328 space_dim = new_dimension; 00329 set_empty(); 00330 assert(OK()); 00331 return; 00332 } 00333 00334 if (new_dimension == 0) { 00335 // Removing all dimensions from a non-empty grid just returns the 00336 // zero-dimensional universe grid. 00337 set_zero_dim_univ(); 00338 return; 00339 } 00340 00341 gen_sys.remove_higher_space_dimensions(new_dimension); 00342 00343 #if 0 00344 // FIXME: Perhaps add something like remove_rows_and_columns(dims) 00345 // to Grid_Generator_System for this. 00346 if (generators_are_minimized()) { 00347 gen_sys.erase_to_end(new_dimension + 1); 00348 dim_kinds.erase(dim_kinds.begin() + new_dimension + 1, dim_kinds.end()); 00349 } 00350 #else 00351 clear_generators_minimized(); 00352 #endif 00353 00354 clear_congruences_up_to_date(); 00355 00356 // Update the space dimension. 00357 space_dim = new_dimension; 00358 00359 assert(OK(true)); 00360 }
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 413 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::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(), generators_are_up_to_date(), Parma_Polyhedra_Library::Grid_Generator_System::insert(), Parma_Polyhedra_Library::Grid_Generator::LINE, marked_empty(), Parma_Polyhedra_Library::not_a_dimension(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), 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::Grid_Generator::type(), and update_generators().
00413 { 00414 if (space_dim == 0) 00415 return; 00416 00417 if (pfunc.has_empty_codomain()) { 00418 // All dimensions vanish: the grid becomes zero_dimensional. 00419 if (marked_empty() 00420 || (!generators_are_up_to_date() && !update_generators())) { 00421 // Removing all dimensions from the empty grid. 00422 space_dim = 0; 00423 set_empty(); 00424 } 00425 else 00426 // Removing all dimensions from a non-empty grid. 00427 set_zero_dim_univ(); 00428 00429 assert(OK()); 00430 return; 00431 } 00432 00433 dimension_type new_space_dimension = pfunc.max_in_codomain() + 1; 00434 00435 if (new_space_dimension == space_dim) { 00436 // The partial function `pfunc' is indeed total and thus specifies 00437 // a permutation, that is, a renaming of the dimensions. For 00438 // maximum efficiency, we will simply permute the columns of the 00439 // constraint system and/or the generator system. 00440 00441 // We first compute suitable permutation cycles for the columns of 00442 // the `con_sys' and `gen_sys' matrices. We will represent them 00443 // with a linear array, using 0 as a terminator for each cycle 00444 // (notice that the columns with index 0 of `con_sys' and 00445 // `gen_sys' represent the inhomogeneous terms, and thus are 00446 // unaffected by the permutation of dimensions). 00447 // Cycles of length 1 will be omitted so that, in the worst case, 00448 // we will have `space_dim' elements organized in `space_dim/2' 00449 // cycles, which means we will have at most `space_dim/2' 00450 // terminators. 00451 std::vector<dimension_type> cycles; 00452 cycles.reserve(space_dim + space_dim/2); 00453 00454 // Used to mark elements as soon as they are inserted in a cycle. 00455 std::deque<bool> visited(space_dim); 00456 00457 for (dimension_type i = space_dim; i-- > 0; ) { 00458 if (!visited[i]) { 00459 dimension_type j = i; 00460 do { 00461 visited[j] = true; 00462 dimension_type k; 00463 (void) pfunc.maps(j, k); 00464 if (k == j) 00465 // Cycle of length 1: skip it. 00466 goto skip; 00467 00468 cycles.push_back(j+1); 00469 // Go along the cycle. 00470 j = k; 00471 } while (!visited[j]); 00472 // End of cycle: mark it. 00473 cycles.push_back(0); 00474 skip: 00475 ; 00476 } 00477 } 00478 00479 // If `cycles' is empty then `pfunc' is the identity. 00480 if (cycles.empty()) 00481 return; 00482 00483 // Permute all that is up-to-date. 00484 if (congruences_are_up_to_date()) { 00485 con_sys.permute_columns(cycles); 00486 clear_congruences_minimized(); 00487 } 00488 00489 if (generators_are_up_to_date()) { 00490 gen_sys.permute_columns(cycles); 00491 clear_generators_minimized(); 00492 } 00493 00494 assert(OK()); 00495 return; 00496 } 00497 00498 // If control gets here, then `pfunc' is not a permutation and some 00499 // dimensions must be projected away. 00500 00501 const Grid_Generator_System& old_gensys = generators(); 00502 00503 if (old_gensys.num_generators() == 0) { 00504 // The grid is empty. 00505 Grid new_grid(new_space_dimension, EMPTY); 00506 std::swap(*this, new_grid); 00507 assert(OK()); 00508 return; 00509 } 00510 00511 // Make a local copy of the partial function. 00512 std::vector<dimension_type> pfunc_maps(space_dim, not_a_dimension()); 00513 for (dimension_type j = space_dim; j-- > 0; ) { 00514 dimension_type pfunc_j; 00515 if (pfunc.maps(j, pfunc_j)) 00516 pfunc_maps[j] = pfunc_j; 00517 } 00518 00519 Grid_Generator_System new_gensys; 00520 // Set sortedness, for the assertion met via gs::insert. 00521 new_gensys.set_sorted(false); 00522 // Get the divisor of the first point. 00523 Grid_Generator_System::const_iterator i; 00524 Grid_Generator_System::const_iterator old_gensys_end = old_gensys.end(); 00525 for (i = old_gensys.begin(); i != old_gensys_end; ++i) 00526 if (i->is_point()) 00527 break; 00528 assert(i != old_gensys_end); 00529 Coefficient_traits::const_reference system_divisor = i->divisor(); 00530 for (Grid_Generator_System::const_iterator i = old_gensys.begin(); 00531 i != old_gensys_end; 00532 ++i) { 00533 const Grid_Generator& old_g = *i; 00534 Linear_Expression e(0 * Variable(new_space_dimension-1)); 00535 bool all_zeroes = true; 00536 for (dimension_type j = space_dim; j-- > 0; ) { 00537 if (old_g.coefficient(Variable(j)) != 0 00538 && pfunc_maps[j] != not_a_dimension()) { 00539 e += Variable(pfunc_maps[j]) * old_g.coefficient(Variable(j)); 00540 all_zeroes = false; 00541 } 00542 } 00543 switch (old_g.type()) { 00544 case Grid_Generator::LINE: 00545 if (!all_zeroes) 00546 new_gensys.insert(grid_line(e)); 00547 break; 00548 case Grid_Generator::PARAMETER: 00549 if (!all_zeroes) 00550 new_gensys.insert(parameter(e, system_divisor)); 00551 break; 00552 case Grid_Generator::POINT: 00553 new_gensys.insert(grid_point(e, old_g.divisor())); 00554 break; 00555 case Grid_Generator::CLOSURE_POINT: 00556 default: 00557 assert(0); 00558 } 00559 } 00560 00561 Grid new_grid(new_gensys); 00562 std::swap(*this, new_grid); 00563 00564 assert(OK(true)); 00565 }
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 363 of file Grid_chdims.cc.
References add_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().
00363 { 00364 // FIXME: this implementation is _really_ an executable specification. 00365 00366 // `var' must be one of the dimensions of the vector space. 00367 if (var.space_dimension() > space_dim) 00368 throw_dimension_incompatible("expand_space_dimension(v, m)", "v", var); 00369 00370 // Adding 0 dimensions leaves the same grid. 00371 if (m == 0) 00372 return; 00373 00374 // The resulting space dimension must be at most the maximum. 00375 if (m > max_space_dimension() - space_dimension()) 00376 throw_space_dimension_overflow("expand_space_dimension(v, m)", 00377 "adding m new space dimensions exceeds " 00378 "the maximum allowed space dimension"); 00379 00380 // Save the number of dimensions before adding new ones. 00381 dimension_type old_dim = space_dim; 00382 00383 // Add the required new dimensions. 00384 add_space_dimensions_and_embed(m); 00385 00386 const dimension_type src_d = var.id(); 00387 const Congruence_System& cgs = congruences(); 00388 Congruence_System new_congruences; 00389 for (Congruence_System::const_iterator i = cgs.begin(), 00390 cgs_end = cgs.end(); i != cgs_end; ++i) { 00391 const Congruence& cg = *i; 00392 00393 // Only consider congruences that constrain `var'. 00394 if (cg.coefficient(var) == 0) 00395 continue; 00396 00397 // Each relevant congruence results in `m' new congruences. 00398 for (dimension_type dst_d = old_dim; dst_d < old_dim+m; ++dst_d) { 00399 Linear_Expression e; 00400 for (dimension_type j = old_dim; j-- > 0; ) 00401 e += 00402 cg.coefficient(Variable(j)) 00403 * (j == src_d ? Variable(dst_d) : Variable(j)); 00404 new_congruences.insert_verbatim((e + cg.inhomogeneous_term() %= 0) 00405 / cg.modulus()); 00406 } 00407 } 00408 add_congruences(new_congruences); 00409 assert(OK()); 00410 }
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 413 of file Grid_chdims.cc.
References affine_image(), join_assign(), OK(), remove_space_dimensions(), space_dim, Parma_Polyhedra_Library::Variable::space_dimension(), throw_dimension_incompatible(), and throw_invalid_argument().
00414 { 00415 // FIXME: this implementation is _really_ an executable specification. 00416 00417 // `var' should be one of the dimensions of the grid. 00418 if (var.space_dimension() > space_dim) 00419 throw_dimension_incompatible("fold_space_dimensions(tbf, v)", "v", var); 00420 00421 // Folding only has effect if dimensions are given. 00422 if (to_be_folded.empty()) 00423 return; 00424 00425 // All variables in `to_be_folded' must be dimensions of the grid. 00426 if (to_be_folded.rbegin()->space_dimension() > space_dim) 00427 throw_dimension_incompatible("fold_space_dimensions(tbf, v)", 00428 "*tbf.rbegin()", 00429 *to_be_folded.rbegin()); 00430 00431 // Moreover, `var' must not occur in `to_be_folded'. 00432 if (to_be_folded.find(var) != to_be_folded.end()) 00433 throw_invalid_argument("fold_space_dimensions(tbf, v)", 00434 "v should not occur in tbf"); 00435 00436 for (Variables_Set::const_iterator i = to_be_folded.begin(), 00437 tbf_end = to_be_folded.end(); i != tbf_end; ++i) { 00438 Grid copy = *this; 00439 copy.affine_image(var, Linear_Expression(*i)); 00440 join_assign(copy); 00441 } 00442 remove_space_dimensions(to_be_folded); 00443 assert(OK()); 00444 }
void Parma_Polyhedra_Library::Grid::swap | ( | Grid & | y | ) | [inline] |
Swaps *this
with grid y
. (*this
and y
can be dimension-incompatible.).
Definition at line 119 of file Grid.inlines.hh.
References con_sys, dim_kinds, gen_sys, space_dim, and status.
Referenced by add_space_dimensions_and_embed(), add_space_dimensions_and_project(), Grid(), minimized_congruences(), set_empty(), and swap().
00119 { 00120 std::swap(con_sys, y.con_sys); 00121 std::swap(gen_sys, y.gen_sys); 00122 std::swap(status, y.status); 00123 std::swap(space_dim, y.space_dim); 00124 std::swap(dim_kinds, y.dim_kinds); 00125 }
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 2103 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.
02103 { 02104 using std::endl; 02105 02106 s << "space_dim " 02107 << space_dim 02108 << endl; 02109 status.ascii_dump(s); 02110 s << "con_sys (" 02111 << (congruences_are_up_to_date() ? "" : "not_") 02112 << "up-to-date)" 02113 << endl; 02114 con_sys.ascii_dump(s); 02115 s << "gen_sys (" 02116 << (generators_are_up_to_date() ? "" : "not_") 02117 << "up-to-date)" 02118 << endl; 02119 gen_sys.ascii_dump(s); 02120 s << "dimension_kinds"; 02121 if ((generators_are_up_to_date() && generators_are_minimized()) 02122 || (congruences_are_up_to_date() && congruences_are_minimized())) 02123 for (Dimension_Kinds::const_iterator i = dim_kinds.begin(); 02124 i != dim_kinds.end(); 02125 ++i) 02126 s << " " << *i; 02127 s << endl; 02128 }
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) and sets *this
accordingly.
true
if successful, else false
. Definition at line 2133 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.
02133 { 02134 std::string str; 02135 02136 if (!(s >> str) || str != "space_dim") 02137 return false; 02138 02139 if (!(s >> space_dim)) 02140 return false; 02141 02142 if (!status.ascii_load(s)) 02143 return false; 02144 02145 if (!(s >> str) || str != "con_sys") 02146 return false; 02147 02148 if (s >> str) { 02149 if (str == "(up-to-date)") 02150 set_congruences_up_to_date(); 02151 else if (str != "(not_up-to-date)") 02152 return false; 02153 } 02154 else 02155 return false; 02156 02157 if (!con_sys.ascii_load(s)) 02158 return false; 02159 02160 if (!(s >> str) || str != "gen_sys") 02161 return false; 02162 02163 if (s >> str) { 02164 if (str == "(up-to-date)") 02165 set_generators_up_to_date(); 02166 else if (str != "(not_up-to-date)") 02167 return false; 02168 } 02169 else 02170 return false; 02171 02172 if (!gen_sys.ascii_load(s)) 02173 return false; 02174 02175 if (!(s >> str) || str != "dimension_kinds") 02176 return false; 02177 02178 if (!marked_empty() 02179 && ((generators_are_up_to_date() && generators_are_minimized()) 02180 || (congruences_are_up_to_date() && congruences_are_minimized()))) { 02181 dim_kinds.resize(space_dim + 1); 02182 for (Dimension_Kinds::size_type dim = 0; dim <= space_dim; ++dim) { 02183 short unsigned int dim_kind; 02184 if (!(s >> dim_kind)) 02185 return false; 02186 switch(dim_kind) { 02187 case 0: dim_kinds[dim] = PARAMETER; break; 02188 case 1: dim_kinds[dim] = LINE; break; 02189 case 2: dim_kinds[dim] = GEN_VIRTUAL; break; 02190 default: return false; 02191 } 02192 } 02193 } 02194 02195 02196 // Check for well-formedness. 02197 assert(OK()); 02198 return true; 02199 }
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 94 of file Grid.inlines.hh.
References external_memory_in_bytes().
00094 { 00095 return sizeof(*this) + external_memory_in_bytes(); 00096 }
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 2202 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().
02202 { 02203 return 02204 con_sys.external_memory_in_bytes() 02205 + gen_sys.external_memory_in_bytes(); 02206 }
void Parma_Polyhedra_Library::Grid::construct | ( | const 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. |
Definition at line 51 of file Grid_nonpublic.cc.
References con_sys, max_space_dimension(), Parma_Polyhedra_Library::Congruence_System::normalize_moduli(), OK(), set_congruences_up_to_date(), set_empty(), set_zero_dim_univ(), space_dim, and Parma_Polyhedra_Library::Congruence_System::space_dimension().
Referenced by Grid().
00051 { 00052 // Protecting against space dimension overflow is up to the caller. 00053 assert(ccgs.space_dimension() <= max_space_dimension()); 00054 00055 // TODO: this implementation is just an executable specification. 00056 Congruence_System cgs = ccgs; 00057 00058 // Set the space dimension. 00059 space_dim = cgs.space_dimension(); 00060 00061 if (space_dim > 0) { 00062 // Stealing the rows from `cgs'. 00063 std::swap(con_sys, cgs); 00064 con_sys.normalize_moduli(); 00065 set_congruences_up_to_date(); 00066 } 00067 else { 00068 // Here `space_dim == 0'. 00069 if (cgs.num_columns() > 1) 00070 // See if an inconsistent congruence has been passed. 00071 for (dimension_type i = cgs.num_rows(); i-- > 0; ) 00072 if (cgs[i].is_trivial_false()) { 00073 // Inconsistent congruence found: the grid is empty. 00074 // FIXME: Initialize con_sys to the correct dimension in the 00075 // caller constructors, and copy the necessary parts 00076 // of set_empty into here. 00077 set_empty(); 00078 assert(OK()); 00079 return; 00080 } 00081 set_zero_dim_univ(); 00082 } 00083 00084 assert(OK()); 00085 }
void Parma_Polyhedra_Library::Grid::construct | ( | const Grid_Generator_System & | gs | ) | [private] |
Builds a grid from a system of generators.
The grid inherits the space dimension of the generator system.
gs | The system of generators defining the grid; |
Definition at line 88 of file Grid_nonpublic.cc.
References gen_sys, max_space_dimension(), normalize_divisors(), OK(), set_empty(), set_generators_up_to_date(), set_zero_dim_univ(), space_dim, Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and throw_invalid_generators().
00088 { 00089 // Protecting against space dimension overflow is up to the caller. 00090 assert(const_gs.space_dimension() <= max_space_dimension()); 00091 00092 // TODO: this implementation is just an executable specification. 00093 Grid_Generator_System gs = const_gs; 00094 00095 // Set the space dimension. 00096 space_dim = gs.space_dimension(); 00097 00098 // An empty set of generators defines the empty grid. 00099 if (gs.num_generators() == 0) { 00100 // FIXME: Initialize gen_sys to the correct dimension in the 00101 // caller constructors, and copy the necessary parts of 00102 // set_empty into here. 00103 set_empty(); 00104 return; 00105 } 00106 00107 // Non-empty valid generator systems have a supporting point, at least. 00108 if (!gs.has_points()) 00109 throw_invalid_generators("Grid(const_gs)", "gs"); 00110 00111 if (space_dim > 0) { 00112 // Steal the rows from `gs'. 00113 std::swap(gen_sys, gs); 00114 normalize_divisors(gen_sys); 00115 00116 // Generators are now up-to-date. 00117 set_generators_up_to_date(); 00118 } 00119 else 00120 set_zero_dim_univ(); 00121 00122 assert(OK()); 00123 }
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 139 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_empty().
Referenced by add_congruence(), add_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_generators(), add_recycled_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_load(), bounds(), concatenate_assign(), congruences(), contains(), generalized_affine_image(), generalized_affine_preimage(), generators(), get_covering_box(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), grid_difference_assign(), intersection_assign(), is_bounded(), is_discrete(), is_empty(), is_included_in(), is_topologically_closed(), is_universe(), join_assign(), join_assign_if_exact(), limited_extrapolation_assign(), map_space_dimensions(), max_min(), minimize(), minimized_congruences(), minimized_generators(), OK(), operator=(), quick_equivalence_test(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), select_wider_congruences(), shrink_bounding_box(), time_elapse_assign(), update_congruences(), update_generators(), and widening_assign().
00139 { 00140 return status.test_empty(); 00141 }
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 144 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_c_up_to_date().
Referenced by add_congruence(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), concatenate_assign(), congruences(), 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().
00144 { 00145 return status.test_c_up_to_date(); 00146 }
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 149 of file Grid.inlines.hh.
References status, and Parma_Polyhedra_Library::Grid::Status::test_g_up_to_date().
Referenced by add_generator(), add_recycled_generators(), add_recycled_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), bounds(), generalized_affine_image(), generators(), get_covering_box(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_bounded(), is_discrete(), is_empty(), is_topologically_closed(), join_assign(), limited_extrapolation_assign(), map_space_dimensions(), minimize(), minimized_generators(), OK(), operator=(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), shrink_bounding_box(), and time_elapse_assign().
00149 { 00150 return status.test_g_up_to_date(); 00151 }
bool Parma_Polyhedra_Library::Grid::congruences_are_minimized | ( | ) | const [inline, private] |
Returns true
if the system of congruences is minimized.
Definition at line 154 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(), ascii_dump(), ascii_load(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_discrete(), is_empty(), is_included_in(), is_topologically_closed(), is_universe(), minimize(), minimized_congruences(), OK(), quick_equivalence_test(), select_wider_congruences(), update_generators(), and widening_assign().
00154 { 00155 return status.test_c_minimized(); 00156 }
bool Parma_Polyhedra_Library::Grid::generators_are_minimized | ( | ) | const [inline, private] |
Returns true
if the system of generators is minimized.
Definition at line 159 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(), ascii_dump(), ascii_load(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_discrete(), is_topologically_closed(), max_min(), minimize(), minimized_generators(), OK(), quick_equivalence_test(), remove_higher_space_dimensions(), and update_congruences().
00159 { 00160 return status.test_g_minimized(); 00161 }
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 287 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_Generator::point(), Parma_Polyhedra_Library::Grid::Status::set_zero_dim_univ(), space_dim, and status.
Referenced by add_generator(), add_recycled_generators(), add_recycled_generators_and_minimize(), construct(), Grid(), map_space_dimensions(), operator=(), remove_higher_space_dimensions(), and remove_space_dimensions().
00287 { 00288 status.set_zero_dim_univ(); 00289 space_dim = 0; 00290 con_sys.clear(); 00291 gen_sys.clear(); 00292 gen_sys.insert(Grid_Generator::point()); 00293 }
void Parma_Polyhedra_Library::Grid::set_empty | ( | ) | [private] |
Sets status
to express that the grid is empty, clearing all corresponding matrices.
Definition at line 296 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(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), concatenate_assign(), construct(), Grid(), grid_difference_assign(), intersection_assign(), is_discrete(), is_empty(), is_topologically_closed(), map_space_dimensions(), minimized_congruences(), operator=(), remove_higher_space_dimensions(), remove_space_dimensions(), time_elapse_assign(), update_generators(), and widening_assign().
00296 { 00297 status.set_empty(); 00298 00299 // Replace gen_sys with an empty system of the right dimension. 00300 Grid_Generator_System gs(space_dim); 00301 gen_sys.swap(gs); 00302 00303 // Extend the zero dim false congruence system to the appropriate 00304 // dimension and then swap it with `con_sys'. 00305 Congruence_System cgs(Congruence::zero_dim_false()); 00306 cgs.increase_space_dimension(space_dim); 00307 const_cast<Congruence_System&>(con_sys).swap(cgs); 00308 }
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 45 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::set_c_up_to_date(), and status.
Referenced by add_congruence(), ascii_load(), construct(), Grid(), and set_congruences_minimized().
00045 { 00046 status.set_c_up_to_date(); 00047 }
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 164 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::set_g_up_to_date(), and status.
Referenced by add_generator(), add_recycled_generators(), ascii_load(), construct(), and set_generators_minimized().
00164 { 00165 status.set_g_up_to_date(); 00166 }
void Parma_Polyhedra_Library::Grid::set_congruences_minimized | ( | ) | [inline, private] |
Sets status
to express that congruences are minimized.
Definition at line 169 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::set_c_minimized(), set_congruences_up_to_date(), and status.
Referenced by Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_discrete(), is_empty(), is_topologically_closed(), minimize(), minimized_congruences(), update_generators(), and widening_assign().
00169 { 00170 set_congruences_up_to_date(); 00171 status.set_c_minimized(); 00172 }
void Parma_Polyhedra_Library::Grid::set_generators_minimized | ( | ) | [inline, private] |
Sets status
to express that generators are minimized.
Definition at line 175 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::set_g_minimized(), set_generators_up_to_date(), and status.
Referenced by Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_discrete(), is_topologically_closed(), max_min(), minimize(), minimized_generators(), and update_generators().
00175 { 00176 set_generators_up_to_date(); 00177 status.set_g_minimized(); 00178 }
void Parma_Polyhedra_Library::Grid::clear_empty | ( | ) | [inline, private] |
Clears the status
flag indicating that the grid is empty.
Definition at line 181 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::reset_empty(), and status.
Referenced by add_generator(), add_recycled_generators(), and add_recycled_generators_and_minimize().
00181 { 00182 status.reset_empty(); 00183 }
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 196 of file Grid.inlines.hh.
References clear_congruences_minimized(), Parma_Polyhedra_Library::Grid::Status::reset_c_up_to_date(), and status.
Referenced by add_generator(), add_recycled_generators(), affine_image(), generalized_affine_image(), generalized_affine_preimage(), join_assign(), remove_higher_space_dimensions(), remove_space_dimensions(), and time_elapse_assign().
00196 { 00197 clear_congruences_minimized(); 00198 status.reset_c_up_to_date(); 00199 // Can get rid of con_sys here. 00200 }
void Parma_Polyhedra_Library::Grid::clear_generators_up_to_date | ( | ) | [inline, private] |
Sets status
to express that parameters are out of date.
Definition at line 203 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(), add_recycled_congruences(), affine_preimage(), concatenate_assign(), intersection_assign(), and OK().
00203 { 00204 clear_generators_minimized(); 00205 status.reset_g_up_to_date(); 00206 // Can get rid of gen_sys here. 00207 }
void Parma_Polyhedra_Library::Grid::clear_congruences_minimized | ( | ) | [inline, private] |
Sets status
to express that congruences are no longer minimized.
Definition at line 186 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::reset_c_minimized(), and status.
Referenced by add_congruence(), 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().
00186 { 00187 status.reset_c_minimized(); 00188 }
void Parma_Polyhedra_Library::Grid::clear_generators_minimized | ( | ) | [inline, private] |
Sets status
to express that generators are no longer minimized.
Definition at line 191 of file Grid.inlines.hh.
References Parma_Polyhedra_Library::Grid::Status::reset_g_minimized(), and status.
Referenced by add_generator(), add_recycled_generators(), add_recycled_generators_and_minimize(), affine_image(), affine_preimage(), clear_generators_up_to_date(), generalized_affine_image(), generalized_affine_preimage(), join_assign(), map_space_dimensions(), remove_higher_space_dimensions(), remove_space_dimensions(), and time_elapse_assign().
00191 { 00192 status.reset_g_minimized(); 00193 }
bool Parma_Polyhedra_Library::Grid::update_congruences | ( | ) | const [private] |
Updates and minimizes the congruences from the generators.
true
. Definition at line 311 of file Grid_nonpublic.cc.
References gen_sys, generators_are_minimized(), marked_empty(), Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), space_dim, and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().
Referenced by add_congruence(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_generators_and_minimize(), concatenate_assign(), congruences(), intersection_assign(), is_included_in(), is_universe(), minimize(), relation_with(), and widening_assign().
00311 { 00312 // The caller must ensure that the generators are up to date. 00313 assert(space_dim > 0); 00314 assert(!marked_empty()); 00315 assert(gen_sys.num_generators() > 0); 00316 assert(gen_sys.space_dimension() > 0); 00317 00318 Grid& gr = const_cast<Grid&>(*this); 00319 00320 if (!generators_are_minimized()) 00321 gr.simplify(gr.gen_sys, gr.dim_kinds); 00322 00323 // `gen_sys' contained rows before being reduced, so it should 00324 // contain at least a single point afterwards. 00325 assert(gen_sys.num_generators() > 0); 00326 00327 // Populate `con_sys' with congruences characterizing the grid 00328 // described by `gen_sys'. 00329 gr.conversion(gr.gen_sys, gr.con_sys, gr.dim_kinds); 00330 00331 // Both systems are minimized. 00332 gr.set_congruences_minimized(); 00333 gr.set_generators_minimized(); 00334 return true; 00335 }
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 338 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_generator(), add_recycled_congruences_and_minimize(), add_recycled_generators(), add_recycled_generators_and_minimize(), bounds(), generators(), get_covering_box(), is_bounded(), join_assign(), limited_extrapolation_assign(), map_space_dimensions(), minimize(), minimized_generators(), OK(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), shrink_bounding_box(), and time_elapse_assign().
00338 { 00339 assert(space_dim > 0); 00340 assert(!marked_empty()); 00341 assert(congruences_are_up_to_date()); 00342 00343 Grid& x = const_cast<Grid&>(*this); 00344 00345 if (!congruences_are_minimized()) 00346 // Either the system of congruences is consistent, or the grid is 00347 // empty. 00348 if (simplify(x.con_sys, x.dim_kinds)) { 00349 x.set_empty(); 00350 return false; 00351 } 00352 00353 // Populate gen_sys with generators characterizing the grid 00354 // described by con_sys. 00355 conversion(x.con_sys, x.gen_sys, x.dim_kinds); 00356 00357 // Both systems are minimized. 00358 x.set_congruences_minimized(); 00359 x.set_generators_minimized(); 00360 return true; 00361 }
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 364 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_congruence_and_minimize(), add_constraint_and_minimize(), add_recycled_congruences_and_minimize(), add_recycled_generators_and_minimize(), affine_image(), affine_preimage(), generalized_affine_image(), intersection_assign_and_minimize(), and join_assign_and_minimize().
00364 { 00365 // 0-dimension and empty grids are already minimized. 00366 if (marked_empty()) 00367 return false; 00368 if (space_dim == 0) 00369 return true; 00370 00371 // Are both systems already minimized? 00372 if (congruences_are_minimized() && generators_are_minimized()) 00373 return true; 00374 00375 // Invoke update_generators, update_congruences or simplify, 00376 // depending on the state of the systems. 00377 if (congruences_are_up_to_date()) { 00378 if (generators_are_up_to_date()) { 00379 Grid& gr = const_cast<Grid&>(*this); 00380 // Only one of the systems can be minimized here. 00381 if (congruences_are_minimized()) { 00382 // Minimize the generator system. 00383 gr.simplify(gr.gen_sys, gr.dim_kinds); 00384 gr.set_generators_minimized(); 00385 } 00386 else { 00387 #ifndef NDEBUG 00388 // Both systems are up to date, and the empty case is handled 00389 // above, so the grid should contain points. 00390 bool empty = simplify(gr.con_sys, gr.dim_kinds); 00391 assert(!empty); 00392 #else 00393 simplify(gr.con_sys, gr.dim_kinds); 00394 #endif 00395 gr.set_congruences_minimized(); 00396 if (!generators_are_minimized()) { 00397 // Minimize the generator system. 00398 gr.simplify(gr.gen_sys, gr.dim_kinds); 00399 gr.set_generators_minimized(); 00400 } 00401 } 00402 } 00403 else { 00404 // Updating the generators may reveal that `*this' is empty. 00405 const bool ret = update_generators(); 00406 assert(OK()); 00407 return ret; 00408 } 00409 } 00410 else { 00411 assert(generators_are_up_to_date()); 00412 update_congruences(); 00413 } 00414 assert(OK()); 00415 return true; 00416 }
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 126 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_generators(), Parma_Polyhedra_Library::Grid_Generator_System::num_lines(), Parma_Polyhedra_Library::Matrix::num_rows(), space_dim, TVB_DONT_KNOW, TVB_FALSE, and TVB_TRUE.
Referenced by contains().
00126 { 00127 // Private method: the caller must ensure the following. 00128 assert(space_dim == y.space_dim); 00129 assert(!marked_empty() && !y.marked_empty() && space_dim > 0); 00130 00131 const Grid& x = *this; 00132 00133 bool css_normalized = false; 00134 00135 if (x.congruences_are_minimized() && y.congruences_are_minimized()) { 00136 // Equivalent minimized congruence systems have: 00137 // - the same number of congruences; ... 00138 if (x.con_sys.num_rows() != y.con_sys.num_rows()) 00139 return Grid::TVB_FALSE; 00140 // - the same number of equalities; ... 00141 dimension_type x_num_equalities = x.con_sys.num_equalities(); 00142 if (x_num_equalities != y.con_sys.num_equalities()) 00143 return Grid::TVB_FALSE; 00144 // - and if there are no equalities, the same congruences. 00145 // Delay this test: try cheaper tests on generators first. 00146 css_normalized = (x_num_equalities == 0); 00147 } 00148 00149 if (x.generators_are_minimized() && y.generators_are_minimized()) { 00150 // Equivalent minimized generator systems have: 00151 // - the same number of generators; ... 00152 if (x.gen_sys.num_generators() != y.gen_sys.num_generators()) 00153 return Grid::TVB_FALSE; 00154 // - the same number of lines; ... 00155 const dimension_type x_num_lines = x.gen_sys.num_lines(); 00156 if (x_num_lines != y.gen_sys.num_lines()) 00157 return Grid::TVB_FALSE; 00158 // - and if there are no lines, the same generators. 00159 if (x_num_lines == 0) { 00160 // Check for syntactic identity. 00161 if (x.gen_sys == y.gen_sys) 00162 return Grid::TVB_TRUE; 00163 else 00164 return Grid::TVB_FALSE; 00165 } 00166 } 00167 00168 // TODO: Consider minimizing the systems and re-performing these 00169 // checks. 00170 00171 if (css_normalized) 00172 if (x.con_sys == y.con_sys) 00173 return Grid::TVB_TRUE; 00174 else 00175 return Grid::TVB_FALSE; 00176 00177 return Grid::TVB_DONT_KNOW; 00178 }
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 181 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 join_assign_if_exact().
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 #if BE_LAZY 00189 if (!x.generators_are_up_to_date() && !x.update_generators()) 00190 // Updating found `x' empty. 00191 return true; 00192 y.congruences_are_up_to_date() || y.update_congruences(); 00193 #else 00194 if (!x.generators_are_minimized() && !x.minimize()) 00195 // Minimizing found `x' empty. 00196 return true; 00197 y.congruences_are_minimized() || y.minimize(); 00198 #endif 00199 00200 assert(x.OK()); 00201 assert(y.OK()); 00202 00203 const Grid_Generator_System& gs = x.gen_sys; 00204 const Congruence_System& cgs = y.con_sys; 00205 00206 dimension_type num_rows = gs.num_generators(); 00207 for (dimension_type i = num_rows; i-- > 0; ) 00208 if (!cgs.satisfies_all_congruences(gs[i])) 00209 return false; 00210 00211 // Inclusion holds. 00212 return true; 00213 }
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 216 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_generators(), 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().
00217 { 00218 // The dimension of `expr' must be at most the dimension of *this. 00219 if (space_dim < expr.space_dimension()) 00220 throw_dimension_incompatible(method_call, "e", expr); 00221 00222 // A zero-dimensional or empty grid bounds everything. 00223 if (space_dim == 0 00224 || marked_empty() 00225 || (!generators_are_up_to_date() && !update_generators())) 00226 return true; 00227 00228 // The generators are up to date. 00229 for (dimension_type i = gen_sys.num_generators(); i-- > 0; ) { 00230 const Grid_Generator& g = gen_sys[i]; 00231 // Only lines and parameters in `*this' can cause `expr' to be 00232 // unbounded. 00233 if (g.is_line_or_parameter()) { 00234 const int sp_sign = Scalar_Products::homogeneous_sign(expr, g); 00235 if (sp_sign != 0) 00236 // `*this' does not bound `expr'. 00237 return false; 00238 } 00239 } 00240 return true; 00241 }
bool Parma_Polyhedra_Library::Grid::max_min | ( | const Linear_Expression & | expr, | |
char * | method_call, | |||
Coefficient & | ext_n, | |||
Coefficient & | ext_d, | |||
bool & | included, | |||
Grid_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 244 of file Grid_nonpublic.cc.
References bounds(), 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::Grid_Generator::point(), set_generators_minimized(), simplify(), space_dim, Parma_Polyhedra_Library::Grid_Generator::strong_normalize(), and TEMP_INTEGER.
Referenced by maximize(), and minimize().
00247 { 00248 if (bounds(expr, method_call)) { 00249 if (marked_empty()) 00250 return false; 00251 if (space_dim == 0) { 00252 ext_n = 0; 00253 ext_d = 1; 00254 included = true; 00255 if (point) 00256 *point = Grid_Generator::point(); 00257 return true; 00258 } 00259 if (!generators_are_minimized()) { 00260 // Minimize the generator system. 00261 Grid& gr = const_cast<Grid&>(*this); 00262 gr.simplify(gr.gen_sys, gr.dim_kinds); 00263 gr.set_generators_minimized(); 00264 } 00265 00266 const Grid_Generator& gen = gen_sys[0]; 00267 Scalar_Products::homogeneous_assign(ext_n, expr, gen); 00268 ext_n += expr.inhomogeneous_term(); 00269 ext_d = gen.divisor(); 00270 // Reduce ext_n and ext_d. 00271 TEMP_INTEGER(gcd); 00272 gcd_assign(gcd, ext_n, ext_d); 00273 exact_div_assign(ext_n, ext_n, gcd); 00274 exact_div_assign(ext_d, ext_d, gcd); 00275 00276 included = true; 00277 if (point) { 00278 *point = gen; 00279 point->strong_normalize(); 00280 } 00281 return true; 00282 } 00283 return false; 00284 }
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 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::add_space_dimensions | ( | Congruence_System & | cgs, | |
Grid_Generator_System & | gs, | |||
const dimension_type | dims | |||
) | [inline, 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 35 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().
00037 { 00038 assert(cgs.num_columns() - 1 == gs.space_dimension() + 1); 00039 assert(dims > 0); 00040 00041 dimension_type tem = cgs.num_columns() - 1; 00042 cgs.add_zero_columns(dims); 00043 // Move the moduli. 00044 cgs.swap_columns(tem, tem + dims); 00045 00046 if (congruences_are_minimized() || generators_are_minimized()) 00047 dim_kinds.resize(tem + dims, CON_VIRTUAL /* a.k.a. LINE */); 00048 00049 gs.add_universe_rows_and_columns(dims); 00050 }
void Parma_Polyhedra_Library::Grid::add_space_dimensions | ( | Grid_Generator_System & | gs, | |
Congruence_System & | cgs, | |||
const dimension_type | dims | |||
) | [inline, 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 54 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().
00056 { 00057 assert(cgs.num_columns() - 1 == gs.space_dimension() + 1); 00058 assert(dims > 0); 00059 00060 cgs.add_unit_rows_and_columns(dims); 00061 00062 // Add `dims' zero columns onto gs. 00063 gs.insert(parameter(0*Variable(space_dim + dims - 1))); 00064 00065 normalize_divisors(gs); 00066 00067 dim_kinds.resize(cgs.num_columns() - 1, EQUALITY /* a.k.a GEN_VIRTUAL */); 00068 }
PPL::Coefficient Parma_Polyhedra_Library::Grid::normalize_divisors | ( | Grid_Generator_System & | sys, | |
Coefficient_traits::const_reference | divisor = Coefficient_one() , |
|||
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.
divisor
was zero.sys | The generator system to be normalized. | |
divisor | An extra divisor to include in the calculation of the common divisor of sys . | |
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 440 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_generators(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and TEMP_INTEGER.
Referenced by add_generator(), add_recycled_generators(), add_recycled_generators_and_minimize(), add_space_dimensions(), add_space_dimensions_and_project(), affine_image(), construct(), generalized_affine_image(), generalized_affine_preimage(), join_assign(), normalize_divisors(), and time_elapse_assign().
00442 { 00443 assert(divisor >= 0); 00444 if (sys.space_dimension() > 0 && divisor > 0) { 00445 TEMP_INTEGER(lcm); 00446 lcm = divisor; 00447 00448 dimension_type row = 0; 00449 dimension_type num_rows = sys.num_generators(); 00450 00451 if (first_point) 00452 lcm_assign(lcm, lcm, (*first_point).divisor()); 00453 else { 00454 // Move to the first point or parameter. 00455 while (sys[row].is_line()) 00456 if (++row == num_rows) 00457 // All rows are lines. 00458 return divisor; 00459 00460 // Calculate the LCM of `divisor' and the divisor of every 00461 // point or parameter. 00462 while (row < num_rows) { 00463 Grid_Generator& g = sys[row]; 00464 if (g.is_parameter_or_point()) 00465 lcm_assign(lcm, lcm, g.divisor()); 00466 ++row; 00467 } 00468 } 00469 00470 // Represent every point and every parameter using the LCM as the 00471 // divisor. 00472 for (dimension_type row = 0; row < num_rows; ++row) 00473 sys[row].scale_to_divisor(lcm); 00474 00475 return lcm; 00476 } 00477 return divisor; 00478 }
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.
Definition at line 419 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Grid_Generator::divisor(), normalize_divisors(), and Parma_Polyhedra_Library::Grid_Generator_System::num_generators().
00420 { 00421 dimension_type row = 0; 00422 dimension_type num_rows = gen_sys.num_generators(); 00423 // Find first point in gen_sys. 00424 while (gen_sys[row].is_line_or_parameter()) 00425 if (++row == num_rows) 00426 // All rows are lines or parameters; generators should always 00427 // contain a point. 00428 throw std::runtime_error("PPL::Grid::normalize_divisors(sys, gen_sys)."); 00429 Grid_Generator& first_point = gen_sys[row]; 00430 Coefficient_traits::const_reference gen_sys_divisor = first_point.divisor(); 00431 Coefficient divisor = normalize_divisors(sys, gen_sys_divisor); 00432 if (divisor != gen_sys_divisor) 00433 // The divisors of the points in gen_sys are always the same, so 00434 // the new divisor will be the LCM of this value and `divisor', 00435 // hence the third argument. 00436 normalize_divisors(gen_sys, divisor, &first_point); 00437 }
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 355 of file Grid_conversion.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::ascii_dump(), Parma_Polyhedra_Library::Congruence_System::ascii_dump(), CON_VIRTUAL, EQUALITY, 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(), TEMP_INTEGER, Parma_Polyhedra_Library::TRACE(), trace_dim_kinds, and upper_triangular().
Referenced by update_generators().
00356 { 00357 TRACE(cerr << "============= convert cgs to gs" << endl); 00358 TRACE(cerr << "source:" << endl); 00359 TRACE(source.ascii_dump(cerr)); 00360 TRACE(cerr << "dest:" << endl); 00361 TRACE(dest.ascii_dump(cerr)); 00362 trace_dim_kinds("cgs to gs ", dim_kinds); 00363 00364 // Quite similar to the generator to congruence version above. 00365 // Changes here may be needed there too. 00366 00367 assert(lower_triangular(source, dim_kinds)); 00368 00369 // Initialise matrix row number counters and compute the LCM of the 00370 // diagonal entries of the proper congruences in `source'. 00371 dimension_type source_num_rows = 0, dest_num_rows = 0; 00372 TEMP_INTEGER(diagonal_lcm); 00373 diagonal_lcm = 1; 00374 dimension_type dims = source.num_columns() - 1; 00375 for (dimension_type dim = dims; dim-- > 0; ) 00376 if (dim_kinds[dim] == CON_VIRTUAL) 00377 // Virtual congruences map to lines. 00378 ++dest_num_rows; 00379 else { 00380 if (dim_kinds[dim] == PROPER_CONGRUENCE) { 00381 // Dimension `dim' has a proper congruence row at 00382 // `source_num_rows' in `source', so include in `diagonal_lcm' 00383 // the `dim'th element of that row. 00384 lcm_assign(diagonal_lcm, diagonal_lcm, source[source_num_rows][dim]); 00385 // Proper congruences map to parameters. 00386 ++dest_num_rows; 00387 } 00388 // Equalities map to virtual generators. 00389 ++source_num_rows; 00390 } 00391 TRACE(cerr << "diagonal_lcm: " << diagonal_lcm << endl); 00392 TRACE(cerr << "source_num_rows: " << source_num_rows << endl); 00393 TRACE(cerr << "dest_num_rows: " << dest_num_rows << endl); 00394 00395 // `source' must be regular. 00396 if (diagonal_lcm == 0) 00397 throw std::runtime_error("PPL internal error: Grid::conversion:" 00398 " source matrix is singular."); 00399 00400 dest.set_index_first_pending_row(dest_num_rows); 00401 dest.resize_no_copy(dest_num_rows, dims + 1 /* parameter divisor */); 00402 00403 // In `dest' initialize row types and elements, including setting 00404 // the diagonal elements to the inverse ratio of the `source' 00405 // diagonal elements. 00406 // 00407 // The top-down order of the congruence system rows corresponds to 00408 // the right-left order of the dimensions. 00409 dimension_type source_index = 0; 00410 // The generator system has a bottom-up ordering. 00411 dimension_type dest_index = dest_num_rows - 1; 00412 for (dimension_type dim = dims; dim-- > 0; ) { 00413 TRACE(cerr << "init dim " << dim << endl); 00414 if (dim_kinds[dim] == EQUALITY) { 00415 TRACE(cerr << " equality" << endl); 00416 ++source_index; 00417 } 00418 else { 00419 Grid_Generator& g = dest[dest_index]; 00420 for (dimension_type j = 0; j < dim; ++j) 00421 g[j] = 0; 00422 for (dimension_type j = dim + 1; j < dims; ++j) 00423 g[j] = 0; 00424 00425 if (dim_kinds[dim] == CON_VIRTUAL) { 00426 TRACE(cerr << " con_virtual" << endl); 00427 g.set_is_line(); 00428 g[dim] = 1; 00429 } 00430 else { 00431 assert(dim_kinds[dim] == PROPER_CONGRUENCE); 00432 TRACE(cerr << " proper_congruence" << endl); 00433 g.set_is_parameter_or_point(); 00434 g[dim] = diagonal_lcm / source[source_index][dim]; 00435 ++source_index; 00436 } 00437 --dest_index; 00438 } 00439 } 00440 00441 assert(upper_triangular(dest, dim_kinds)); 00442 00443 TRACE(cerr << "dest after init:" << endl); 00444 TRACE(dest.ascii_dump(cerr)); 00445 00446 // Convert. 00447 // 00448 // `source_index' and `dest_index' hold the positions of pivot rows 00449 // in `source' and `dest'. The order of the rows in `dest' is the 00450 // reverse of the order in `source', so the rows are iterated from 00451 // last to first (index 0) in `source' and from first to last in 00452 // `dest'. 00453 source_index = source_num_rows; 00454 dest_index = 0; 00455 00456 for (dimension_type dim = 0; dim < dims; ++dim) { 00457 TRACE(cerr << "dim: " << dim << endl); 00458 00459 if (dim_kinds[dim] != CON_VIRTUAL) { 00460 --source_index; 00461 TEMP_INTEGER(source_dim); 00462 source_dim = source[source_index][dim]; 00463 00464 // In the rows in `dest' above `dest_index' divide each element 00465 // at column `dim' by `source_dim'. 00466 for (dimension_type row = dest_index; row-- > 0; ) { 00467 TRACE(cerr << " row " << row << endl); 00468 TRACE(dest.ascii_dump(cerr)); 00469 00470 Grid_Generator& g = dest[row]; 00471 00472 // Multiply the representation of `dest' such that entry `dim' 00473 // of `g' is a multiple of `source_dim'. This ensures that 00474 // the result of the division that follows is a whole number. 00475 TEMP_INTEGER(red_source_dim); 00476 gcd_assign(red_source_dim, g[dim], source_dim); 00477 red_source_dim = source_dim / red_source_dim; 00478 multiply_grid(red_source_dim, g, dest, dest_num_rows, 00479 dims + 1 /* parameter divisor */); 00480 00481 g[dim] /= source_dim; 00482 } 00483 TRACE(cerr << "dest after dividing grid:" << endl); 00484 TRACE(dest.ascii_dump(cerr)); 00485 } 00486 00487 // Invert and transpose the source row at `source_index' into the 00488 // destination row at `dest_index'. 00489 // 00490 // Consider each dimension `dim_fol' that follows `dim', as the 00491 // rows in `dest' that follow row `dest_index' are zero at index 00492 // `dim'. 00493 dimension_type tem_source_index = source_index; 00494 if (dim_kinds[dim] != EQUALITY) 00495 ++dest_index; 00496 for (dimension_type dim_fol = dim + 1; dim_fol < dims; ++dim_fol) { 00497 TRACE(cerr << " dim_fol: " << dim_fol); 00498 TRACE(cerr << " dest_index: " << dest_index); 00499 TRACE(cerr << " tem_source_index: " << tem_source_index << endl); 00500 if (dim_kinds[dim_fol] != CON_VIRTUAL) { 00501 --tem_source_index; 00502 TEMP_INTEGER(source_dim); 00503 source_dim = source[tem_source_index][dim]; 00504 TRACE(cerr << " rows:" << endl); 00505 // In order to compute the transpose of the inverse of 00506 // `source', subtract source[tem_source_index][dim] times the 00507 // column vector in `dest' at `dim' from the column vector in 00508 // `dest' at `dim_fol'. 00509 // 00510 // I.e., for each row `dest_index' in `dest' that is above the 00511 // row `dest_index', subtract dest[tem_source_index][dim] 00512 // times the entry `dim' from the entry at `dim_fol'. 00513 for (dimension_type row = dest_index; row-- > 0; ) { 00514 assert(row < dest_num_rows); 00515 TRACE(cerr << " " << row << endl); 00516 Grid_Generator& g = dest[row]; 00517 g[dim_fol] -= source_dim * g[dim]; 00518 } 00519 } 00520 } 00521 TRACE(cerr << "dest after processing preceding rows:" << endl); 00522 TRACE(dest.ascii_dump(cerr)); 00523 } 00524 00525 assert(upper_triangular(dest, dim_kinds)); 00526 00527 #ifdef STRONG_REDUCTION 00528 for (dimension_type dim = 0, i = 0; dim < dims; ++dim) 00529 if (dim_kinds[dim] != GEN_VIRTUAL) 00530 // Factor the "diagonal" generator out of the preceding rows. 00531 reduce_reduced<Grid_Generator_System, Grid_Generator> 00532 (dest, dim, i++, dim, dims - 1, dim_kinds); 00533 TRACE(cerr << "dest after strong reduction:" << endl); 00534 TRACE(dest.ascii_dump(cerr)); 00535 #endif 00536 00537 // Ensure that the parameter divisors are the same as the divisor of 00538 // the point. 00539 Coefficient_traits::const_reference system_divisor = dest[0][0]; 00540 for (dimension_type row = 1, dim = 1; dim < dims; ++dim) 00541 switch (dim_kinds[dim]) { 00542 case PARAMETER: 00543 dest[row].divisor() = system_divisor; 00544 case LINE: 00545 ++row; 00546 case GEN_VIRTUAL: 00547 break; 00548 } 00549 TRACE(cerr << "dest after updating param divisors:" << endl); 00550 TRACE(dest.ascii_dump(cerr)); 00551 00552 trace_dim_kinds("cgs to gs end ", dim_kinds); 00553 00554 TRACE(cerr << "------------------- cgs to gs conversion done." << endl); 00555 }
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 158 of file Grid_conversion.cc.
References Parma_Polyhedra_Library::Congruence_System::ascii_dump(), Parma_Polyhedra_Library::Grid_Generator_System::ascii_dump(), CON_VIRTUAL, Parma_Polyhedra_Library::gcd_assign(), GEN_VIRTUAL, Parma_Polyhedra_Library::lcm_assign(), LINE, lower_triangular(), multiply_grid(), PARAMETER, Parma_Polyhedra_Library::Congruence_System::resize_no_copy(), Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), TEMP_INTEGER, Parma_Polyhedra_Library::TRACE(), trace_dim_kinds, and upper_triangular().
00159 { 00160 TRACE(cerr << "============= convert gs to cgs" << endl); 00161 TRACE(cerr << "source:" << endl); 00162 TRACE(source.ascii_dump(cerr)); 00163 TRACE(cerr << "dest:" << endl); 00164 TRACE(dest.ascii_dump(cerr)); 00165 trace_dim_kinds("gs to cgs ", dim_kinds); 00166 00167 // Quite similar to the congruence to generator version below. 00168 // Changes here may be needed there too. 00169 00170 assert(upper_triangular(source, dim_kinds)); 00171 00172 // Initialise matrix row number counters and compute the LCM of the 00173 // diagonal entries of the parameters in `source'. 00174 // 00175 // The top-down order of the parameter system rows corresponds to 00176 // the left-right order of the dimensions. 00177 dimension_type source_num_rows = 0; 00178 // The congruence system rows have a bottom-up ordering. 00179 dimension_type dest_num_rows = 0; 00180 TEMP_INTEGER(diagonal_lcm); 00181 diagonal_lcm = 1; 00182 const dimension_type dims = source.space_dimension() + 1; 00183 for (dimension_type dim = 0; dim < dims; ++dim) 00184 if (dim_kinds[dim] == GEN_VIRTUAL) 00185 // Virtual generators map to equalities. 00186 ++dest_num_rows; 00187 else { 00188 if (dim_kinds[dim] == PARAMETER) { 00189 // Dimension `dim' has a parameter row at `source_num_rows' in 00190 // `source', so include in `diagonal_lcm' the `dim'th element 00191 // of that row. 00192 lcm_assign(diagonal_lcm, diagonal_lcm, source[source_num_rows][dim]); 00193 // Parameters map to proper congruences. 00194 ++dest_num_rows; 00195 } 00196 // Lines map to virtual congruences. 00197 ++source_num_rows; 00198 } 00199 TRACE(cerr << "diagonal_lcm: " << diagonal_lcm << endl); 00200 TRACE(cerr << "source_num_rows: " << source_num_rows << endl); 00201 TRACE(cerr << "dest_num_rows: " << dest_num_rows << endl); 00202 00203 // `source' must be regular. 00204 if (diagonal_lcm == 0) 00205 throw std::runtime_error("PPL internal error: Grid::conversion:" 00206 " source matrix is singular."); 00207 00208 dest.resize_no_copy(dest_num_rows, dims + 1 /* moduli */); 00209 00210 // In `dest' initialize row types and elements, including setting 00211 // the diagonal elements to the inverse ratio of the `source' 00212 // diagonal elements. 00213 dimension_type source_index = 0, dest_index = dest_num_rows - 1; 00214 for (dimension_type dim = 0; dim < dims; ++dim) { 00215 TRACE(cerr << "init dim " << dim << endl); 00216 if (dim_kinds[dim] == LINE) { 00217 TRACE(cerr << " line" << endl); 00218 ++source_index; 00219 } 00220 else { 00221 Congruence& cg = dest[dest_index]; 00222 for (dimension_type j = 0; j < dim; j++) 00223 cg[j] = 0; 00224 for (dimension_type j = dim + 1; j < dims; j++) 00225 cg[j] = 0; 00226 00227 if (dim_kinds[dim] == GEN_VIRTUAL) { 00228 TRACE(cerr << " gen_virtual" << endl); 00229 cg[dims] = 0; // An equality. 00230 cg[dim] = 1; 00231 } 00232 else { 00233 assert(dim_kinds[dim] == PARAMETER); 00234 TRACE(cerr << " parameter" << endl); 00235 cg[dims] = 1; // A proper congruence. 00236 cg[dim] = diagonal_lcm / source[source_index][dim]; 00237 ++source_index; 00238 } 00239 --dest_index; 00240 } 00241 } 00242 00243 assert(lower_triangular(dest, dim_kinds)); 00244 00245 TRACE(cerr << "dest after init:" << endl); 00246 TRACE(dest.ascii_dump(cerr)); 00247 00248 // Convert. 00249 // 00250 // `source_index' and `dest_index' hold the positions of pivot rows 00251 // in `source' and `dest'. The order of the rows in `dest' is the 00252 // reverse of the order in `source', so the rows are iterated from 00253 // last to first (index 0) in `source' and from first to last in 00254 // `dest'. 00255 source_index = source_num_rows; 00256 dest_index = 0; 00257 00258 for (dimension_type dim = dims; dim-- > 0; ) { 00259 TRACE(cerr << "dim: " << dim << endl); 00260 00261 if (dim_kinds[dim] != GEN_VIRTUAL) { 00262 --source_index; 00263 TEMP_INTEGER(source_dim); 00264 source_dim = source[source_index][dim]; 00265 00266 // In the rows in `dest' above `dest_index' divide each element 00267 // at column `dim' by `source_dim'. 00268 for (dimension_type row = dest_index; row-- > 0; ) { 00269 TRACE(cerr << " row " << row << endl); 00270 TRACE(dest.ascii_dump(cerr)); 00271 00272 Congruence& cg = dest[row]; 00273 00274 // Multiply the representation of `dest' such that entry `dim' 00275 // of `g' is a multiple of `source_dim'. This ensures that 00276 // the result of the division that follows is a whole number. 00277 TEMP_INTEGER(multiplier); 00278 gcd_assign(multiplier, cg[dim], source_dim); 00279 multiplier = source_dim / multiplier; 00280 multiply_grid(multiplier, cg, dest, dest_num_rows, dims); 00281 00282 cg[dim] /= source_dim; 00283 } 00284 TRACE(cerr << "dest after dividing grid:" << endl); 00285 TRACE(dest.ascii_dump(cerr)); 00286 } 00287 00288 // Invert and transpose the source row at `source_index' into the 00289 // destination row at `dest_index'. 00290 // 00291 // Consider each dimension `dim_prec' that precedes `dim', as the 00292 // rows in `dest' that follow `dim_index' have zeroes at index 00293 // `dim'. 00294 dimension_type tem_source_index = source_index; 00295 if (dim_kinds[dim] != LINE) 00296 ++dest_index; 00297 for (dimension_type dim_prec = dim; dim_prec-- > 0; ) { 00298 TRACE(cerr << " dim_prec: " << dim_prec); 00299 TRACE(cerr << " dest_index: " << dest_index); 00300 TRACE(cerr << " tem_source_index: " << tem_source_index << endl); 00301 if (dim_kinds[dim_prec] != GEN_VIRTUAL) { 00302 --tem_source_index; 00303 TEMP_INTEGER(source_dim); 00304 source_dim = source[tem_source_index][dim]; 00305 TRACE(cerr << " rows:" << endl); 00306 // In order to compute the transpose of the inverse of 00307 // `source', subtract source[tem_source_index][dim] times the 00308 // column vector in `dest' at `dim' from the column vector in 00309 // `dest' at `dim_prec'. 00310 // 00311 // I.e., for each row `dest_index' in `dest' that is above the 00312 // row `dest_index', subtract dest[tem_source_index][dim] 00313 // times the entry `dim' from the entry at `dim_prec'. 00314 for (dimension_type row = dest_index; row-- > 0; ) { 00315 assert(row < dest_num_rows); 00316 TRACE(cerr << " " << row << endl); 00317 Congruence& cg = dest[row]; 00318 cg[dim_prec] -= source_dim * cg[dim]; 00319 } 00320 } 00321 } 00322 00323 TRACE(cerr << "dest after processing preceding rows:" << endl); 00324 TRACE(dest.ascii_dump(cerr)); 00325 } 00326 // Set the modulus in every congruence. 00327 Coefficient_traits::const_reference modulus = dest[dest_num_rows - 1][0]; 00328 for (dimension_type row = 0; row < dest_num_rows; ++row) { 00329 Congruence& cg = dest[row]; 00330 if (cg[dims] > 0) 00331 // `cg' is a proper congruence. 00332 cg[dims] = modulus; 00333 } 00334 TRACE(cerr << "dest after setting moduli:" << endl); 00335 TRACE(dest.ascii_dump(cerr)); 00336 00337 assert(lower_triangular(dest, dim_kinds)); 00338 00339 #ifdef STRONG_REDUCTION 00340 for (dimension_type dim = dims, i = 0; dim-- > 0; ) 00341 if (dim_kinds[dim] != CON_VIRTUAL) 00342 // Factor the "diagonal" congruence out of the preceding rows. 00343 reduce_reduced<Congruence_System, Congruence> 00344 (dest, dim, i++, 0, dim, dim_kinds, false); 00345 TRACE(cerr << "dest after strong reduction:" << endl); 00346 TRACE(dest.ascii_dump(cerr)); 00347 #endif 00348 00349 trace_dim_kinds("gs to cgs end ", dim_kinds); 00350 00351 TRACE(cerr << "------------------- gs to cgs conversion done." << endl); 00352 }
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 452 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::Matrix::add_zero_rows(), Parma_Polyhedra_Library::Congruence_System::ascii_dump(), 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(), Parma_Polyhedra_Library::TRACE(), and trace_dim_kinds.
Referenced by Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_discrete(), is_empty(), is_topologically_closed(), max_min(), minimize(), minimized_congruences(), minimized_generators(), OK(), update_generators(), and widening_assign().
00452 { 00453 TRACE(cerr << "======== simplify (reduce) cgs:" << endl); 00454 TRACE(cerr << "sys:" << endl); 00455 TRACE(sys.ascii_dump(cerr)); 00456 assert(sys.num_columns() > 2); 00457 00458 // Changes here may also be required in the generator version above. 00459 00460 // TODO: Consider normalizing the moduli only when congruences are 00461 // added to con_sys. 00462 sys.normalize_moduli(); 00463 00464 dimension_type num_cols = sys.num_columns() - 1 /* modulus */; 00465 00466 if (dim_kinds.size() != num_cols) 00467 dim_kinds.resize(num_cols); 00468 00469 dimension_type num_rows = sys.num_rows(); 00470 TRACE(cerr << " num_rows " << num_rows << endl); 00471 00472 // For each dimension `dim' move or construct a row into position 00473 // `pivot_index' such that the row has a value of zero in all 00474 // elements preceding column `dim' and some other value in column 00475 // `dim'. 00476 dimension_type pivot_index = 0; 00477 for (dimension_type dim = num_cols; dim-- > 0; ) { 00478 TRACE(cerr << "dim " << dim << endl); 00479 trace_dim_kinds(" ", dim_kinds); 00480 00481 // Consider the pivot and following rows. 00482 dimension_type row_index = pivot_index; 00483 TRACE(cerr << " row_index " << row_index << endl); 00484 00485 // Move down over rows which have zero in column `dim'. 00486 while (row_index < num_rows && sys[row_index][dim] == 0) { 00487 TRACE(cerr << " ."); 00488 ++row_index; 00489 } 00490 TRACE(cerr << endl); 00491 00492 if (row_index == num_rows) { 00493 // Element in column `dim' is zero in all rows from the pivot, 00494 // or `sys' is empty of rows. 00495 TRACE(cerr << " Marking virtual row" << endl); 00496 dim_kinds[dim] = CON_VIRTUAL; 00497 } 00498 else { 00499 // row_index != num_rows 00500 if (row_index != pivot_index) 00501 std::swap(sys[row_index], sys[pivot_index]); 00502 Congruence& pivot = sys[pivot_index]; 00503 bool pivot_is_equality = pivot.is_equality(); 00504 00505 // Change the matrix so that the value at `dim' in every row 00506 // following `pivot_index' is 0, leaving an equivalent grid. 00507 TRACE(cerr << " Reducing all following rows" << endl); 00508 while (row_index < num_rows - 1) { 00509 ++row_index; 00510 TRACE(cerr << " row_index " << row_index << endl); 00511 00512 Congruence& row = sys[row_index]; 00513 00514 if (row[dim] == 0) 00515 continue; 00516 00517 if (row.is_equality()) 00518 if (pivot_is_equality) 00519 reduce_equality_with_equality(row, pivot, dim); 00520 else { 00521 assert(pivot.is_proper_congruence()); 00522 std::swap(row, pivot); 00523 pivot_is_equality = true; 00524 reduce_congruence_with_equality(row, pivot, dim, sys); 00525 } 00526 else { 00527 assert(row.is_proper_congruence()); 00528 if (pivot_is_equality) 00529 reduce_congruence_with_equality(row, pivot, dim, sys); 00530 else { 00531 assert(pivot.is_proper_congruence()); 00532 reduce_pc_with_pc(row, pivot, dim, 0, dim); 00533 } 00534 } 00535 } 00536 00537 if (pivot_is_equality) 00538 dim_kinds[dim] = EQUALITY; 00539 else { 00540 assert(pivot.is_proper_congruence()); 00541 dim_kinds[dim] = PROPER_CONGRUENCE; 00542 } 00543 00544 #ifdef STRONG_REDUCTION 00545 // Ensure a positive follows the leading zeros. 00546 if (pivot[dim] < 0) 00547 pivot.negate(0, dim); 00548 // Factor this row out of the preceding ones. 00549 reduce_reduced<Congruence_System, Congruence> 00550 (sys, dim, pivot_index, 0, dim, dim_kinds, false); 00551 #endif 00552 ++pivot_index; 00553 } 00554 TRACE(sys.ascii_dump(cerr)); 00555 } // end for (dimension_type dim = num_cols; dim-- > 0; ) 00556 00557 dimension_type& reduced_num_rows = pivot_index; // For clearer naming. 00558 00559 // Clip any zero rows from the end of the matrix. 00560 if (num_rows > 1 && num_rows > reduced_num_rows) { 00561 TRACE(cerr << "clipping trailing" << endl); 00562 #ifndef NDEBUG 00563 bool ret = rows_are_zero<Congruence_System,Congruence> 00564 (sys, 00565 reduced_num_rows, // index of first 00566 num_rows - 1, // index of last 00567 num_cols); // row size 00568 assert(ret == true); 00569 #endif 00570 // Don't erase the last row as this will be changed to the integrality row. 00571 // FIXME Simplify and improve code if possible. 00572 if (reduced_num_rows > 0) 00573 sys.erase_to_end(reduced_num_rows); 00574 else 00575 sys.erase_to_end(1); 00576 } 00577 00578 assert(sys.num_rows() == reduced_num_rows 00579 || (sys.num_rows() == 1 && reduced_num_rows == 0)); 00580 00581 if (reduced_num_rows > 0) { 00582 // If the last row is false then make it the equality 1 = 0, and 00583 // make it the only row. 00584 Congruence& last_row = sys[reduced_num_rows - 1]; 00585 if (dim_kinds[0] == PROPER_CONGRUENCE) { 00586 if (last_row.inhomogeneous_term() % last_row.modulus() != 0) { 00587 // The last row is a false proper congruence. 00588 last_row.set_is_equality(); 00589 dim_kinds[0] = EQUALITY; 00590 goto return_empty; 00591 } 00592 } 00593 else if (dim_kinds[0] == EQUALITY) { 00594 // The last row is a false equality, as all the coefficient terms 00595 // are zero while the inhomogeneous term (as a result of the 00596 // reduced form) is some other value. 00597 return_empty: 00598 last_row[0] = 1; 00599 dim_kinds.resize(1); 00600 std::swap(sys.rows[0], sys.rows.back()); 00601 sys.erase_to_end(1); 00602 00603 trace_dim_kinds("cgs simpl end ", dim_kinds); 00604 assert(sys.OK()); 00605 TRACE(cerr << "---- simplify (reduce) cgs done (empty)." << endl); 00606 return true; 00607 } 00608 } 00609 else if (num_rows > 0) { 00610 assert(sys.num_rows() == 1); 00611 // All columns up to the modulus column must have been zero, set 00612 // up the integrality congruence. 00613 dim_kinds[0] = PROPER_CONGRUENCE; 00614 sys[0][num_cols] = 1; 00615 reduced_num_rows = 1; 00616 } 00617 00618 // Ensure that the last row is the integrality congruence. 00619 dimension_type mod_index = num_cols; 00620 if (dim_kinds[0] == CON_VIRTUAL) { 00621 // The last row is virtual, append the integrality congruence. 00622 dim_kinds[0] = PROPER_CONGRUENCE; 00623 sys.add_zero_rows(1, Linear_Row::Flags(NECESSARILY_CLOSED, 00624 Linear_Row::RAY_OR_POINT_OR_INEQUALITY)); 00625 Congruence& new_last_row = sys[reduced_num_rows]; 00626 new_last_row[mod_index] = 1; 00627 // Try use an existing modulus. 00628 dimension_type row_index = reduced_num_rows; 00629 while (row_index-- > 0) { 00630 Congruence& row = sys[row_index]; 00631 if (row[mod_index] > 0) { 00632 new_last_row[mod_index] = row[mod_index]; 00633 break; 00634 } 00635 } 00636 new_last_row[0] = new_last_row[mod_index]; 00637 #ifdef STRONG_REDUCTION 00638 ++reduced_num_rows; 00639 #endif 00640 } 00641 else { 00642 Congruence& last_row = sys[reduced_num_rows - 1]; 00643 last_row[0] = last_row[mod_index]; 00644 } 00645 00646 #ifdef STRONG_REDUCTION 00647 // Factor the modified integrality congruence out of the other rows. 00648 reduce_reduced<Congruence_System, Congruence> 00649 (sys, 0, reduced_num_rows - 1, 0, 0, dim_kinds, false); 00650 #endif 00651 00652 trace_dim_kinds("cgs simpl end ", dim_kinds); 00653 assert(sys.OK()); 00654 TRACE(cerr << "---- simplify (reduce) cgs done." << endl); 00655 return false; 00656 }
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 309 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::ascii_dump(), GEN_VIRTUAL, 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_generators(), Parma_Polyhedra_Library::Grid_Generator_System::OK(), PARAMETER, reduce_line_with_line(), reduce_parameter_with_line(), reduce_pc_with_pc(), Parma_Polyhedra_Library::TRACE(), trace_dim_kinds, and Parma_Polyhedra_Library::Grid_Generator_System::unset_pending_rows().
00309 { 00310 TRACE(cerr << "==== simplify (reduce) gs:" << endl); 00311 TRACE(cerr << "sys:" << endl); 00312 TRACE(sys.ascii_dump(cerr)); 00313 assert(sys.num_generators() > 0); 00314 assert(sys.num_columns() > 0); // For reduce_pc_with_pc. 00315 00316 // Changes here may also be required in the congruence version 00317 // below. 00318 00319 dimension_type num_cols = sys.num_columns() - 1 /* parameter divisor */; 00320 00321 if (dim_kinds.size() != num_cols) 00322 dim_kinds.resize(num_cols); 00323 00324 dimension_type num_rows = sys.num_generators(); 00325 TRACE(cerr << " num_rows " << num_rows << endl); 00326 00327 // For each dimension `dim' move or construct a row into position 00328 // `pivot_index' such that the row has zero in all elements 00329 // following column `dim' and a value other than zero in column 00330 // `dim'. 00331 dimension_type pivot_index = 0; 00332 for (dimension_type dim = 0; dim < num_cols; ++dim) { 00333 TRACE(cerr << "dim " << dim << endl); 00334 trace_dim_kinds(" ", dim_kinds); 00335 00336 // Consider the pivot and following rows. 00337 dimension_type row_index = pivot_index; 00338 TRACE(cerr << " row_index " << row_index << endl); 00339 00340 // Move down over rows which have zero in column `dim'. 00341 while (row_index < num_rows && sys[row_index][dim] == 0) { 00342 TRACE(cerr << " ."); 00343 ++row_index; 00344 } 00345 TRACE(cerr << endl); 00346 00347 if (row_index == num_rows) { 00348 // Element in column `dim' is zero in all rows from the pivot. 00349 TRACE(cerr << " Marking virtual row" << endl); 00350 dim_kinds[dim] = GEN_VIRTUAL; 00351 } 00352 else { 00353 if (row_index != pivot_index) 00354 std::swap(sys[row_index], sys[pivot_index]); 00355 Grid_Generator& pivot = sys[pivot_index]; 00356 bool pivot_is_line = pivot.is_line(); 00357 00358 // Change the matrix so that the value at `dim' in every row 00359 // following `pivot_index' is 0, leaving an equivalent grid. 00360 TRACE(cerr << " Reducing all following rows" << endl); 00361 while (row_index < num_rows - 1) { 00362 ++row_index; 00363 TRACE(cerr << " row_index " << row_index << endl); 00364 00365 Grid_Generator& row = sys[row_index]; 00366 00367 if (row[dim] == 0) 00368 continue; 00369 00370 if (row.is_line()) 00371 if (pivot_is_line) 00372 reduce_line_with_line(row, pivot, dim); 00373 else { 00374 assert(pivot.is_parameter_or_point()); 00375 std::swap(row, pivot); 00376 pivot_is_line = true; 00377 reduce_parameter_with_line(row, pivot, dim, sys); 00378 } 00379 else { 00380 assert(row.is_parameter_or_point()); 00381 if (pivot_is_line) 00382 reduce_parameter_with_line(row, pivot, dim, sys); 00383 else { 00384 assert(pivot.is_parameter_or_point()); 00385 reduce_pc_with_pc(row, pivot, dim, dim + 1, num_cols); 00386 } 00387 } 00388 } 00389 00390 if (pivot_is_line) 00391 dim_kinds[dim] = LINE; 00392 else { 00393 assert(pivot.is_parameter_or_point()); 00394 dim_kinds[dim] = PARAMETER; 00395 } 00396 00397 #ifdef STRONG_REDUCTION 00398 // Ensure a positive follows the leading zeros. 00399 if (pivot[dim] < 0) 00400 pivot.negate(dim, num_cols - 1); 00401 TRACE(cerr << " rr pivot_index " << pivot_index << endl); 00402 TRACE(sys.ascii_dump(cerr)); 00403 // Factor this row out of the preceding rows. 00404 reduce_reduced<Grid_Generator_System, Grid_Generator> 00405 (sys, dim, pivot_index, dim, num_cols - 1, dim_kinds); 00406 #endif 00407 00408 ++pivot_index; 00409 } 00410 TRACE(sys.ascii_dump(cerr)); 00411 } 00412 trace_dim_kinds("gs simpl end ", dim_kinds); 00413 00414 // Clip any zero rows from the end of the matrix. 00415 if (num_rows > pivot_index) { 00416 TRACE(cerr << "clipping trailing" << endl); 00417 #ifndef NDEBUG 00418 bool ret = rows_are_zero<Grid_Generator_System,Grid_Generator> 00419 (sys, 00420 pivot_index, // index of first 00421 sys.num_generators() - 1, // index of last 00422 sys.num_columns() - 1); // row size 00423 assert(ret == true); 00424 #endif 00425 sys.erase_to_end(pivot_index); 00426 } 00427 00428 sys.unset_pending_rows(); 00429 00430 // Ensure that the parameter divisors are the same as the system 00431 // divisor. 00432 TRACE(cerr << "updating param divisors" << endl); 00433 Coefficient_traits::const_reference system_divisor = sys[0][0]; 00434 for (dimension_type row = 1, dim = 1, num_cols = sys.num_columns() - 1; 00435 dim < num_cols; 00436 ++dim) 00437 switch (dim_kinds[dim]) { 00438 case PARAMETER: 00439 sys[row].divisor() = system_divisor; 00440 case LINE: 00441 ++row; 00442 case GEN_VIRTUAL: 00443 break; 00444 } 00445 00446 assert(sys.OK()); 00447 00448 TRACE(cerr << "---- simplify (reduce) gs done." << endl); 00449 }
void Parma_Polyhedra_Library::Grid::reduce_line_with_line | ( | Grid_Generator & | row, | |
Grid_Generator & | pivot, | |||
dimension_type | col | |||
) | [inline, 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 110 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Grid_Generator::size(), TEMP_INTEGER, and Parma_Polyhedra_Library::TRACE().
Referenced by simplify().
00111 { 00112 TRACE(cerr << "reduce_line_with_line" << endl); 00113 00114 TEMP_INTEGER(gcd); 00115 gcd_assign(gcd, pivot[column], row[column]); 00116 // Store the reduced ratio between pivot[column] and row[column]. 00117 TEMP_INTEGER(red_pivot_col); 00118 TEMP_INTEGER(red_row_col); 00119 red_pivot_col = pivot[column] / gcd; 00120 red_row_col = row[column] / gcd; 00121 // Multiply row, then subtract from it a multiple of pivot such that 00122 // the result in row[column] is zero. 00123 row[column] = 0; 00124 for (dimension_type col = pivot.size() - 2 /* parameter divisor, index */; 00125 col > column; 00126 --col) 00127 row[col] = (red_pivot_col * row[col]) - (red_row_col * pivot[col]); 00128 }
void Parma_Polyhedra_Library::Grid::reduce_equality_with_equality | ( | Congruence & | row, | |
Congruence & | pivot, | |||
dimension_type | col | |||
) | [inline, 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 131 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::gcd_assign(), Parma_Polyhedra_Library::Congruence::modulus(), TEMP_INTEGER, and Parma_Polyhedra_Library::TRACE().
Referenced by simplify().
00132 { 00133 TRACE(cerr << "reduce_equality_with_equality" << endl); 00134 // Assume two equalities. 00135 assert(row.modulus() == 0 && pivot.modulus() == 0); 00136 00137 TEMP_INTEGER(gcd); 00138 gcd_assign(gcd, pivot[column], row[column]); 00139 // Store the reduced ratio between pivot[column] and row[column]. 00140 TEMP_INTEGER(red_pivot_col); 00141 TEMP_INTEGER(red_row_col); 00142 red_pivot_col = pivot[column] / gcd; 00143 red_row_col = row[column] / gcd; 00144 // Multiply row, then subtract from it a multiple of pivot such that 00145 // the result in row[column] is zero. 00146 row[column] = 0; 00147 for (dimension_type col = 0; col < column; ++col) 00148 row[col] = (red_pivot_col * row[col]) - (red_row_col * pivot[col]); 00149 }
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 153 of file Grid_simplify.cc.
References Parma_Polyhedra_Library::gcdext_assign(), TEMP_INTEGER, and Parma_Polyhedra_Library::TRACE().
Referenced by simplify().
00156 { 00157 TEMP_INTEGER(gcd); 00158 TEMP_INTEGER(s); 00159 TEMP_INTEGER(t); 00160 gcdext_assign(gcd, pivot[column], row[column], s, t); 00161 // Now pivot[column] * s + row[column] * t == gcd. 00162 TRACE(cerr << " gcd " << gcd << ", s " << s << ", t " << t << endl); 00163 00164 // Store the reduced ratio between pivot[column] and row[column]. 00165 TEMP_INTEGER(red_pivot_col); 00166 TEMP_INTEGER(red_row_col); 00167 red_pivot_col = pivot[column] / gcd; 00168 red_row_col = row[column] / gcd; 00169 TRACE(cerr << " red_pivot_col " << red_pivot_col 00170 << ", red_row_col " << red_row_col << endl); 00171 00172 // Multiply row, then subtract from it a multiple of pivot such that 00173 // the result in row[column] is zero. Afterwards, multiply pivot, 00174 // then add to it a (possibly negative) multiple of row such that 00175 // the result in pivot[column] is the smallest possible positive 00176 // integer. 00177 assert(pivot.size() > 0); 00178 assert(row.size() > 0); 00179 pivot[column] = gcd; 00180 row[column] = 0; 00181 for (dimension_type col = start; col < end; ++col) { 00182 TEMP_INTEGER(pivot_col); 00183 TEMP_INTEGER(row_col); 00184 pivot_col = pivot[col]; 00185 row_col = row[col]; 00186 pivot[col] = (s * pivot_col) + (t * row_col); 00187 row[col] = (red_pivot_col * row_col) - (red_row_col * pivot_col); 00188 } 00189 }
void Parma_Polyhedra_Library::Grid::reduce_parameter_with_line | ( | Grid_Generator & | row, | |
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 192 of file Grid_simplify.cc.
References 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_generators(), TEMP_INTEGER, and Parma_Polyhedra_Library::TRACE().
Referenced by simplify().
00195 { 00196 // Very similar to reduce_congruence_with_equality below. Any 00197 // change here may be needed there too. 00198 TRACE(cerr << "reduce_parameter_with_line" << endl); 00199 00200 dimension_type num_cols = sys.num_columns() - 1 /* parameter divisor */; 00201 00202 // If the elements at column in row and pivot are the same, then 00203 // just subtract pivot from row. 00204 if (row[column] == pivot[column]) { 00205 for (dimension_type col = 0; col < num_cols; ++col) 00206 row[col] -= pivot[col]; 00207 return; 00208 } 00209 00210 TEMP_INTEGER(gcd); 00211 gcd_assign(gcd, pivot[column], row[column]); 00212 // Store the reduced ratio between pivot[column] and row[column]. 00213 TEMP_INTEGER(red_pivot_col); 00214 TEMP_INTEGER(red_row_col); 00215 red_pivot_col = pivot[column] / gcd; 00216 red_row_col = row[column] / gcd; 00217 00218 // Multiply row such that a multiple of pivot can be subtracted from 00219 // it below to render row[column] zero. This requires multiplying 00220 // all other parameters to match. 00221 #ifdef STRONG_REDUCTION 00222 // Ensure that the multiplier is positive, so that the preceding 00223 // diagonals (including the divisor) remain positive. It's safe to 00224 // swap the signs as row[column] will still come out 0. 00225 if (red_pivot_col < 0) { 00226 neg_assign(red_pivot_col); 00227 neg_assign(red_row_col); 00228 } 00229 #endif 00230 for (dimension_type index = 0; index < sys.num_generators(); ++index) { 00231 Grid_Generator& row = sys[index]; 00232 if (row.is_parameter_or_point()) 00233 for (dimension_type col = 0; col < num_cols; ++col) 00234 row[col] *= red_pivot_col; 00235 } 00236 // Subtract from row a multiple of pivot such that the result in 00237 // row[column] is zero. 00238 row[column] = 0; 00239 for (dimension_type col = num_cols - 1; col > column; --col) 00240 row[col] -= red_row_col * pivot[col]; 00241 }
void Parma_Polyhedra_Library::Grid::reduce_congruence_with_equality | ( | Congruence & | row, | |
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 244 of file Grid_simplify.cc.
References 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(), TEMP_INTEGER, and Parma_Polyhedra_Library::TRACE().
Referenced by simplify().
00247 { 00248 // Very similar to reduce_parameter_with_line above. Any change 00249 // here may be needed there too. 00250 TRACE(cerr << "reduce_congruence_with_equality" << endl); 00251 assert(row.modulus() > 0 && pivot.modulus() == 0); 00252 00253 dimension_type num_cols = sys.num_columns(); 00254 00255 // If the elements at `column' in row and pivot are the same, then 00256 // just subtract `pivot' from `row'. 00257 if (row[column] == pivot[column]) { 00258 for (dimension_type col = 0; col < num_cols; ++col) 00259 row[col] -= pivot[col]; 00260 return; 00261 } 00262 00263 TEMP_INTEGER(gcd); 00264 gcd_assign(gcd, pivot[column], row[column]); 00265 TEMP_INTEGER(red_pivot_col); 00266 TEMP_INTEGER(red_row_a); 00267 red_pivot_col = pivot[column] / gcd; 00268 red_row_a = row[column] / gcd; 00269 // Ensure that `red_pivot_col' is positive, so that the modulus 00270 // remains positive when multiplying the proper congruences below. 00271 // It's safe to swap the signs as row[column] will still come out 0. 00272 if (red_pivot_col < 0) { 00273 neg_assign(red_pivot_col); 00274 neg_assign(red_row_a); 00275 } 00276 // Multiply `row', including the modulus, by red_pivot_col. To keep 00277 // all the moduli the same this requires multiplying all the other 00278 // proper congruences in the same way. 00279 for (dimension_type index = 0; index < sys.num_rows(); ++index) { 00280 Congruence& row = sys[index]; 00281 if (row.is_proper_congruence()) 00282 for (dimension_type col = 0; col < num_cols; ++col) 00283 row[col] *= red_pivot_col; 00284 } 00285 --num_cols; // Modulus. 00286 row[column] = 0; 00287 // Subtract from row a multiple of pivot such that the result in 00288 // row[column] is zero. 00289 for (dimension_type col = 0; col < column; ++col) 00290 row[col] -= red_row_a * pivot[col]; 00291 }
void Parma_Polyhedra_Library::Grid::reduce_reduced | ( | M & | sys, | |
dimension_type | dim, | |||
dimension_type | pivot_index, | |||
dimension_type | start, | |||
dimension_type | end, | |||
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.
Definition at line 39 of file Grid_simplify.cc.
References CON_VIRTUAL, EQUALITY, GEN_VIRTUAL, LINE, PARAMETER, and TEMP_INTEGER.
00041 { 00042 R& pivot = sys[pivot_index]; 00043 00044 TEMP_INTEGER(pivot_dim); 00045 pivot_dim = pivot[dim]; 00046 00047 if (pivot_dim == 0) 00048 return; 00049 00050 TEMP_INTEGER(pivot_dim_half); 00051 pivot_dim_half = (pivot_dim + 1) / 2; 00052 Dimension_Kind row_kind = dim_kinds[dim]; 00053 Dimension_Kind line_or_equality, virtual_kind; 00054 int jump; 00055 if (generators) { 00056 line_or_equality = LINE; 00057 virtual_kind = GEN_VIRTUAL; 00058 jump = -1; 00059 } else { 00060 line_or_equality = EQUALITY; 00061 virtual_kind = CON_VIRTUAL; 00062 jump = 1; 00063 } 00064 00065 for (dimension_type row_index = pivot_index, kinds_index = dim + jump; 00066 row_index-- > 0; 00067 kinds_index += jump) { 00068 // Move over any virtual rows. 00069 while (dim_kinds[kinds_index] == virtual_kind) 00070 kinds_index += jump; 00071 00072 if (row_kind == line_or_equality 00073 || (row_kind == PARAMETER // a.k.a. CONGRUENCE 00074 && dim_kinds[kinds_index] == PARAMETER)) { 00075 R& row = sys[row_index]; 00076 00077 TEMP_INTEGER(row_dim); 00078 row_dim = row[dim]; 00079 // num_rows_to_subtract may be positive or negative. 00080 TEMP_INTEGER(num_rows_to_subtract); 00081 num_rows_to_subtract = row_dim / pivot_dim; 00082 00083 // Ensure that after subtracting num_rows_to_subtract * r_dim 00084 // from row_dim, 00085 // -pivot_dim_half < row_dim <= pivot_dim_half. E.g., if pivot[dim] = 00086 // 9, then after strong reduction -5 < row_dim <= 5. 00087 Coefficient& row_dim_rem = row_dim; 00088 row_dim_rem %= pivot_dim; 00089 if (row_dim_rem < 0) { 00090 if (row_dim_rem <= -pivot_dim_half) 00091 --num_rows_to_subtract; 00092 } 00093 else if (row_dim_rem > 0 && row_dim_rem > pivot_dim_half) 00094 num_rows_to_subtract++; 00095 00096 // Subtract num_rows_to_subtract copies of pivot from row i. Only the 00097 // entries from dim need to be subtracted, as the preceding 00098 // entries are all zero. 00099 // If num_rows_to_subtract is negative, these copies of pivot are 00100 // added to row i. 00101 if (num_rows_to_subtract != 0) 00102 for (dimension_type col = start; col <= end; ++col) 00103 row[col] -= num_rows_to_subtract * pivot[col]; 00104 } 00105 } 00106 }
void Parma_Polyhedra_Library::Grid::multiply_grid | ( | const Coefficient & | multiplier, | |
Congruence & | cg, | |||
Congruence_System & | dest, | |||
const dimension_type | num_rows, | |||
const dimension_type | num_dims | |||
) | [inline, static, private] |
Multiply the elements of dest
by multiplier
.
Definition at line 131 of file Grid_conversion.cc.
References Parma_Polyhedra_Library::Congruence::is_equality(), and Parma_Polyhedra_Library::Congruence::is_proper_congruence().
Referenced by conversion().
00133 { 00134 if (multiplier == 1) 00135 return; 00136 00137 if (cg.is_proper_congruence()) 00138 // Multiply every element of every congruence. 00139 for (dimension_type index = 0; index < num_rows; ++index) { 00140 Congruence& congruence = dest[index]; 00141 if (congruence.is_proper_congruence()) 00142 for (dimension_type column = 0; column < num_dims; ++column) 00143 congruence[column] *= multiplier; 00144 } 00145 else { 00146 assert(cg.is_equality()); 00147 // Multiply every element of the equality. 00148 for (dimension_type column = 0; column < num_dims; ++column) 00149 cg[column] *= multiplier; 00150 } 00151 }
void Parma_Polyhedra_Library::Grid::multiply_grid | ( | const Coefficient & | multiplier, | |
Grid_Generator & | gen, | |||
Grid_Generator_System & | dest, | |||
const dimension_type | num_rows, | |||
const dimension_type | num_dims | |||
) | [inline, static, private] |
Multiply the elements of dest
by multiplier
.
Definition at line 108 of file Grid_conversion.cc.
References Parma_Polyhedra_Library::Grid_Generator::is_line(), and Parma_Polyhedra_Library::Grid_Generator::is_parameter_or_point().
00110 { 00111 if (multiplier == 1) 00112 return; 00113 00114 if (gen.is_line()) 00115 // Multiply every element of the line. 00116 for (dimension_type column = 0; column < num_dims; ++column) 00117 gen[column] *= multiplier; 00118 else { 00119 assert(gen.is_parameter_or_point()); 00120 // Multiply every element of every parameter. 00121 for (dimension_type index = 0; index < num_rows; ++index) { 00122 Grid_Generator& generator = dest[index]; 00123 if (generator.is_parameter_or_point()) 00124 for (dimension_type column = 0; column < num_dims; ++column) 00125 generator[column] *= multiplier; 00126 } 00127 } 00128 }
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 43 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().
00044 { 00045 dimension_type num_cols = sys.num_columns() - 1; 00046 dimension_type row = sys.num_rows(); 00047 00048 // Check for easy square failure case. 00049 if (row > num_cols) 00050 return false; 00051 00052 // Check triangularity. 00053 for (dimension_type dim = 0; dim < num_cols; ++dim) { 00054 if (dim_kinds[dim] == CON_VIRTUAL) 00055 continue; 00056 const Congruence& cg = sys[--row]; 00057 // Check diagonal. 00058 if (cg[dim] <= 0) 00059 return false; 00060 // Check elements following diagonal. 00061 dimension_type col = dim; 00062 while (++col < num_cols) 00063 if (cg[col] != 0) 00064 return false; 00065 } 00066 00067 // Check squareness. 00068 return row == 0; 00069 }
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 78 of file Grid_conversion.cc.
References GEN_VIRTUAL, Parma_Polyhedra_Library::Grid_Generator_System::num_generators(), and Parma_Polyhedra_Library::Grid_Generator_System::space_dimension().
Referenced by conversion(), and OK().
00079 { 00080 dimension_type num_cols = sys.space_dimension() + 1; 00081 dimension_type row = sys.num_generators(); 00082 00083 // Check for easy square fail case. 00084 if (row > num_cols) 00085 return false; 00086 00087 // Check triangularity. 00088 while (num_cols > 0) { 00089 --num_cols; 00090 if (dim_kinds[num_cols] == GEN_VIRTUAL) 00091 continue; 00092 const Grid_Generator& gen = sys[--row]; 00093 // Check diagonal. 00094 if (gen[num_cols] <= 0) 00095 return false; 00096 // Check elements preceding diagonal. 00097 dimension_type col = num_cols; 00098 while (col-- > 0) 00099 if (gen[col] != 0) 00100 return false; 00101 } 00102 00103 // Check for squareness. 00104 return num_cols == row; 00105 }
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 296 of file Grid_simplify.cc.
00297 { 00298 while (first <= last) { 00299 R& row = system[first++]; 00300 for (dimension_type col = 0; col < row_size; ++col) 00301 if (row[col] != 0) 00302 return false; 00303 } 00304 return true; 00305 }
void Parma_Polyhedra_Library::Grid::throw_runtime_error | ( | const char * | method | ) | const [protected] |
Definition at line 481 of file Grid_nonpublic.cc.
00481 { 00482 std::ostringstream s; 00483 s << "PPL::Grid::" << method << "." << std::endl; 00484 throw std::runtime_error(s.str()); 00485 }
void Parma_Polyhedra_Library::Grid::throw_invalid_argument | ( | const char * | method, | |
const char * | reason | |||
) | const [protected] |
Definition at line 488 of file Grid_nonpublic.cc.
Referenced by affine_image(), affine_preimage(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), Grid(), and shrink_bounding_box().
00489 { 00490 std::ostringstream s; 00491 s << "PPL::Grid::" << method << ":" << std::endl 00492 << reason << "."; 00493 throw std::invalid_argument(s.str()); 00494 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | other_name, | |||
dimension_type | other_dim | |||
) | const [protected] |
Definition at line 497 of file Grid_nonpublic.cc.
References space_dimension().
Referenced by add_congruence(), add_congruences(), add_congruences_and_minimize(), add_constraint(), add_constraint_and_minimize(), add_constraints(), add_constraints_and_minimize(), add_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_constraints(), add_recycled_constraints_and_minimize(), add_recycled_generators(), add_recycled_generators_and_minimize(), affine_image(), affine_preimage(), bounds(), contains(), expand_space_dimension(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), get_covering_box(), grid_difference_assign(), intersection_assign(), is_disjoint_from(), join_assign(), join_assign_if_exact(), limited_extrapolation_assign(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), shrink_bounding_box(), throw_dimension_incompatible(), time_elapse_assign(), and widening_assign().
00499 { 00500 std::ostringstream s; 00501 s << "PPL::Grid::" << method << ":\n" 00502 << "this->space_dimension() == " << space_dimension() << ", " 00503 << other_name << ".space_dimension() == " << other_dim << "."; 00504 throw std::invalid_argument(s.str()); 00505 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | gr_name, | |||
const Grid & | gr | |||
) | const [protected] |
Definition at line 508 of file Grid_nonpublic.cc.
References space_dimension(), and throw_dimension_incompatible().
00510 { 00511 throw_dimension_incompatible(method, gr_name, gr.space_dimension()); 00512 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | e_name, | |||
const Linear_Expression & | e | |||
) | const [protected] |
Definition at line 515 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Linear_Expression::space_dimension(), and throw_dimension_incompatible().
00517 { 00518 throw_dimension_incompatible(method, e_name, e.space_dimension()); 00519 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | cg_name, | |||
const Congruence & | cg | |||
) | const [protected] |
Definition at line 522 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Congruence::space_dimension(), and throw_dimension_incompatible().
00524 { 00525 throw_dimension_incompatible(method, cg_name, cg.space_dimension()); 00526 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | c_name, | |||
const Constraint & | c | |||
) | const [protected] |
Definition at line 529 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Constraint::space_dimension(), and throw_dimension_incompatible().
00531 { 00532 throw_dimension_incompatible(method, c_name, c.space_dimension()); 00533 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | g_name, | |||
const Grid_Generator & | g | |||
) | const [protected] |
Definition at line 536 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Grid_Generator::space_dimension(), and throw_dimension_incompatible().
00538 { 00539 throw_dimension_incompatible(method, g_name, g.space_dimension()); 00540 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | cgs_name, | |||
const Congruence_System & | cgs | |||
) | const [protected] |
Definition at line 543 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Congruence_System::space_dimension(), and throw_dimension_incompatible().
00545 { 00546 throw_dimension_incompatible(method, cgs_name, cgs.space_dimension()); 00547 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | cs_name, | |||
const Constraint_System & | cs | |||
) | const [protected] |
Definition at line 550 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Constraint_System::space_dimension(), and throw_dimension_incompatible().
00552 { 00553 throw_dimension_incompatible(method, cs_name, cs.space_dimension()); 00554 }
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 557 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Grid_Generator_System::space_dimension(), and throw_dimension_incompatible().
00559 { 00560 throw_dimension_incompatible(method, gs_name, gs.space_dimension()); 00561 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
const char * | var_name, | |||
const Variable | var | |||
) | const [protected] |
Definition at line 564 of file Grid_nonpublic.cc.
References Parma_Polyhedra_Library::Variable::space_dimension(), and space_dimension().
00566 { 00567 std::ostringstream s; 00568 s << "PPL::Grid::" << method << ":" << std::endl 00569 << "this->space_dimension() == " << space_dimension() << ", " 00570 << var_name << ".space_dimension() == " << var.space_dimension() << "."; 00571 throw std::invalid_argument(s.str()); 00572 }
void Parma_Polyhedra_Library::Grid::throw_dimension_incompatible | ( | const char * | method, | |
dimension_type | required_space_dim | |||
) | const [protected] |
Definition at line 576 of file Grid_nonpublic.cc.
References space_dimension().
00577 { 00578 std::ostringstream s; 00579 s << "PPL::Grid::" << method << ":" << std::endl 00580 << "this->space_dimension() == " << space_dimension() 00581 << ", required space dimension == " << required_space_dim << "."; 00582 throw std::invalid_argument(s.str()); 00583 }
void Parma_Polyhedra_Library::Grid::throw_space_dimension_overflow | ( | const char * | method, | |
const char * | reason | |||
) | [static, protected] |
Definition at line 586 of file Grid_nonpublic.cc.
Referenced by add_space_dimensions_and_embed(), add_space_dimensions_and_project(), concatenate_assign(), expand_space_dimension(), and Grid().
00587 { 00588 std::ostringstream s; 00589 s << "PPL::Grid::" << method << ":" << std::endl 00590 << reason << "."; 00591 throw std::length_error(s.str()); 00592 }
void Parma_Polyhedra_Library::Grid::throw_invalid_generator | ( | const char * | method, | |
const char * | g_name | |||
) | const [protected] |
Definition at line 595 of file Grid_nonpublic.cc.
Referenced by add_generator().
00596 { 00597 std::ostringstream s; 00598 s << "PPL::Grid::" << method << ":" << std::endl 00599 << "*this is an empty grid and " 00600 << g_name << " is not a point."; 00601 throw std::invalid_argument(s.str()); 00602 }
void Parma_Polyhedra_Library::Grid::throw_invalid_generators | ( | const char * | method, | |
const char * | gs_name | |||
) | const [protected] |
Definition at line 605 of file Grid_nonpublic.cc.
Referenced by add_recycled_generators(), add_recycled_generators_and_minimize(), and construct().
00606 { 00607 std::ostringstream s; 00608 s << "PPL::Grid::" << method << ":" << std::endl 00609 << "*this is an empty grid and" << std::endl 00610 << "the non-empty generator system " << gs_name << " contains no points."; 00611 throw std::invalid_argument(s.str()); 00612 }
friend class Parma_Polyhedra_Library::Grid_Certificate [friend] |
Definition at line 1914 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 2046 of file Grid_public.cc.
02046 { 02047 if (x.space_dim != y.space_dim) 02048 return false; 02049 02050 if (x.marked_empty()) 02051 return y.is_empty(); 02052 if (y.marked_empty()) 02053 return x.is_empty(); 02054 if (x.space_dim == 0) 02055 return true; 02056 02057 switch (x.quick_equivalence_test(y)) { 02058 case Grid::TVB_TRUE: 02059 return true; 02060 02061 case Grid::TVB_FALSE: 02062 return false; 02063 02064 default: 02065 if (x.is_included_in(y)) { 02066 if (x.marked_empty()) 02067 return y.is_empty(); 02068 return y.is_included_in(x); 02069 } 02070 return false; 02071 } 02072 }
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 2210 of file Grid_public.cc.
References is_empty(), is_universe(), and minimized_congruences().
02210 { 02211 if (gr.is_empty()) 02212 s << "false"; 02213 else if (gr.is_universe()) 02214 s << "true"; 02215 else 02216 s << gr.minimized_congruences(); 02217 return s; 02218 }
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 247 of file Grid.inlines.hh.
void swap | ( | Parma_Polyhedra_Library::Grid & | x, | |
Parma_Polyhedra_Library::Grid & | y | |||
) | [related] |
Specializes std::swap
.
Definition at line 131 of file Grid.inlines.hh.
References swap().
00132 { 00133 x.swap(y); 00134 }
The system of congruences.
Definition at line 1952 of file Grid.defs.hh.
Referenced by add_congruence(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), concatenate_assign(), congruences(), construct(), external_memory_in_bytes(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), intersection_assign(), is_discrete(), is_empty(), is_included_in(), is_topologically_closed(), is_universe(), map_space_dimensions(), minimize(), minimized_congruences(), OK(), operator=(), quick_equivalence_test(), relation_with(), select_wider_congruences(), set_empty(), set_zero_dim_univ(), swap(), update_generators(), and widening_assign().
The system of generators.
Definition at line 1955 of file Grid.defs.hh.
Referenced by add_generator(), add_recycled_generators(), add_recycled_generators_and_minimize(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), affine_image(), affine_preimage(), ascii_dump(), ascii_load(), bounds(), construct(), external_memory_in_bytes(), generalized_affine_image(), generalized_affine_preimage(), generators(), get_covering_box(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_bounded(), is_discrete(), is_topologically_closed(), join_assign(), map_space_dimensions(), max_min(), minimize(), minimized_generators(), OK(), operator=(), quick_equivalence_test(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), set_empty(), set_zero_dim_univ(), shrink_bounding_box(), swap(), time_elapse_assign(), update_congruences(), and update_generators().
Status Parma_Polyhedra_Library::Grid::status [private] |
The status flags to keep track of the grid's internal state.
Definition at line 2128 of file Grid.defs.hh.
Referenced by add_recycled_congruences(), 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(), 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 2131 of file Grid.defs.hh.
Referenced by add_congruence(), add_congruences(), add_congruences_and_minimize(), add_constraint(), add_constraint_and_minimize(), add_constraints(), add_constraints_and_minimize(), add_generator(), add_recycled_congruences(), add_recycled_congruences_and_minimize(), add_recycled_constraints(), add_recycled_constraints_and_minimize(), add_recycled_generators(), add_recycled_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(), bounds(), concatenate_assign(), congruences(), construct(), contains(), expand_space_dimension(), fold_space_dimensions(), generalized_affine_image(), generalized_affine_preimage(), generators(), get_covering_box(), Grid(), grid_difference_assign(), intersection_assign(), is_bounded(), is_discrete(), is_disjoint_from(), is_empty(), is_included_in(), is_topologically_closed(), is_universe(), join_assign(), join_assign_if_exact(), limited_extrapolation_assign(), map_space_dimensions(), max_min(), minimize(), minimized_congruences(), minimized_generators(), OK(), operator=(), quick_equivalence_test(), relation_with(), remove_higher_space_dimensions(), remove_space_dimensions(), select_wider_congruences(), set_empty(), set_zero_dim_univ(), shrink_bounding_box(), space_dimension(), swap(), time_elapse_assign(), update_congruences(), update_generators(), and widening_assign().
Definition at line 2150 of file Grid.defs.hh.
Referenced by add_space_dimensions(), add_space_dimensions_and_embed(), add_space_dimensions_and_project(), ascii_dump(), ascii_load(), Grid(), Parma_Polyhedra_Library::Grid_Certificate::Grid_Certificate(), is_discrete(), is_empty(), is_topologically_closed(), max_min(), minimize(), minimized_congruences(), minimized_generators(), OK(), operator=(), remove_higher_space_dimensions(), select_wider_congruences(), swap(), update_generators(), and widening_assign().