PPL
1.2
|
The powerset construction instantiated on PPL pointset domains. More...
#include <ppl.hh>
Public Member Functions | |
void | ascii_dump () const |
Writes to std::cerr an ASCII representation of *this . | |
void | ascii_dump (std::ostream &s) const |
Writes to s an ASCII representation of *this . | |
void | print () const |
Prints *this to std::cerr using operator<< . | |
bool | ascii_load (std::istream &s) |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise. | |
Constructors | |
Pointset_Powerset (dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE) | |
Builds a universe (top) or empty (bottom) Pointset_Powerset. More... | |
Pointset_Powerset (const Pointset_Powerset &y, Complexity_Class complexity=ANY_COMPLEXITY) | |
Ordinary copy constructor. More... | |
template<typename QH > | |
Pointset_Powerset (const Pointset_Powerset< QH > &y, Complexity_Class complexity=ANY_COMPLEXITY) | |
Conversion constructor: the type QH of the disjuncts in the source powerset is different from PSET . More... | |
template<typename QH1 , typename QH2 , typename R > | |
Pointset_Powerset (const Partially_Reduced_Product< QH1, QH2, R > &prp, Complexity_Class complexity=ANY_COMPLEXITY) | |
Creates a Pointset_Powerset from a product This will be created as a single disjunct of type PSET that approximates the product. | |
Pointset_Powerset (const Constraint_System &cs) | |
Creates a Pointset_Powerset with a single disjunct approximating the system of constraints cs . | |
Pointset_Powerset (const Congruence_System &cgs) | |
Creates a Pointset_Powerset with a single disjunct approximating the system of congruences cgs . | |
Pointset_Powerset (const C_Polyhedron &ph, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a pointset_powerset out of a closed polyhedron. More... | |
Pointset_Powerset (const NNC_Polyhedron &ph, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a pointset_powerset out of an nnc polyhedron. More... | |
Pointset_Powerset (const Grid &gr, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a pointset_powerset out of a grid. More... | |
template<typename T > | |
Pointset_Powerset (const Octagonal_Shape< T > &os, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a pointset_powerset out of an octagonal shape. More... | |
template<typename T > | |
Pointset_Powerset (const BD_Shape< T > &bds, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a pointset_powerset out of a bd shape. More... | |
template<typename Interval > | |
Pointset_Powerset (const Box< Interval > &box, Complexity_Class complexity=ANY_COMPLEXITY) | |
Builds a pointset_powerset out of a box. More... | |
Member Functions that Do Not Modify the Pointset_Powerset | |
dimension_type | space_dimension () const |
Returns the dimension of the vector space enclosing *this . | |
dimension_type | affine_dimension () const |
Returns the dimension of the vector space enclosing *this . | |
bool | is_empty () const |
Returns true if and only if *this is an empty powerset. | |
bool | is_universe () const |
Returns true if and only if *this is the top element of the powerset lattice. | |
bool | is_topologically_closed () const |
Returns true if and only if all the disjuncts in *this are topologically closed. | |
bool | is_bounded () const |
Returns true if and only if all elements in *this are bounded. | |
bool | is_disjoint_from (const Pointset_Powerset &y) const |
Returns true if and only if *this and y are disjoint. More... | |
bool | is_discrete () const |
Returns true if and only if *this is discrete. | |
bool | constrains (Variable var) const |
Returns true if and only if var is constrained in *this . More... | |
bool | bounds_from_above (const Linear_Expression &expr) const |
Returns true if and only if expr is bounded from above in *this . More... | |
bool | bounds_from_below (const Linear_Expression &expr) const |
Returns true if and only if expr is bounded from below in *this . More... | |
bool | maximize (const Linear_Expression &expr, Coefficient &sup_n, Coefficient &sup_d, bool &maximum) const |
Returns true if and only if *this is not empty and expr is bounded from above in *this , in which case the supremum value is computed. More... | |
bool | maximize (const Linear_Expression &expr, Coefficient &sup_n, Coefficient &sup_d, bool &maximum, Generator &g) const |
Returns true if and only if *this is not empty and expr is bounded from above in *this , in which case the supremum value and a point where expr reaches it are computed. More... | |
bool | minimize (const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum) const |
Returns true if and only if *this is not empty and expr is bounded from below in *this , in which case the infimum value is computed. More... | |
bool | minimize (const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum, Generator &g) const |
Returns true if and only if *this is not empty and expr is bounded from below in *this , in which case the infimum value and a point where expr reaches it are computed. More... | |
bool | geometrically_covers (const Pointset_Powerset &y) const |
Returns true if and only if *this geometrically covers y , i.e., if any point (in some element) of y is also a point (of some element) of *this . More... | |
bool | geometrically_equals (const Pointset_Powerset &y) const |
Returns true if and only if *this is geometrically equal to y , i.e., if (the elements of) *this and y contain the same set of points. More... | |
bool | contains (const Pointset_Powerset &y) const |
Returns true if and only if each disjunct of y is contained in a disjunct of *this . More... | |
bool | strictly_contains (const Pointset_Powerset &y) const |
Returns true if and only if each disjunct of y is strictly contained in a disjunct of *this . More... | |
bool | contains_integer_point () const |
Returns true if and only if *this contains at least one integer point. | |
Poly_Con_Relation | relation_with (const Constraint &c) const |
Returns the relations holding between the powerset *this and the constraint c . More... | |
Poly_Gen_Relation | relation_with (const Generator &g) const |
Returns the relations holding between the powerset *this and the generator g . More... | |
Poly_Con_Relation | relation_with (const Congruence &cg) const |
Returns the relations holding between the powerset *this and the congruence c . More... | |
memory_size_type | total_memory_in_bytes () const |
Returns a lower bound to the total size in bytes of the memory occupied by *this . | |
memory_size_type | external_memory_in_bytes () const |
Returns a lower bound to the size in bytes of the memory managed by *this . | |
int32_t | hash_code () const |
Returns a 32-bit hash code for *this . More... | |
bool | OK () const |
Checks if all the invariants are satisfied. | |
Space Dimension Preserving Member Functions that May Modify the Pointset_Powerset | |
void | add_disjunct (const PSET &ph) |
Adds to *this the disjunct ph . More... | |
void | add_constraint (const Constraint &c) |
Intersects *this with constraint c . More... | |
void | refine_with_constraint (const Constraint &c) |
Use the constraint c to refine *this . More... | |
void | add_constraints (const Constraint_System &cs) |
Intersects *this with the constraints in cs . More... | |
void | refine_with_constraints (const Constraint_System &cs) |
Use the constraints in cs to refine *this . More... | |
void | add_congruence (const Congruence &cg) |
Intersects *this with congruence cg . More... | |
void | refine_with_congruence (const Congruence &cg) |
Use the congruence cg to refine *this . More... | |
void | add_congruences (const Congruence_System &cgs) |
Intersects *this with the congruences in cgs . More... | |
void | refine_with_congruences (const Congruence_System &cgs) |
Use the congruences in cgs to refine *this . More... | |
void | unconstrain (Variable var) |
Computes the cylindrification of *this with respect to space dimension var , assigning the result to *this . More... | |
void | unconstrain (const Variables_Set &vars) |
Computes the cylindrification of *this with respect to the set of space dimensions vars , assigning the result to *this . More... | |
void | drop_some_non_integer_points (Complexity_Class complexity=ANY_COMPLEXITY) |
Possibly tightens *this by dropping some points with non-integer coordinates. More... | |
void | drop_some_non_integer_points (const Variables_Set &vars, Complexity_Class complexity=ANY_COMPLEXITY) |
Possibly tightens *this by dropping some points with non-integer coordinates for the space dimensions corresponding to vars . More... | |
void | topological_closure_assign () |
Assigns to *this its topological closure. | |
void | intersection_assign (const Pointset_Powerset &y) |
Assigns to *this the intersection of *this and y . More... | |
void | difference_assign (const Pointset_Powerset &y) |
Assigns to *this an (a smallest) over-approximation as a powerset of the disjunct domain of the set-theoretical difference of *this and y . More... | |
bool | simplify_using_context_assign (const Pointset_Powerset &y) |
Assigns to *this a meet-preserving simplification of *this with respect to y . If false is returned, then the intersection is empty. More... | |
void | affine_image (Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the affine image of *this under the function mapping variable var to the affine expression specified by expr and denominator . More... | |
void | affine_preimage (Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the affine preimage of *this under the function mapping variable var to the affine expression specified by expr and denominator . More... | |
void | generalized_affine_image (Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the image of *this with respect to the generalized affine relation ![]() ![]() relsym . More... | |
void | generalized_affine_preimage (Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the preimage of *this with respect to the generalized affine relation ![]() ![]() relsym . More... | |
void | generalized_affine_image (const Linear_Expression &lhs, Relation_Symbol relsym, const Linear_Expression &rhs) |
Assigns to *this the image of *this with respect to the generalized affine relation ![]() ![]() relsym . More... | |
void | generalized_affine_preimage (const Linear_Expression &lhs, Relation_Symbol relsym, const Linear_Expression &rhs) |
Assigns to *this the preimage of *this with respect to the generalized affine relation ![]() ![]() relsym . More... | |
void | bounded_affine_image (Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the image of *this with respect to the bounded affine relation ![]() | |
void | bounded_affine_preimage (Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one()) |
Assigns to *this the preimage of *this with respect to the bounded affine relation ![]() | |
void | time_elapse_assign (const Pointset_Powerset &y) |
Assigns to *this the result of computing the time-elapse between *this and y . More... | |
void | wrap_assign (const Variables_Set &vars, Bounded_Integer_Type_Width w, Bounded_Integer_Type_Representation r, Bounded_Integer_Type_Overflow o, const Constraint_System *cs_p=0, unsigned complexity_threshold=16, bool wrap_individually=true) |
Wraps the specified dimensions of the vector space. More... | |
void | pairwise_reduce () |
Assign to *this the result of (recursively) merging together the pairs of disjuncts whose upper-bound is the same as their set-theoretical union. More... | |
template<typename Widening > | |
void | BGP99_extrapolation_assign (const Pointset_Powerset &y, Widening widen_fun, unsigned max_disjuncts) |
Assigns to *this the result of applying the BGP99 extrapolation operator to *this and y , using the widening function widen_fun and the cardinality threshold max_disjuncts . More... | |
template<typename Cert , typename Widening > | |
void | BHZ03_widening_assign (const Pointset_Powerset &y, Widening widen_fun) |
Assigns to *this the result of computing the BHZ03-widening between *this and y , using the widening function widen_fun certified by the convergence certificate Cert . More... | |
Member Functions that May Modify the Dimension of the Vector Space | |
Pointset_Powerset & | operator= (const Pointset_Powerset &y) |
The assignment operator (*this and y can be dimension-incompatible). | |
template<typename QH > | |
Pointset_Powerset & | operator= (const Pointset_Powerset< QH > &y) |
Conversion assignment: the type QH of the disjuncts in the source powerset is different from PSET (*this and y can be dimension-incompatible). | |
void | m_swap (Pointset_Powerset &y) |
Swaps *this with y . | |
void | add_space_dimensions_and_embed (dimension_type m) |
Adds m new dimensions to the vector space containing *this and embeds each disjunct in *this in the new space. | |
void | add_space_dimensions_and_project (dimension_type m) |
Adds m new dimensions to the vector space containing *this without embedding the disjuncts in *this in the new space. | |
void | concatenate_assign (const Pointset_Powerset &y) |
Assigns to *this the concatenation of *this and y . More... | |
void | remove_space_dimensions (const Variables_Set &vars) |
Removes all the specified space dimensions. More... | |
void | remove_higher_space_dimensions (dimension_type new_dimension) |
Removes the higher space dimensions so that the resulting space will have dimension new_dimension . More... | |
template<typename Partial_Function > | |
void | map_space_dimensions (const Partial_Function &pfunc) |
Remaps the dimensions of the vector space according to a partial function. More... | |
void | expand_space_dimension (Variable var, dimension_type m) |
Creates m copies of the space dimension corresponding to var . More... | |
void | fold_space_dimensions (const Variables_Set &vars, Variable dest) |
Folds the space dimensions in vars into dest . More... | |
![]() | |
Powerset () | |
Default constructor: builds the bottom of the powerset constraint system (i.e., the empty powerset). | |
Powerset (const Powerset &y) | |
Copy constructor. | |
Powerset (const Parma_Polyhedra_Library::Determinate< PSET > &d) | |
If d is not bottom, builds a powerset containing only d . Builds the empty powerset otherwise. | |
~Powerset () | |
Destructor. | |
bool | definitely_entails (const Powerset &y) const |
Returns true if *this definitely entails y . Returns false if *this may not entail y (i.e., if *this does not entail y or if entailment could not be decided). | |
bool | is_top () const |
Returns true if and only if *this is the top element of the powerset constraint system (i.e., it represents the universe). | |
bool | is_bottom () const |
Returns true if and only if *this is the bottom element of the powerset constraint system (i.e., it represents the empty set). | |
memory_size_type | total_memory_in_bytes () const |
Returns a lower bound to the total size in bytes of the memory occupied by *this . | |
memory_size_type | external_memory_in_bytes () const |
Returns a lower bound to the size in bytes of the memory managed by *this . | |
bool | OK (bool disallow_bottom=false) const |
Checks if all the invariants are satisfied. | |
void | omega_reduce () const |
Drops from the sequence of disjuncts in *this all the non-maximal elements so that *this is non-redundant. More... | |
size_type | size () const |
Returns the number of disjuncts. | |
bool | empty () const |
Returns true if and only if there are no disjuncts in *this . | |
iterator | begin () |
Returns an iterator pointing to the first disjunct, if *this is not empty; otherwise, returns the past-the-end iterator. | |
const_iterator | begin () const |
Returns a const_iterator pointing to the first disjunct, if *this is not empty; otherwise, returns the past-the-end const_iterator. | |
iterator | end () |
Returns the past-the-end iterator. | |
const_iterator | end () const |
Returns the past-the-end const_iterator. | |
reverse_iterator | rbegin () |
Returns a reverse_iterator pointing to the last disjunct, if *this is not empty; otherwise, returns the before-the-start reverse_iterator. | |
const_reverse_iterator | rbegin () const |
Returns a const_reverse_iterator pointing to the last disjunct, if *this is not empty; otherwise, returns the before-the-start const_reverse_iterator. | |
reverse_iterator | rend () |
Returns the before-the-start reverse_iterator. | |
const_reverse_iterator | rend () const |
Returns the before-the-start const_reverse_iterator. | |
void | add_disjunct (const Parma_Polyhedra_Library::Determinate< PSET > &d) |
Adds to *this the disjunct d . | |
iterator | drop_disjunct (iterator position) |
Drops the disjunct in *this pointed to by position , returning an iterator to the disjunct following position . | |
void | drop_disjuncts (iterator first, iterator last) |
Drops all the disjuncts from first to last (excluded). | |
void | clear () |
Drops all the disjuncts, making *this an empty powerset. | |
Powerset & | operator= (const Powerset &y) |
The assignment operator. | |
void | m_swap (Powerset &y) |
Swaps *this with y . | |
void | least_upper_bound_assign (const Powerset &y) |
Assigns to *this the least upper bound of *this and y . | |
void | upper_bound_assign (const Powerset &y) |
Assigns to *this an upper bound of *this and y . More... | |
bool | upper_bound_assign_if_exact (const Powerset &y) |
Assigns to *this the least upper bound of *this and y and returns true . More... | |
void | meet_assign (const Powerset &y) |
Assigns to *this the meet of *this and y . | |
void | collapse () |
If *this is not empty (i.e., it is not the bottom element), it is reduced to a singleton obtained by computing an upper-bound of all the disjuncts. | |
Static Public Member Functions | |
static dimension_type | max_space_dimension () |
Returns the maximum space dimension a Pointset_Powerset<PSET> can handle. | |
Related Functions | |
(Note that these are not member functions.) | |
template<typename PSET > | |
Widening_Function< PSET > | widen_fun_ref (void(PSET::*wm)(const PSET &, unsigned *)) |
Wraps a widening method into a function object. More... | |
template<typename PSET , typename CSYS > | |
Limited_Widening_Function< PSET, CSYS > | widen_fun_ref (void(PSET::*lwm)(const PSET &, const CSYS &, unsigned *), const CSYS &cs) |
Wraps a limited widening method into a function object. More... | |
template<typename PSET > | |
Widening_Function< PSET > | widen_fun_ref (void(PSET::*wm)(const PSET &, unsigned *)) |
template<typename PSET , typename CSYS > | |
Limited_Widening_Function< PSET, CSYS > | widen_fun_ref (void(PSET::*lwm)(const PSET &, const CSYS &, unsigned *), const CSYS &cs) |
template<typename PSET > | |
void | swap (Pointset_Powerset< PSET > &x, Pointset_Powerset< PSET > &y) |
Swaps x with y . More... | |
template<typename PSET > | |
std::pair< PSET, Pointset_Powerset< NNC_Polyhedron > > | linear_partition (const PSET &p, const PSET &q) |
Partitions q with respect to p . More... | |
bool | check_containment (const NNC_Polyhedron &ph, const Pointset_Powerset< NNC_Polyhedron > &ps) |
Returns true if and only if the union of the NNC polyhedra in ps contains the NNC polyhedron ph . | |
std::pair< Grid, Pointset_Powerset< Grid > > | approximate_partition (const Grid &p, const Grid &q, bool &finite_partition) |
Partitions the grid q with respect to grid p if and only if such a partition is finite. More... | |
bool | check_containment (const Grid &ph, const Pointset_Powerset< Grid > &ps) |
Returns true if and only if the union of the grids ps contains the grid g . | |
template<typename PSET > | |
bool | check_containment (const PSET &ph, const Pointset_Powerset< PSET > &ps) |
Returns true if and only if the union of the objects in ps contains ph . More... | |
template<typename PSET > | |
bool | check_containment (const PSET &ph, const Pointset_Powerset< PSET > &ps) |
template<> | |
bool | check_containment (const C_Polyhedron &ph, const Pointset_Powerset< C_Polyhedron > &ps) |
template<typename PSET > | |
void | swap (Pointset_Powerset< PSET > &x, Pointset_Powerset< PSET > &y) |
template<typename PSET > | |
std::pair< PSET, Pointset_Powerset< NNC_Polyhedron > > | linear_partition (const PSET &p, const PSET &q) |
Additional Inherited Members | |
![]() | |
typedef iterator_to_const< Sequence > | iterator |
Alias for a read-only bidirectional iterator on the disjuncts of a Powerset element. More... | |
typedef const_iterator_to_const< Sequence > | const_iterator |
A bidirectional const_iterator on the disjuncts of a Powerset element. | |
typedef std::reverse_iterator< iterator > | reverse_iterator |
The reverse iterator type built from Powerset::iterator. | |
typedef std::reverse_iterator< const_iterator > | const_reverse_iterator |
The reverse iterator type built from Powerset::const_iterator. | |
![]() | |
typedef std::list< Parma_Polyhedra_Library::Determinate< PSET > > | Sequence |
A powerset is implemented as a sequence of elements. More... | |
typedef Sequence::iterator | Sequence_iterator |
Alias for the low-level iterator on the disjuncts. | |
typedef Sequence::const_iterator | Sequence_const_iterator |
Alias for the low-level const_iterator on the disjuncts. | |
![]() | |
void | collapse (unsigned max_disjuncts) |
Upon return, *this will contain at most max_disjuncts elements; the set of disjuncts in positions greater than or equal to max_disjuncts , will be replaced at that position by their upper-bound. | |
bool | is_omega_reduced () const |
Returns true if and only if *this does not contain non-maximal elements. | |
iterator | add_non_bottom_disjunct_preserve_reduction (const Parma_Polyhedra_Library::Determinate< PSET > &d, iterator first, iterator last) |
Adds to *this the disjunct d , assuming d is not the bottom element and ensuring partial Omega-reduction. More... | |
void | add_non_bottom_disjunct_preserve_reduction (const Parma_Polyhedra_Library::Determinate< PSET > &d) |
Adds to *this the disjunct d , assuming d is not the bottom element and preserving Omega-reduction. More... | |
void | pairwise_apply_assign (const Powerset &y, Binary_Operator_Assign op_assign) |
Assigns to *this the result of applying op_assign pairwise to the elements in *this and y . More... | |
![]() | |
Sequence | sequence |
The sequence container holding powerset's elements. | |
bool | reduced |
If true , *this is Omega-reduced. | |
The powerset construction instantiated on PPL pointset domains.
PSET
are the simple pointset domains: C_Polyhedron
, NNC_Polyhedron
, Grid
, Octagonal_Shape<T>
, BD_Shape<T>
, Box<T>
.
|
inlineexplicit |
Builds a universe (top) or empty (bottom) Pointset_Powerset.
num_dimensions | The number of dimensions of the vector space enclosing the powerset; |
kind | Specifies whether the universe or the empty powerset has to be built. |
|
inline |
Ordinary copy constructor.
The complexity argument is ignored.
|
explicit |
Conversion constructor: the type QH
of the disjuncts in the source powerset is different from PSET
.
y | The powerset to be used to build the new powerset. |
complexity | The maximal complexity of any algorithms used. |
|
inlineexplicit |
Builds a pointset_powerset out of a closed polyhedron.
Builds a powerset that is either empty (if the polyhedron is found to be empty) or contains a single disjunct approximating the polyhedron; this must only use algorithms that do not exceed the specified complexity. The powerset inherits the space dimension of the polyhedron.
ph | The closed polyhedron to be used to build the powerset. |
complexity | The maximal complexity of any algorithms used. |
std::length_error | Thrown if the space dimension of ph exceeds the maximum allowed space dimension. |
|
inlineexplicit |
Builds a pointset_powerset out of an nnc polyhedron.
Builds a powerset that is either empty (if the polyhedron is found to be empty) or contains a single disjunct approximating the polyhedron; this must only use algorithms that do not exceed the specified complexity. The powerset inherits the space dimension of the polyhedron.
ph | The closed polyhedron to be used to build the powerset. |
complexity | The maximal complexity of any algorithms used. |
std::length_error | Thrown if the space dimension of ph exceeds the maximum allowed space dimension. |
|
inlineexplicit |
Builds a pointset_powerset out of a grid.
If the grid is nonempty, builds a powerset containing a single disjunct approximating the grid. Builds the empty powerset otherwise. The powerset inherits the space dimension of the grid.
gr | The grid to be used to build the powerset. |
complexity | This argument is ignored. |
std::length_error | Thrown if the space dimension of gr exceeds the maximum allowed space dimension. |
|
explicit |
Builds a pointset_powerset out of an octagonal shape.
If the octagonal shape is nonempty, builds a powerset containing a single disjunct approximating the octagonal shape. Builds the empty powerset otherwise. The powerset inherits the space dimension of the octagonal shape.
os | The octagonal shape to be used to build the powerset. |
complexity | This argument is ignored. |
std::length_error | Thrown if the space dimension of os exceeds the maximum allowed space dimension. |
|
explicit |
Builds a pointset_powerset out of a bd shape.
If the bd shape is nonempty, builds a powerset containing a single disjunct approximating the bd shape. Builds the empty powerset otherwise. The powerset inherits the space dimension of the bd shape.
bds | The bd shape to be used to build the powerset. |
complexity | This argument is ignored. |
std::length_error | Thrown if the space dimension of bds exceeds the maximum allowed space dimension. |
|
explicit |
Builds a pointset_powerset out of a box.
If the box is nonempty, builds a powerset containing a single disjunct approximating the box. Builds the empty powerset otherwise. The powerset inherits the space dimension of the box.
box | The box to be used to build the powerset. |
complexity | This argument is ignored. |
std::length_error | Thrown if the space dimension of box exceeds the maximum allowed space dimension. |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::is_disjoint_from | ( | const Pointset_Powerset< PSET > & | y | ) | const |
Returns true
if and only if *this
and y
are disjoint.
std::invalid_argument | Thrown if x and y are topology-incompatible or dimension-incompatible. |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::constrains | ( | Variable | var | ) | const |
Returns true
if and only if var
is constrained in *this
.
std::invalid_argument | Thrown if var is not a space dimension of *this . |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::bounds_from_above | ( | const Linear_Expression & | expr | ) | const |
Returns true
if and only if expr
is bounded from above in *this
.
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::bounds_from_below | ( | const Linear_Expression & | expr | ) | const |
Returns true
if and only if expr
is bounded from below in *this
.
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::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.
expr | The linear expression to be maximized subject to *this ; |
sup_n | The numerator of the supremum value; |
sup_d | The denominator of the supremum value; |
maximum | true if and only if the supremum is also the maximum value. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
If *this
is empty or expr
is not bounded from above, false
is returned and sup_n
, sup_d
and maximum
are left untouched.
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::maximize | ( | const Linear_Expression & | expr, |
Coefficient & | sup_n, | ||
Coefficient & | sup_d, | ||
bool & | maximum, | ||
Generator & | g | ||
) | const |
Returns true
if and only if *this
is not empty and expr
is bounded from above in *this
, in which case the supremum value and a point where expr
reaches it are computed.
expr | The linear expression to be maximized subject to *this ; |
sup_n | The numerator of the supremum value; |
sup_d | The denominator of the supremum value; |
maximum | true if and only if the supremum is also the maximum value; |
g | When maximization succeeds, will be assigned the point or closure point where expr reaches its supremum value. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
If *this
is empty or expr
is not bounded from above, false
is returned and sup_n
, sup_d
, maximum
and g
are left untouched.
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::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.
expr | The linear expression to be minimized subject to *this ; |
inf_n | The numerator of the infimum value; |
inf_d | The denominator of the infimum value; |
minimum | true if and only if the infimum is also the minimum value. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
If *this
is empty or expr
is not bounded from below, false
is returned and inf_n
, inf_d
and minimum
are left untouched.
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::minimize | ( | const Linear_Expression & | expr, |
Coefficient & | inf_n, | ||
Coefficient & | inf_d, | ||
bool & | minimum, | ||
Generator & | g | ||
) | const |
Returns true
if and only if *this
is not empty and expr
is bounded from below in *this
, in which case the infimum value and a point where expr
reaches it are computed.
expr | The linear expression to be minimized subject to *this ; |
inf_n | The numerator of the infimum value; |
inf_d | The denominator of the infimum value; |
minimum | true if and only if the infimum is also the minimum value; |
g | When minimization succeeds, will be assigned a point or closure point where expr reaches its infimum value. |
std::invalid_argument | Thrown if expr and *this are dimension-incompatible. |
If *this
is empty or expr
is not bounded from below, false
is returned and inf_n
, inf_d
, minimum
and g
are left untouched.
|
inline |
Returns true
if and only if *this
geometrically covers y
, i.e., if any point (in some element) of y
is also a point (of some element) of *this
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
|
inline |
Returns true
if and only if *this
is geometrically equal to y
, i.e., if (the elements of) *this
and y
contain the same set of points.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::contains | ( | const Pointset_Powerset< PSET > & | y | ) | const |
Returns true
if and only if each disjunct of y
is contained in a disjunct of *this
.
std::invalid_argument | Thrown if *this and y are topology-incompatible or dimension-incompatible. |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::strictly_contains | ( | const Pointset_Powerset< PSET > & | y | ) | const |
Returns true
if and only if each disjunct of y
is strictly contained in a disjunct of *this
.
std::invalid_argument | Thrown if *this and y are topology-incompatible or dimension-incompatible. |
|
inline |
Returns the relations holding between the powerset *this
and the constraint c
.
std::invalid_argument | Thrown if *this and constraint c are dimension-incompatible. |
Poly_Gen_Relation Parma_Polyhedra_Library::Pointset_Powerset< PSET >::relation_with | ( | const Generator & | g | ) | const |
Returns the relations holding between the powerset *this
and the generator g
.
std::invalid_argument | Thrown if *this and generator g are dimension-incompatible. |
|
inline |
Returns the relations holding between the powerset *this
and the congruence c
.
std::invalid_argument | Thrown if *this and congruence c are dimension-incompatible. |
|
inline |
Returns a 32-bit hash code for *this
.
If x
and y
are such that x == y
, then x.hash_code() == y.hash_code()
.
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::add_disjunct | ( | const PSET & | ph | ) |
Adds to *this
the disjunct ph
.
std::invalid_argument | Thrown if *this and ph are dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::add_constraint | ( | const Constraint & | c | ) |
Intersects *this
with constraint c
.
std::invalid_argument | Thrown if *this and constraint c are topology-incompatible or dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::refine_with_constraint | ( | const Constraint & | c | ) |
Use the constraint c
to refine *this
.
c | The constraint to be used for refinement. |
std::invalid_argument | Thrown if *this and c are dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::add_constraints | ( | const Constraint_System & | cs | ) |
Intersects *this
with the constraints in cs
.
cs | The constraints to intersect with. |
std::invalid_argument | Thrown if *this and cs are topology-incompatible or dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::refine_with_constraints | ( | const Constraint_System & | cs | ) |
Use the constraints in cs
to refine *this
.
cs | The constraints to be used for refinement. |
std::invalid_argument | Thrown if *this and cs are dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::add_congruence | ( | const Congruence & | cg | ) |
Intersects *this
with congruence cg
.
std::invalid_argument | Thrown if *this and congruence cg are topology-incompatible or dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::refine_with_congruence | ( | const Congruence & | cg | ) |
Use the congruence cg
to refine *this
.
cg | The congruence to be used for refinement. |
std::invalid_argument | Thrown if *this and cg are dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::add_congruences | ( | const Congruence_System & | cgs | ) |
Intersects *this
with the congruences in cgs
.
cgs | The congruences to intersect with. |
std::invalid_argument | Thrown if *this and cgs are topology-incompatible or dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::refine_with_congruences | ( | const Congruence_System & | cgs | ) |
Use the congruences in cgs
to refine *this
.
cgs | The congruences to be used for refinement. |
std::invalid_argument | Thrown if *this and cgs are dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::unconstrain | ( | Variable | var | ) |
Computes the cylindrification of *this
with respect to space dimension var
, assigning the result to *this
.
var | The space dimension that will be unconstrained. |
std::invalid_argument | Thrown if var is not a space dimension of *this . |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::unconstrain | ( | const Variables_Set & | vars | ) |
Computes the cylindrification of *this
with respect to the set of space dimensions vars
, assigning the result to *this
.
vars | The set of space dimension that will be unconstrained. |
std::invalid_argument | Thrown if *this is dimension-incompatible with one of the Variable objects contained in vars . |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::drop_some_non_integer_points | ( | Complexity_Class | complexity = ANY_COMPLEXITY | ) |
Possibly tightens *this
by dropping some points with non-integer coordinates.
complexity | The maximal complexity of any algorithms used. |
complexity
is ANY_COMPLEXITY
. void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::drop_some_non_integer_points | ( | const Variables_Set & | vars, |
Complexity_Class | complexity = ANY_COMPLEXITY |
||
) |
Possibly tightens *this
by dropping some points with non-integer coordinates for the space dimensions corresponding to vars
.
vars | Points with non-integer coordinates for these variables/space-dimensions can be discarded. |
complexity | The maximal complexity of any algorithms used. |
complexity
is ANY_COMPLEXITY
.
|
inline |
Assigns to *this
the intersection of *this
and y
.
The result is obtained by intersecting each disjunct in *this
with each disjunct in y
and collecting all these intersections.
|
inline |
Assigns to *this
an (a smallest) over-approximation as a powerset of the disjunct domain of the set-theoretical difference of *this
and y
.
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
bool Parma_Polyhedra_Library::Pointset_Powerset< PSET >::simplify_using_context_assign | ( | const Pointset_Powerset< PSET > & | y | ) |
Assigns to *this
a meet-preserving simplification of *this
with respect to y
. If false
is returned, then the intersection is empty.
std::invalid_argument | Thrown if *this and y are topology-incompatible or dimension-incompatible. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::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 . |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::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 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 . |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::generalized_affine_image | ( | Variable | var, |
Relation_Symbol | relsym, | ||
const Linear_Expression & | expr, | ||
Coefficient_traits::const_reference | denominator = Coefficient_one() |
||
) |
Assigns to *this
the image of *this
with respect to the generalized affine relation , where
is the relation symbol encoded by
relsym
.
var | The left hand side variable of the generalized affine relation; |
relsym | The relation symbol; |
expr | The numerator of the right hand side affine expression; |
denominator | The denominator of the right hand side 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 or if *this is a C_Polyhedron and relsym is a strict relation symbol. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::generalized_affine_preimage | ( | Variable | var, |
Relation_Symbol | relsym, | ||
const Linear_Expression & | expr, | ||
Coefficient_traits::const_reference | denominator = Coefficient_one() |
||
) |
Assigns to *this
the preimage of *this
with respect to the generalized affine relation , where
is the relation symbol encoded by
relsym
.
var | The left hand side variable of the generalized affine relation; |
relsym | The relation symbol; |
expr | The numerator of the right hand side affine expression; |
denominator | The denominator of the right hand side 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 or if *this is a C_Polyhedron and relsym is a strict relation symbol. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::generalized_affine_image | ( | const Linear_Expression & | lhs, |
Relation_Symbol | relsym, | ||
const Linear_Expression & | rhs | ||
) |
Assigns to *this
the image of *this
with respect to the generalized affine relation , where
is the relation symbol encoded by
relsym
.
lhs | The left hand side affine expression; |
relsym | The relation symbol; |
rhs | The right hand side affine expression. |
std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs or if *this is a C_Polyhedron and relsym is a strict relation symbol. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::generalized_affine_preimage | ( | const Linear_Expression & | lhs, |
Relation_Symbol | relsym, | ||
const Linear_Expression & | rhs | ||
) |
Assigns to *this
the preimage of *this
with respect to the generalized affine relation , where
is the relation symbol encoded by
relsym
.
lhs | The left hand side affine expression; |
relsym | The relation symbol; |
rhs | The right hand side affine expression. |
std::invalid_argument | Thrown if *this is dimension-incompatible with lhs or rhs or if *this is a C_Polyhedron and relsym is a strict relation symbol. |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::bounded_affine_image | ( | Variable | var, |
const Linear_Expression & | lb_expr, | ||
const Linear_Expression & | ub_expr, | ||
Coefficient_traits::const_reference | denominator = Coefficient_one() |
||
) |
Assigns to *this
the image of *this
with respect to the bounded affine relation .
var | The variable updated by the affine relation; |
lb_expr | The numerator of the lower bounding affine expression; |
ub_expr | The numerator of the upper bounding affine expression; |
denominator | The (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1). |
std::invalid_argument | Thrown if denominator is zero or if lb_expr (resp., ub_expr ) and *this are dimension-incompatible or if var is not a space dimension of *this . |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::bounded_affine_preimage | ( | Variable | var, |
const Linear_Expression & | lb_expr, | ||
const Linear_Expression & | ub_expr, | ||
Coefficient_traits::const_reference | denominator = Coefficient_one() |
||
) |
Assigns to *this
the preimage of *this
with respect to the bounded affine relation .
var | The variable updated by the affine relation; |
lb_expr | The numerator of the lower bounding affine expression; |
ub_expr | The numerator of the upper bounding affine expression; |
denominator | The (common) denominator for the lower and upper bounding affine expressions (optional argument with default value 1). |
std::invalid_argument | Thrown if denominator is zero or if lb_expr (resp., ub_expr ) and *this are dimension-incompatible or if var is not a space dimension of *this . |
|
inline |
Assigns to *this
the result of computing the time-elapse between *this
and y
.
The result is obtained by computing the pairwise time elapse of each disjunct in *this
with each disjunct in y
.
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::wrap_assign | ( | const Variables_Set & | vars, |
Bounded_Integer_Type_Width | w, | ||
Bounded_Integer_Type_Representation | r, | ||
Bounded_Integer_Type_Overflow | o, | ||
const Constraint_System * | cs_p = 0 , |
||
unsigned | complexity_threshold = 16 , |
||
bool | wrap_individually = true |
||
) |
Wraps the specified dimensions of the vector space.
vars | The set of Variable objects corresponding to the space dimensions to be wrapped. |
w | The width of the bounded integer type corresponding to all the dimensions to be wrapped. |
r | The representation of the bounded integer type corresponding to all the dimensions to be wrapped. |
o | The overflow behavior of the bounded integer type corresponding to all the dimensions to be wrapped. |
cs_p | Possibly null pointer to a constraint system whose variables are contained in vars . If *cs_p depends on variables not in vars , the behavior is undefined. When non-null, the pointed-to constraint system is assumed to represent the conditional or looping construct guard with respect to which wrapping is performed. Since wrapping requires the computation of upper bounds and due to non-distributivity of constraint refinement over upper bounds, passing a constraint system in this way can be more precise than refining the result of the wrapping operation with the constraints in *cs_p . |
complexity_threshold | A precision parameter of the wrapping operator: higher values result in possibly improved precision. |
wrap_individually | true if the dimensions should be wrapped individually (something that results in much greater efficiency to the detriment of precision). |
std::invalid_argument | Thrown if *cs_p is dimension-incompatible with vars , or if *this is dimension-incompatible vars or with *cs_p . |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::pairwise_reduce | ( | ) |
Assign to *this
the result of (recursively) merging together the pairs of disjuncts whose upper-bound is the same as their set-theoretical union.
On exit, for all the pairs ,
of different disjuncts in
*this
, we have .
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::BGP99_extrapolation_assign | ( | const Pointset_Powerset< PSET > & | y, |
Widening | widen_fun, | ||
unsigned | max_disjuncts | ||
) |
Assigns to *this
the result of applying the BGP99 extrapolation operator to *this
and y
, using the widening function widen_fun
and the cardinality threshold max_disjuncts
.
y | A powerset that must definitely entail *this ; |
widen_fun | The widening function to be used on polyhedra objects. It is obtained from the corresponding widening method by using the helper function Parma_Polyhedra_Library::widen_fun_ref. Legal values are, e.g., widen_fun_ref(&Polyhedron::H79_widening_assign) and widen_fun_ref(&Polyhedron::limited_H79_extrapolation_assign, cs) ; |
max_disjuncts | The maximum number of disjuncts occurring in the powerset *this before starting the computation. If this number is exceeded, some of the disjuncts in *this are collapsed (i.e., joined together). |
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
For a description of the extrapolation operator, see [BGP99] and [BHZ03b].
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::BHZ03_widening_assign | ( | const Pointset_Powerset< PSET > & | y, |
Widening | widen_fun | ||
) |
Assigns to *this
the result of computing the BHZ03-widening between *this
and y
, using the widening function widen_fun
certified by the convergence certificate Cert
.
y | The finite powerset computed in the previous iteration step. It must definitely entail *this ; |
widen_fun | The widening function to be used on disjuncts. It is obtained from the corresponding widening method by using the helper function widen_fun_ref. Legal values are, e.g., widen_fun_ref(&Polyhedron::H79_widening_assign) and widen_fun_ref(&Polyhedron::limited_H79_extrapolation_assign, cs) . |
std::invalid_argument | Thrown if *this and y are dimension-incompatible. |
Cert
should be a finite convergence certificate for the base-level widening function widen_fun
; otherwise, an extrapolation operator is obtained. For a description of the methods that should be provided by Cert
, see BHRZ03_Certificate or H79_Certificate. void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::concatenate_assign | ( | const Pointset_Powerset< PSET > & | y | ) |
Assigns to *this
the concatenation of *this
and y
.
The result is obtained by computing the pairwise concatenation of each disjunct in *this
with each disjunct in y
.
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::remove_space_dimensions | ( | const Variables_Set & | vars | ) |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::remove_higher_space_dimensions | ( | dimension_type | new_dimension | ) |
Removes the higher space dimensions 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 . |
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::map_space_dimensions | ( | const Partial_Function & | pfunc | ) |
Remaps the dimensions of the vector space according to a partial function.
See also Polyhedron::map_space_dimensions.
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::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() . |
If *this
has space dimension , with
, and
var
has space dimension , then the
-th space dimension is expanded to
m
new space dimensions ,
,
,
.
void Parma_Polyhedra_Library::Pointset_Powerset< PSET >::fold_space_dimensions | ( | const Variables_Set & | vars, |
Variable | dest | ||
) |
Folds the space dimensions in vars
into dest
.
vars | The set of Variable objects corresponding to the space dimensions to be folded; |
dest | 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 dest or with one of the Variable objects contained in vars . Also thrown if dest is contained in vars . |
If *this
has space dimension , with
,
dest
has space dimension ,
vars
is a set of variables whose maximum space dimension is also less than or equal to , and
dest
is not a member of vars
, then the space dimensions corresponding to variables in vars
are folded into the -th space dimension.
|
related |
Wraps a widening method into a function object.
wm | The widening method. |
|
related |
Wraps a limited widening method into a function object.
lwm | The limited widening method. |
cs | The constraint system limiting the widening. |
|
related |
|
related |
|
related |
Swaps x
with y
.
|
related |
Partitions q
with respect to p
.
Let p
and q
be two polyhedra. The function returns an object r
of type std::pair<PSET, Pointset_Powerset<NNC_Polyhedron> >
such that
r.first
is the intersection of p
and q
;r.second
has the property that all its elements are pairwise disjoint and disjoint from p
;r.first
with all the elements of r.second
gives q
(i.e., r
is the representation of a partition of q
).
|
related |
Partitions the grid q
with respect to grid p
if and only if such a partition is finite.
Let p
and q
be two grids. The function returns an object r
of type std::pair<PSET, Pointset_Powerset<Grid> >
such that
r.first
is the intersection of p
and q
;q
with respect to p
the Boolean finite_partition
is set to true and r.second
has the property that all its elements are pairwise disjoint and disjoint from p
and the set-theoretical union of r.first
with all the elements of r.second
gives q
(i.e., r
is the representation of a partition of q
).finite_partition
is set to false and the singleton set that contains q
is stored in r.second
r.
|
related |
Returns true
if and only if the union of the objects in ps
contains ph
.
|
related |
|
related |
|
related |
|
related |