1 /* Congruence class implementation: inline functions.
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_Congruence_inlines_hh
25 #define PPL_Congruence_inlines_hh 1
26 
27 #include <sstream>
28 
29 namespace Parma_Polyhedra_Library {
30 
31 inline
Congruence(Representation r)32 Congruence::Congruence(Representation r)
33   : expr(r) {
34   PPL_ASSERT(OK());
35 }
36 
37 inline
Congruence(const Congruence & cg)38 Congruence::Congruence(const Congruence& cg)
39   : expr(cg.expr), modulus_(cg.modulus_) {
40 }
41 
42 inline
Congruence(const Congruence & cg,Representation r)43 Congruence::Congruence(const Congruence& cg, Representation r)
44   : expr(cg.expr, r), modulus_(cg.modulus_) {
45 }
46 
47 inline
Congruence(const Congruence & cg,dimension_type new_space_dimension)48 Congruence::Congruence(const Congruence& cg,
49                        dimension_type new_space_dimension)
50   : expr(cg.expr, new_space_dimension), modulus_(cg.modulus_) {
51   PPL_ASSERT(OK());
52 }
53 
54 inline
Congruence(const Congruence & cg,dimension_type new_space_dimension,Representation r)55 Congruence::Congruence(const Congruence& cg,
56                        dimension_type new_space_dimension,
57                        Representation r)
58   : expr(cg.expr, new_space_dimension, r), modulus_(cg.modulus_) {
59   PPL_ASSERT(OK());
60 }
61 
62 inline Representation
representation() const63 Congruence::representation() const {
64   return expr.representation();
65 }
66 
67 inline void
set_representation(Representation r)68 Congruence::set_representation(Representation r) {
69   expr.set_representation(r);
70 }
71 
72 inline Congruence::expr_type
expression() const73 Congruence::expression() const {
74   return expr_type(expr);
75 }
76 
77 inline void
set_space_dimension(dimension_type n)78 Congruence::set_space_dimension(dimension_type n) {
79   expr.set_space_dimension(n);
80   PPL_ASSERT(OK());
81 }
82 
83 inline void
shift_space_dimensions(Variable v,dimension_type n)84 Congruence::shift_space_dimensions(Variable v, dimension_type n) {
85   expr.shift_space_dimensions(v, n);
86 }
87 
88 inline
~Congruence()89 Congruence::~Congruence() {
90 }
91 
92 inline
Congruence(Linear_Expression & le,Coefficient_traits::const_reference m,Recycle_Input)93 Congruence::Congruence(Linear_Expression& le,
94                        Coefficient_traits::const_reference m,
95                        Recycle_Input)
96   : modulus_(m) {
97   PPL_ASSERT(m >= 0);
98   swap(expr, le);
99 
100   PPL_ASSERT(OK());
101 }
102 
103 inline Congruence
create(const Linear_Expression & e,Coefficient_traits::const_reference n,Representation r)104 Congruence::create(const Linear_Expression& e,
105                    Coefficient_traits::const_reference n,
106                    Representation r) {
107   Linear_Expression diff(e, r);
108   diff -= n;
109   const Congruence cg(diff, 1, Recycle_Input());
110   return cg;
111 }
112 
113 inline Congruence
create(Coefficient_traits::const_reference n,const Linear_Expression & e,Representation r)114 Congruence::create(Coefficient_traits::const_reference n,
115                    const Linear_Expression& e,
116                    Representation r) {
117   Linear_Expression diff(e, r);
118   diff -= n;
119   const Congruence cg(diff, 1, Recycle_Input());
120   return cg;
121 }
122 
123 /*! \relates Parma_Polyhedra_Library::Congruence */
124 inline Congruence
operator %=(const Linear_Expression & e1,const Linear_Expression & e2)125 operator%=(const Linear_Expression& e1, const Linear_Expression& e2) {
126   return Congruence::create(e1, e2);
127 }
128 
129 /*! \relates Parma_Polyhedra_Library::Congruence */
130 inline Congruence
operator %=(const Linear_Expression & e,Coefficient_traits::const_reference n)131 operator%=(const Linear_Expression& e, Coefficient_traits::const_reference n) {
132   return Congruence::create(e, n);
133 }
134 
135 /*! \relates Parma_Polyhedra_Library::Congruence */
136 inline Congruence
operator /(const Congruence & cg,Coefficient_traits::const_reference k)137 operator/(const Congruence& cg, Coefficient_traits::const_reference k) {
138   Congruence ret = cg;
139   ret /= k;
140   return ret;
141 }
142 
143 inline const Congruence&
zero_dim_integrality()144 Congruence::zero_dim_integrality() {
145   return *zero_dim_integrality_p;
146 }
147 
148 inline const Congruence&
zero_dim_false()149 Congruence::zero_dim_false() {
150   return *zero_dim_false_p;
151 }
152 
153 inline Congruence&
operator =(const Congruence & y)154 Congruence::operator=(const Congruence& y) {
155   Congruence tmp = y;
156   swap(*this, tmp);
157   return *this;
158 }
159 
160 /*! \relates Congruence */
161 inline Congruence
operator /(const Constraint & c,Coefficient_traits::const_reference m)162 operator/(const Constraint& c, Coefficient_traits::const_reference m) {
163   Congruence ret(c);
164   ret /= m;
165   return ret;
166 }
167 
168 inline Congruence&
operator /=(Coefficient_traits::const_reference k)169 Congruence::operator/=(Coefficient_traits::const_reference k) {
170   if (k >= 0) {
171     modulus_ *= k;
172   }
173   else {
174     modulus_ *= -k;
175   }
176   return *this;
177 }
178 
179 /*! \relates Congruence */
180 inline bool
operator ==(const Congruence & x,const Congruence & y)181 operator==(const Congruence& x, const Congruence& y) {
182   if (x.space_dimension() != y.space_dimension()) {
183     return false;
184   }
185   Congruence x_temp(x);
186   Congruence y_temp(y);
187   x_temp.strong_normalize();
188   y_temp.strong_normalize();
189   return x_temp.expr.is_equal_to(y_temp.expr)
190     && x_temp.modulus() == y_temp.modulus();
191 }
192 
193 /*! \relates Congruence */
194 inline bool
operator !=(const Congruence & x,const Congruence & y)195 operator!=(const Congruence& x, const Congruence& y) {
196   return !(x == y);
197 }
198 
199 inline dimension_type
max_space_dimension()200 Congruence::max_space_dimension() {
201   return Linear_Expression::max_space_dimension();
202 }
203 
204 inline dimension_type
space_dimension() const205 Congruence::space_dimension() const {
206   return expr.space_dimension();
207 }
208 
209 inline Coefficient_traits::const_reference
coefficient(const Variable v) const210 Congruence::coefficient(const Variable v) const {
211   if (v.space_dimension() > space_dimension()) {
212     throw_dimension_incompatible("coefficient(v)", "v", v);
213   }
214   return expr.coefficient(v);
215 }
216 
217 inline void
permute_space_dimensions(const std::vector<Variable> & cycles)218 Congruence::permute_space_dimensions(const std::vector<Variable>& cycles) {
219   expr.permute_space_dimensions(cycles);
220 }
221 
222 inline Coefficient_traits::const_reference
inhomogeneous_term() const223 Congruence::inhomogeneous_term() const {
224   return expr.inhomogeneous_term();
225 }
226 
227 inline Coefficient_traits::const_reference
modulus() const228 Congruence::modulus() const {
229   return modulus_;
230 }
231 
232 inline void
set_modulus(Coefficient_traits::const_reference m)233 Congruence::set_modulus(Coefficient_traits::const_reference m) {
234   modulus_ = m;
235   PPL_ASSERT(OK());
236 }
237 
238 inline bool
is_proper_congruence() const239 Congruence::is_proper_congruence() const {
240   return modulus() > 0;
241 }
242 
243 inline bool
is_equality() const244 Congruence::is_equality() const {
245   return modulus() == 0;
246 }
247 
248 inline bool
is_equal_at_dimension(Variable v,const Congruence & cg) const249 Congruence::is_equal_at_dimension(Variable v,
250                                   const Congruence& cg) const {
251   return coefficient(v) * cg.modulus() == cg.coefficient(v) * modulus();
252 }
253 
254 inline memory_size_type
external_memory_in_bytes() const255 Congruence::external_memory_in_bytes() const {
256   return expr.external_memory_in_bytes()
257          + Parma_Polyhedra_Library::external_memory_in_bytes(modulus_);
258 }
259 
260 inline memory_size_type
total_memory_in_bytes() const261 Congruence::total_memory_in_bytes() const {
262   return external_memory_in_bytes() + sizeof(*this);
263 }
264 
265 inline void
m_swap(Congruence & y)266 Congruence::m_swap(Congruence& y) {
267   using std::swap;
268   swap(expr, y.expr);
269   swap(modulus_, y.modulus_);
270 }
271 
272 inline void
swap_space_dimensions(Variable v1,Variable v2)273 Congruence::swap_space_dimensions(Variable v1, Variable v2) {
274   expr.swap_space_dimensions(v1, v2);
275 }
276 
277 /*! \relates Congruence */
278 inline void
swap(Congruence & x,Congruence & y)279 swap(Congruence& x, Congruence& y) {
280   x.m_swap(y);
281 }
282 
283 } // namespace Parma_Polyhedra_Library
284 
285 #endif // !defined(PPL_Congruence_inlines_hh)
286