this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 *
6 * Copyright:
7 * Christian Schulte, 2009
8 *
9 * This file is part of Gecode, the generic constraint
10 * development environment:
11 * http://www.gecode.org
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining
14 * a copy of this software and associated documentation files (the
15 * "Software"), to deal in the Software without restriction, including
16 * without limitation the rights to use, copy, modify, merge, publish,
17 * distribute, sublicense, and/or sell copies of the Software, and to
18 * permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34#include <gecode/int/element.hh>
35
36namespace Gecode { namespace Int { namespace Element {
37
38 Actor*
39 Pair::copy(Space& home) {
40 return new (home) Pair(home,*this);
41 }
42
43 /// Value iterator for pair of iterators
44 template<class View>
45 class PairValues {
46 private:
47 /// View for x-values
48 View x;
49 /// Iterator for x-values
50 ViewValues<View> xv;
51 /// Iterator for y-values
52 ViewValues<View> yv;
53 /// Width
54 int w;
55 public:
56 /// \name Constructors and initialization
57 //@{
58 /// Initialize with views \a x and \a y and width \a w
59 PairValues(View x, View y, int w);
60 //@}
61
62 /// \name Iteration control
63 //@{
64 /// Test whether iterator is still at a value or done
65 bool operator ()(void) const;
66 /// Move iterator to next value (if possible)
67 void operator ++(void);
68 //@}
69
70 /// \name Value access
71 //@{
72 /// Return current value
73 int val(void) const;
74 //@}
75 };
76
77 template<class View>
78 forceinline
79 PairValues<View>::PairValues(View x0, View y0, int w0)
80 : x(x0), xv(x0), yv(y0), w(w0) {}
81 template<class View>
82 forceinline void
83 PairValues<View>::operator ++(void) {
84 ++xv;
85 if (!xv()) {
86 xv.init(x); ++yv;
87 }
88 }
89 template<class View>
90 forceinline bool
91 PairValues<View>::operator ()(void) const {
92 return yv();
93 }
94 template<class View>
95 forceinline int
96 PairValues<View>::val(void) const {
97 return xv.val() + w*yv.val();
98 }
99
100
101 ExecStatus
102 Pair::propagate(Space& home, const ModEventDelta&) {
103 Region r;
104
105 if (x0.assigned()) {
106 // Bitset for supported div and mod values
107 Support::BitSet<Region> d(r,static_cast<unsigned int>((x2.max() / w)+1));
108 for (ViewValues<IntView> i(x2); i(); ++i) {
109 d.set(static_cast<unsigned int>(i.val() / w));
110 }
111 Iter::Values::BitSet<Support::BitSet<Region> > id(d,x1.min(),x1.max());
112 GECODE_ME_CHECK(x1.inter_v(home,id,false));
113 } else {
114 // Bitset for supported div and mod values
115 Support::BitSet<Region>
116 d(r,static_cast<unsigned int>((x2.max() / w)+1)),
117 m(r,static_cast<unsigned int>(w));
118 for (ViewValues<IntView> i(x2); i(); ++i) {
119 d.set(static_cast<unsigned int>(i.val() / w));
120 m.set(static_cast<unsigned int>(i.val() % w));
121 }
122 Iter::Values::BitSet<Support::BitSet<Region> > im(m,x0.min(),x0.max());
123 GECODE_ME_CHECK(x0.inter_v(home,im,false));
124 Iter::Values::BitSet<Support::BitSet<Region> > id(d,x1.min(),x1.max());
125 GECODE_ME_CHECK(x1.inter_v(home,id,false));
126 }
127
128 if (x0.assigned() && x1.assigned()) {
129 GECODE_ME_CHECK(x2.eq(home,x0.val()+w*x1.val()));
130 return home.ES_SUBSUMED(*this);
131 } else if (x1.assigned()) {
132 OffsetView x0x1w(x0,x1.val()*w);
133 GECODE_REWRITE(*this,(Rel::EqDom<OffsetView,IntView>
134 ::post(home(*this),x0x1w,x2)));
135 }
136
137 PairValues<IntView> xy(x0,x1,w);
138 GECODE_ME_CHECK(x2.inter_v(home,xy,false));
139
140 if (x2.assigned()) {
141 GECODE_ME_CHECK(x0.eq(home,x2.val() % w));
142 GECODE_ME_CHECK(x1.eq(home,static_cast<int>(x2.val() / w)));
143 return home.ES_SUBSUMED(*this);
144 }
145
146 return ES_NOFIX;
147 }
148
149 Actor*
150 PairWithOffsets::copy(Space& home) {
151 return new (home) PairWithOffsets(home,*this);
152 }
153
154 ExecStatus
155 PairWithOffsets::propagate(Space& home, const ModEventDelta&) {
156 Region r;
157
158 if (x0.assigned()) {
159 // Bitset for supported div and mod values
160 Support::BitSet<Region> d(r,static_cast<unsigned int>((x2.max() / w)+1));
161 for (ViewValues<OffsetView> i(x2); i(); ++i) {
162 d.set(static_cast<unsigned int>(i.val() / w));
163 }
164 Iter::Values::BitSet<Support::BitSet<Region> > id(d,x1.min(),x1.max());
165 GECODE_ME_CHECK(x1.inter_v(home,id,false));
166 } else {
167 // Bitset for supported div and mod values
168 Support::BitSet<Region>
169 d(r,static_cast<unsigned int>((x2.max() / w)+1)),
170 m(r,static_cast<unsigned int>(w));
171 for (ViewValues<OffsetView> i(x2); i(); ++i) {
172 d.set(static_cast<unsigned int>(i.val() / w));
173 m.set(static_cast<unsigned int>(i.val() % w));
174 }
175 Iter::Values::BitSet<Support::BitSet<Region> > im(m,x0.min(),x0.max());
176 GECODE_ME_CHECK(x0.inter_v(home,im,false));
177 Iter::Values::BitSet<Support::BitSet<Region> > id(d,x1.min(),x1.max());
178 GECODE_ME_CHECK(x1.inter_v(home,id,false));
179 }
180
181 if (x0.assigned() && x1.assigned()) {
182 GECODE_ME_CHECK(x2.eq(home,x0.val()+w*x1.val()));
183 return home.ES_SUBSUMED(*this);
184 } else if (x1.assigned()) {
185 OffsetView x0x1w(x0.base(),x0.offset()+x1.val()*w);
186 GECODE_REWRITE(*this,(Rel::EqDom<OffsetView,OffsetView>
187 ::post(home(*this),x0x1w,x2)));
188 }
189
190 PairValues<OffsetView> xy(x0,x1,w);
191 GECODE_ME_CHECK(x2.inter_v(home,xy,false));
192
193 if (x2.assigned()) {
194 GECODE_ME_CHECK(x0.eq(home,x2.val() % w));
195 GECODE_ME_CHECK(x1.eq(home,static_cast<int>(x2.val() / w)));
196 return home.ES_SUBSUMED(*this);
197 }
198
199 return ES_NOFIX;
200 }
201
202}}}
203
204// STATISTICS: int-prop
205