Generated on Thu Jan 16 2025 00:00:00 for Gecode by doxygen 1.14.0
mult.hpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 * Vincent Barichard <Vincent.Barichard@univ-angers.fr>
6 *
7 * Copyright:
8 * Christian Schulte, 2004
9 * Vincent Barichard, 2012
10 *
11 * This file is part of Gecode, the generic constraint
12 * development environment:
13 * http://www.gecode.org
14 *
15 * Permission is hereby granted, free of charge, to any person obtaining
16 * a copy of this software and associated documentation files (the
17 * "Software"), to deal in the Software without restriction, including
18 * without limitation the rights to use, copy, modify, merge, publish,
19 * distribute, sublicense, and/or sell copies of the Software, and to
20 * permit persons to whom the Software is furnished to do so, subject to
21 * the following conditions:
22 *
23 * The above copyright notice and this permission notice shall be
24 * included in all copies or substantial portions of the Software.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 *
34 */
35
36namespace Gecode { namespace Float { namespace Arithmetic {
37
39 template<class View>
40 forceinline bool
41 pos(const View& x) {
42 return x.min() >= 0.0;
43 }
44
45 template<class View>
46 forceinline bool
47 neg(const View& x) {
48 return x.max() <= 0.0;
49 }
50
51 template<class View>
52 forceinline bool
53 any(const View& x) {
54 return (x.min() <= 0.0) && (x.max() >= 0.0);
55 }
56
57 /*
58 * Propagator for x * y = x
59 *
60 */
61
62 template<class View>
66
67 template<class View>
70 switch (rtest_eq(x0,0.0)) {
71 case RT_FALSE:
72 GECODE_ME_CHECK(x1.eq(home,1.0));
73 break;
74 case RT_TRUE:
75 break;
76 case RT_MAYBE:
77 switch (rtest_eq(x1,1.0)) {
78 case RT_FALSE:
79 GECODE_ME_CHECK(x0.eq(home,0.0));
80 break;
81 case RT_TRUE:
82 break;
83 case RT_MAYBE:
84 (void) new (home) MultZeroOne<View>(home,x0,x1);
85 break;
86 default: GECODE_NEVER;
87 }
88 break;
89 default: GECODE_NEVER;
90 }
91 return ES_OK;
92 }
93
94 template<class View>
98
99 template<class View>
100 Actor*
102 return new (home) MultZeroOne<View>(home,*this);
103 }
104
105 template<class View>
108 switch (rtest_eq(x0,0.0)) {
109 case RT_FALSE:
110 GECODE_ME_CHECK(x1.eq(home,1.0));
111 break;
112 case RT_TRUE:
113 break;
114 case RT_MAYBE:
115 switch (rtest_eq(x1,1.0)) {
116 case RT_FALSE:
117 GECODE_ME_CHECK(x0.eq(home,0.0));
118 break;
119 case RT_TRUE:
120 break;
121 case RT_MAYBE:
122 return ES_FIX;
123 default: GECODE_NEVER;
124 }
125 break;
126 default: GECODE_NEVER;
127 }
128 return home.ES_SUBSUMED(*this);
129 }
130
131
132 /*
133 * Positive bounds consistent multiplication
134 *
135 */
136 template<class VA, class VB, class VC>
141
142 template<class VA, class VB, class VC>
147
148 template<class VA, class VB, class VC>
149 Actor*
151 return new (home) MultPlus<VA,VB,VC>(home,*this);
152 }
153
154 template<class VA, class VB, class VC>
157 if (x1.min() != 0.0)
158 GECODE_ME_CHECK(x0.eq(home,x2.val() / x1.val()));
159 if (x0.min() != 0.0)
160 GECODE_ME_CHECK(x1.eq(home,x2.val() / x0.val()));
161 GECODE_ME_CHECK(x2.eq(home,x0.val() * x1.val()));
162 if (x0.assigned() && x1.assigned() && x2.assigned())
163 return home.ES_SUBSUMED(*this);
164 return ES_NOFIX;
165 }
166
167 template<class VA, class VB, class VC>
170 GECODE_ME_CHECK(x0.gq(home,0.0));
171 GECODE_ME_CHECK(x1.gq(home,0.0));
172 Rounding r;
173 GECODE_ME_CHECK(x2.gq(home,r.mul_down(x0.min(),x1.min())));
174 (void) new (home) MultPlus<VA,VB,VC>(home,x0,x1,x2);
175 return ES_OK;
176 }
177
178
179 /*
180 * Bounds consistent multiplication
181 *
182 */
183 template<class View>
187
188 template<class View>
192
193 template<class View>
194 Actor*
196 return new (home) Mult<View>(home,*this);
197 }
198
199 template<class View>
202 Rounding r;
203 if (pos(x0)) {
204 if (pos(x1) || pos(x2)) goto rewrite_ppp;
205 if (neg(x1) || neg(x2)) goto rewrite_pnn;
206 goto prop_pxx;
207 }
208 if (neg(x0)) {
209 if (neg(x1) || pos(x2)) goto rewrite_nnp;
210 if (pos(x1) || neg(x2)) goto rewrite_npn;
211 goto prop_nxx;
212 }
213 if (pos(x1)) {
214 if (pos(x2)) goto rewrite_ppp;
215 if (neg(x2)) goto rewrite_npn;
216 goto prop_xpx;
217 }
218 if (neg(x1)) {
219 if (pos(x2)) goto rewrite_nnp;
220 if (neg(x2)) goto rewrite_pnn;
221 goto prop_xnx;
222 }
223
224 assert(any(x0) && any(x1));
225 GECODE_ME_CHECK(x2.lq(home,std::max(r.mul_up(x0.max(),x1.max()),
226 r.mul_up(x0.min(),x1.min()))));
227 GECODE_ME_CHECK(x2.gq(home,std::min(r.mul_down(x0.min(),x1.max()),
228 r.mul_down(x0.max(),x1.min()))));
229
230 if (pos(x2)) {
231 if (r.div_up(x2.min(),x1.min()) < x0.min())
232 GECODE_ME_CHECK(x0.gq(home,0));
233 if (r.div_up(x2.min(),x0.min()) < x1.min())
234 GECODE_ME_CHECK(x1.gq(home,0));
235 }
236 if (neg(x2)) {
237 if (r.div_up(x2.max(),x1.max()) < x0.min())
238 GECODE_ME_CHECK(x0.gq(home,0));
239 if (r.div_up(x2.max(),x0.max()) < x1.min())
240 GECODE_ME_CHECK(x1.gq(home,0));
241 }
242
243 if (x0.assigned()) {
244 assert((x0.val() == 0.0) && (x2.val() == 0.0));
245 return home.ES_SUBSUMED(*this);
246 }
247
248 if (x1.assigned()) {
249 assert((x1.val() == 0.0) && (x2.val() == 0.0));
250 return home.ES_SUBSUMED(*this);
251 }
252
253 return ES_NOFIX;
254
255 prop_xpx:
256 std::swap(x0,x1);
257 prop_pxx:
258 assert(pos(x0) && any(x1) && any(x2));
259
260 GECODE_ME_CHECK(x2.lq(home,r.mul_up(x0.max(),x1.max())));
261 GECODE_ME_CHECK(x2.gq(home,r.mul_down(x0.max(),x1.min())));
262
263 if (pos(x2)) goto rewrite_ppp;
264 if (neg(x2)) goto rewrite_pnn;
265
266 GECODE_ME_CHECK(x1.lq(home,r.div_up(x2.max(),x0.min())));
267 GECODE_ME_CHECK(x1.gq(home,r.div_down(x2.min(),x0.min())));
268
269 if (x0.assigned() && x1.assigned()) {
270 GECODE_ME_CHECK(x2.eq(home,x0.val()*x1.val()));
271 return home.ES_SUBSUMED(*this);
272 }
273
274 return ES_NOFIX;
275
276 prop_xnx:
277 std::swap(x0,x1);
278 prop_nxx:
279 assert(neg(x0) && any(x1) && any(x2));
280
281 GECODE_ME_CHECK(x2.lq(home,r.mul_up(x0.min(),x1.min())));
282 GECODE_ME_CHECK(x2.gq(home,r.mul_down(x0.min(),x1.max())));
283
284 if (pos(x2)) goto rewrite_nnp;
285 if (neg(x2)) goto rewrite_npn;
286
287 if (x0.max() != 0.0) {
288 GECODE_ME_CHECK(x1.lq(home,r.div_up(x2.min(),x0.max())));
289 GECODE_ME_CHECK(x1.gq(home,r.div_down(x2.max(),x0.max())));
290 }
291
292 if (x0.assigned() && x1.assigned()) {
293 GECODE_ME_CHECK(x2.eq(home,x0.val()*x1.val()));
294 return home.ES_SUBSUMED(*this);
295 }
296
297 return ES_NOFIX;
298
299 rewrite_ppp:
301 ::post(home(*this),x0,x1,x2)));
302 rewrite_nnp:
304 ::post(home(*this),MinusView(x0),MinusView(x1),x2)));
305 rewrite_pnn:
306 std::swap(x0,x1);
307 rewrite_npn:
309 ::post(home(*this),MinusView(x0),x1,MinusView(x2))));
310 }
311
312 template<class View>
315 if (x0 == x1)
316 return Sqr<View>::post(home,x0,x2);
317 if (x0 == x2)
318 return MultZeroOne<View>::post(home,x0,x1);
319 if (x1 == x2)
320 return MultZeroOne<View>::post(home,x1,x0);
321 if (pos(x0)) {
322 if (pos(x1) || pos(x2)) goto post_ppp;
323 if (neg(x1) || neg(x2)) goto post_pnn;
324 } else if (neg(x0)) {
325 if (neg(x1) || pos(x2)) goto post_nnp;
326 if (pos(x1) || neg(x2)) goto post_npn;
327 } else if (pos(x1)) {
328 if (pos(x2)) goto post_ppp;
329 if (neg(x2)) goto post_npn;
330 } else if (neg(x1)) {
331 if (pos(x2)) goto post_nnp;
332 if (neg(x2)) goto post_pnn;
333 }
334 {
335 GECODE_ME_CHECK(x2.eq(home,x0.val()*x1.val()));
336 (void) new (home) Mult<View>(home,x0,x1,x2);
337 }
338 return ES_OK;
339
340 post_ppp:
342 post_nnp:
345 post_pnn:
346 std::swap(x0,x1);
347 post_npn:
350 }
351
352
353}}}
354
355// STATISTICS: float-prop
356
Base-class for both propagators and branchers.
Definition core.hpp:628
BinaryPropagator(Space &home, BinaryPropagator &p)
Bounds consistent positive multiplication propagator.
static ExecStatus post(Home home, VA x0, VB x1, VC x2)
Post propagator .
Definition mult.hpp:169
virtual Actor * copy(Space &home)
Copy propagator during cloning.
Definition mult.hpp:150
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition mult.hpp:156
MultPlus(Home home, VA x0, VB x1, VC x2)
Constructor for posting.
Definition mult.hpp:138
static ExecStatus post(Home home, View x0, View x1)
Post propagator .
Definition mult.hpp:69
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition mult.hpp:107
virtual Actor * copy(Space &home)
Copy propagator during cloning.
Definition mult.hpp:101
MultZeroOne(Space &home, MultZeroOne< View > &p)
Constructor for cloning p.
Definition mult.hpp:96
static ExecStatus post(Home home, View x0, View x1, View x2)
Post propagator .
Definition mult.hpp:314
virtual Actor * copy(Space &home)
Copy propagator during cloning.
Definition mult.hpp:195
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)
Perform propagation.
Definition mult.hpp:201
Mult(Space &home, Mult< View > &p)
Constructor for cloning p.
Definition mult.hpp:190
static ExecStatus post(Home home, View x0, View x1)
Post propagator for .
Definition sqr-sqrt.hpp:105
Minus float view.
Definition view.hpp:154
Floating point rounding policy.
Definition float.hh:154
Home class for posting propagators
Definition core.hpp:856
friend class Space
Definition core.hpp:1068
TernaryPropagator(Space &home, TernaryPropagator &p)
ExecStatus ES_SUBSUMED(Propagator &p)
Propagator p is subsumed
Definition core.hpp:3570
int ModEventDelta
Modification event deltas.
Definition core.hpp:89
#define GECODE_ME_CHECK(me)
Check whether modification event me is failed, and forward failure.
Definition macros.hpp:52
#define GECODE_REWRITE(prop, post)
Rewrite propagator by executing post function.
Definition macros.hpp:116
Arithmetic propagators
bool any(const View &x)
Test whether x is neither positive nor negative.
Definition mult.hpp:53
bool pos(const View &x)
Test whether x is postive.
Definition mult.hpp:41
bool neg(const View &x)
Test whether x is negative.
Definition mult.hpp:47
Floating point numbers.
@ RT_TRUE
Relation does hold.
Definition view.hpp:536
@ RT_FALSE
Relation does not hold.
Definition view.hpp:534
@ RT_MAYBE
Relation may hold or not.
Definition view.hpp:535
RelTest rtest_eq(View x, View y)
Test whether views x and y are equal.
Definition rel-test.hpp:40
const Gecode::PropCond PC_FLOAT_BND
Propagate when minimum or maximum of a view changes.
Definition var-type.hpp:292
Gecode toplevel namespace
Post propagator for SetVar SetOpType SetVar SetRelType r
Definition set.hh:773
ExecStatus
Definition core.hpp:472
@ ES_OK
Execution is okay.
Definition core.hpp:476
@ ES_FIX
Propagation has computed fixpoint.
Definition core.hpp:477
@ ES_NOFIX
Propagation has not computed fixpoint.
Definition core.hpp:475
Post propagator for SetVar x
Definition set.hh:773
#define forceinline
Definition config.hpp:194
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56