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