1 /* Expression_Adapter class declaration.
2    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3    Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef PPL_Expression_Adapter_defs_hh
25 #define PPL_Expression_Adapter_defs_hh 1
26 
27 #include "Expression_Adapter_types.hh"
28 #include "Variable_types.hh"
29 #include "Variables_Set_types.hh"
30 #include "Dense_Row_defs.hh"
31 #include "Sparse_Row_defs.hh"
32 
33 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
34 //! Adapters' base type (for template meta-programming).
35 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
36 class Parma_Polyhedra_Library::Expression_Adapter_Base {
37 };
38 
39 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
40 //! An adapter for Linear_Expression objects.
41 /*!
42   The adapters are meant to provide read-only, customized access to the
43   Linear_Expression members in Constraint, Generator, Congruence and
44   Grid_Generator objects. They typically implement the user-level view
45   of these expressions.
46 
47   \note
48   A few methods implement low-level access routines and will take
49   bare indexes as arguments (rather than Variable objects):
50   when such a bare index \c i is zero, the inhomogeneous term is meant;
51   when the bare index \c i is greater than zero, the coefficient of the
52   variable having id <CODE>i - 1</CODE> is meant.
53 */
54 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
55 template <typename T>
56 class Parma_Polyhedra_Library::Expression_Adapter
57   : public Expression_Adapter_Base {
58 public:
59   //! The type of this object.
60   typedef Expression_Adapter<T> const_reference;
61   //! The type obtained by one-level unwrapping.
62   typedef typename T::const_reference inner_type;
63   //! The raw, completely unwrapped type.
64   typedef typename T::raw_type raw_type;
65 
66   //! Returns an adapter after one-level unwrapping.
67   inner_type inner() const;
68 
69   //! The type of const iterators on coefficients.
70   typedef typename raw_type::const_iterator const_iterator;
71 
72   //! Returns the current representation of \p *this.
73   Representation representation() const;
74 
75   //! Iterator pointing to the first nonzero variable coefficient.
76   const_iterator begin() const;
77 
78   //! Iterator pointing after the last nonzero variable coefficient.
79   const_iterator end() const;
80 
81   //! Iterator pointing to the first nonzero variable coefficient
82   //! of a variable bigger than or equal to \p v.
83   const_iterator lower_bound(Variable v) const;
84 
85   //! Returns the dimension of the vector space enclosing \p *this.
86   dimension_type space_dimension() const;
87 
88   //! Returns the coefficient of \p v in \p *this.
89   Coefficient_traits::const_reference coefficient(Variable v) const;
90 
91   //! Returns the inhomogeneous term of \p *this.
92   Coefficient_traits::const_reference inhomogeneous_term() const;
93 
94   //! Returns <CODE>true</CODE> if and only if \p *this is zero.
95   bool is_zero() const;
96 
97   /*! \brief
98     Returns <CODE>true</CODE> if and only if all the homogeneous
99     terms of \p *this are zero.
100   */
101   bool all_homogeneous_terms_are_zero() const;
102 
103   /*! \brief Returns \p true if \p *this is equal to \p y.
104 
105     Note that <CODE>(*this == y)</CODE> has a completely different meaning.
106   */
107   template <typename Expression>
108   bool is_equal_to(const Expression& y) const;
109 
110   /*! \brief
111     Returns <CODE>true</CODE> if the coefficient of each variable in
112     \p vars is zero.
113   */
114   bool all_zeroes(const Variables_Set& vars) const;
115 
116   //! Returns the \p i -th coefficient.
117   Coefficient_traits::const_reference get(dimension_type i) const;
118 
119   //! Returns the coefficient of variable \p v.
120   Coefficient_traits::const_reference get(Variable v) const;
121 
122   /*! \brief
123     Returns <CODE>true</CODE> if (*this)[i] is zero,
124     for each i in [start, end).
125   */
126   bool all_zeroes(dimension_type start, dimension_type end) const;
127 
128   //! Returns the number of zero coefficient in [start, end).
129   dimension_type num_zeroes(dimension_type start, dimension_type end) const;
130 
131   /*! \brief
132     Returns the gcd of the nonzero coefficients in [start,end).
133     Returns zero if all the coefficients in the range are zero.
134   */
135   Coefficient gcd(dimension_type start, dimension_type end) const;
136 
137   //! Returns the index of the last nonzero element, or zero if there are no
138   //! nonzero elements.
139   dimension_type last_nonzero() const;
140 
141   //! Returns the index of the last nonzero element in [first,last),
142   //! or \p last if there are no nonzero elements.
143   dimension_type last_nonzero(dimension_type first, dimension_type last) const;
144 
145   //! Returns the index of the first nonzero element, or \p last if there
146   //! are no nonzero elements, considering only elements in [first,last).
147   dimension_type first_nonzero(dimension_type first, dimension_type last) const;
148 
149   /*! \brief
150     Returns <CODE>true</CODE> if all coefficients in [start,end),
151     except those corresponding to variables in \p vars, are zero.
152   */
153   bool all_zeroes_except(const Variables_Set& vars,
154                          dimension_type start, dimension_type end) const;
155 
156   //! Removes from set \p x all the indexes of nonzero elements in \p *this.
157   void has_a_free_dimension_helper(std::set<dimension_type>& x) const;
158 
159   //! Returns \c true if <CODE>(*this)[i]</CODE> is equal to <CODE>y[i]</CODE>,
160   //! for each i in [start,end).
161   template <typename Expression>
162   bool is_equal_to(const Expression& y,
163                    dimension_type start, dimension_type end) const;
164 
165   //! Returns \c true if <CODE>(*this)[i]*c1</CODE> is equal to
166   //! <CODE>y[i]*c2</CODE>, for each i in [start,end).
167   template <typename Expression>
168   bool is_equal_to(const Expression& y,
169                    Coefficient_traits::const_reference c1,
170                    Coefficient_traits::const_reference c2,
171                    dimension_type start, dimension_type end) const;
172 
173   //! Sets \p r to a copy of the row as adapted by \p *this.
174   void get_row(Dense_Row& r) const;
175 
176   //! Sets \p r to a copy of the row as adapted by \p *this.
177   void get_row(Sparse_Row& r) const;
178 
179   //! Returns \c true if there is a variable in [first,last) whose coefficient
180   //! is nonzero in both \p *this and \p y.
181   template <typename Expression>
182   bool have_a_common_variable(const Expression& y,
183                               Variable first, Variable last) const;
184 
185 protected:
186   //! Constructor.
187   explicit Expression_Adapter(const raw_type& expr);
188   //! The raw, completely unwrapped object subject to adaptation.
189   const raw_type& raw_;
190 };
191 
192 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
193 //! A transparent adapter for Linear_Expression objects.
194 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
195 template <typename T>
196 class Parma_Polyhedra_Library::Expression_Adapter_Transparent
197   : public Expression_Adapter<T> {
198   typedef Expression_Adapter<T> base_type;
199 public:
200   //! The type of this object.
201   typedef Expression_Adapter_Transparent<T> const_reference;
202   //! The type obtained by one-level unwrapping.
203   typedef typename base_type::inner_type inner_type;
204   //! The raw, completely unwrapped type.
205   typedef typename base_type::raw_type raw_type;
206 
207   //! The type of const iterators on coefficients.
208   typedef typename base_type::const_iterator const_iterator;
209 
210   //! Constructor.
211   explicit Expression_Adapter_Transparent(const raw_type& expr);
212 };
213 
214 #include "Expression_Adapter_inlines.hh"
215 
216 #endif // !defined(PPL_Expression_Adapter_defs_hh)
217