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, 2012
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
34namespace Gecode {
35
36 /**
37 * \defgroup TaskBranchViewVal Generic brancher based on view and value selection
38 *
39 * Implements view-based brancher for an array of views and value.
40 * \ingroup TaskActor
41 */
42
43 //@{
44 /// %Choice storing position and value
45 template<class Val>
46 class GECODE_VTABLE_EXPORT PosValChoice : public PosChoice {
47 private:
48 /// Value to assign to
49 const Val _val;
50 public:
51 /// Initialize choice for brancher \a b, number of alternatives \a a, position \a p, and value \a n
52 PosValChoice(const Brancher& b, unsigned int a, const Pos& p, const Val& n);
53 const Val& val(void) const;
54 /// Archive into \a e
55 virtual void archive(Archive& e) const;
56 };
57
58
59 /// View-value no-good literal
60 template<class View, class Val, PropCond pc>
61 class ViewValNGL : public NGL {
62 protected:
63 /// The stored view
64 View x;
65 /// The stored value
66 Val n;
67 public:
68 /// Initialize for propagator \a p with view \a x and value \a n
69 ViewValNGL(Space& home, View x, Val n);
70 /// Constructor for cloning \a ngl
71 ViewValNGL(Space& home, ViewValNGL& ngl);
72 /// Create subscription for no-good literal
73 virtual void subscribe(Space& home, Propagator& p);
74 /// Cancel subscription for no-good literal
75 virtual void cancel(Space& home, Propagator& p);
76 /// Schedule propagator \a p
77 virtual void reschedule(Space& home, Propagator& p);
78 /// Dispose
79 virtual size_t dispose(Space& home);
80 };
81
82 /**
83 * \brief Generic brancher by view and value selection
84 *
85 * Implements view-based branching for an array of views (of type
86 * \a View) and value (of type \a Val).
87 *
88 */
89 template<class View, int n, class Val, unsigned int a,
90 class Filter, class Print>
91 class ViewValBrancher : public ViewBrancher<View,Filter,n> {
92 protected:
93 using ViewBrancher<View,Filter,n>::vs;
94 using ViewBrancher<View,Filter,n>::x;
95 using ViewBrancher<View,Filter,n>::f;
96 /// The corresponding variable
97 typedef typename View::VarType Var;
98 /// Value selection and commit object
99 ValSelCommitBase<View,Val>* vsc;
100 /// Print function
101 Print p;
102 /// Constructor for cloning \a b
103 ViewValBrancher(Space& home, ViewValBrancher& b);
104 /// Constructor for creation
105 ViewValBrancher(Home home,
106 ViewArray<View>& x,
107 ViewSel<View>* vs[n],
108 ValSelCommitBase<View,Val>* vsc,
109 BranchFilter<Var> bf,
110 VarValPrint<Var,Val> vvp);
111 public:
112 /// Return choice
113 virtual const Choice* choice(Space& home);
114 /// Return choice
115 virtual const Choice* choice(const Space& home, Archive& e);
116 /// Perform commit for choice \a c and alternative \a b
117 virtual ExecStatus commit(Space& home, const Choice& c, unsigned int b);
118 /// Create no-good literal for choice \a c and alternative \a b
119 virtual NGL* ngl(Space& home, const Choice& c, unsigned int b) const;
120 /**
121 * \brief Print branch for choice \a c and alternative \a b
122 *
123 * Prints an explanation of the alternative \a b of choice \a c
124 * on the stream \a o.
125 *
126 */
127 virtual void print(const Space& home, const Choice& c, unsigned int b,
128 std::ostream& o) const;
129 /// Perform cloning
130 virtual Actor* copy(Space& home);
131 /// Delete brancher and return its size
132 virtual size_t dispose(Space& home);
133 /// Brancher post function
134 static void post(Home home,
135 ViewArray<View>& x,
136 ViewSel<View>* vs[n],
137 ValSelCommitBase<View,Val>* vsc,
138 BranchFilter<Var> bf,
139 VarValPrint<Var,Val> vvp);
140 };
141
142 /// Post view value brancher
143 template<class View, int n, class Val, unsigned int a>
144 void
145 postviewvalbrancher(Home home,
146 ViewArray<View>& x,
147 ViewSel<View>* vs[n],
148 ValSelCommitBase<View,Val>* vsc,
149 BranchFilter<typename View::VarType> bf,
150 VarValPrint<typename View::VarType,Val> vvp);
151 //@}
152
153 /*
154 * %Choice with position and value
155 *
156 */
157 template<class Val>
158 forceinline
159 PosValChoice<Val>::PosValChoice(const Brancher& b, unsigned int a,
160 const Pos& p, const Val& n)
161 : PosChoice(b,a,p), _val(n) {}
162
163 template<class Val>
164 forceinline const Val&
165 PosValChoice<Val>::val(void) const {
166 return _val;
167 }
168
169 template<class Val>
170 forceinline void
171 PosValChoice<Val>::archive(Archive& e) const {
172 PosChoice::archive(e);
173 e << _val;
174 }
175
176
177 /*
178 * View-value no-good literal
179 *
180 */
181 template<class View, class Val, PropCond pc>
182 forceinline
183 ViewValNGL<View,Val,pc>::ViewValNGL(Space& home, View x0, Val n0)
184 : NGL(home), x(x0), n(n0) {}
185
186 template<class View, class Val, PropCond pc>
187 forceinline
188 ViewValNGL<View,Val,pc>::ViewValNGL(Space& home, ViewValNGL& ngl)
189 : NGL(home,ngl), n(ngl.n) {
190 x.update(home,ngl.x);
191 }
192
193 template<class View, class Val, PropCond pc>
194 void
195 ViewValNGL<View,Val,pc>::subscribe(Space& home, Propagator& p) {
196 x.subscribe(home,p,pc);
197 }
198
199 template<class View, class Val, PropCond pc>
200 void
201 ViewValNGL<View,Val,pc>::cancel(Space& home, Propagator& p) {
202 x.cancel(home,p,pc);
203 }
204
205 template<class View, class Val, PropCond pc>
206 void
207 ViewValNGL<View,Val,pc>::reschedule(Space& home, Propagator& p) {
208 x.reschedule(home,p,pc);
209 }
210
211 template<class View, class Val, PropCond pc>
212 size_t
213 ViewValNGL<View,Val,pc>::dispose(Space& home) {
214 (void) NGL::dispose(home);
215 return sizeof(*this);
216 }
217
218
219
220 /*
221 * Generic brancher based on variable/value selection
222 *
223 */
224 template<class View, int n, class Val, unsigned int a,
225 class Filter, class Print>
226 forceinline
227 ViewValBrancher<View,n,Val,a,Filter,Print>::
228 ViewValBrancher(Home home,
229 ViewArray<View>& x,
230 ViewSel<View>* vs[n],
231 ValSelCommitBase<View,Val>* vsc0,
232 BranchFilter<Var> bf,
233 VarValPrint<Var,Val> vvp)
234 : ViewBrancher<View,Filter,n>(home,x,vs,bf), vsc(vsc0), p(vvp) {
235 if (vsc->notice() || f.notice() || p.notice())
236 home.notice(*this,AP_DISPOSE,true);
237 }
238
239 template<class View, int n, class Val, unsigned int a,
240 class Filter, class Print>
241 forceinline void
242 ViewValBrancher<View,n,Val,a,Filter,Print>::
243 post(Home home, ViewArray<View>& x,
244 ViewSel<View>* vs[n], ValSelCommitBase<View,Val>* vsc,
245 BranchFilter<Var> bf,
246 VarValPrint<Var,Val> vvp) {
247 (void) new (home) ViewValBrancher<View,n,Val,a,Filter,Print>
248 (home,x,vs,vsc,bf,vvp);
249 }
250
251 template<class View, int n, class Val, unsigned int a,
252 class Filter, class Print>
253 forceinline
254 ViewValBrancher<View,n,Val,a,Filter,Print>::
255 ViewValBrancher(Space& home,
256 ViewValBrancher<View,n,Val,a,Filter,Print>& b)
257 : ViewBrancher<View,Filter,n>(home,b),
258 vsc(b.vsc->copy(home)), p(b.p) {}
259
260 template<class View, int n, class Val, unsigned int a,
261 class Filter, class Print>
262 Actor*
263 ViewValBrancher<View,n,Val,a,Filter,Print>::copy(Space& home) {
264 return new (home) ViewValBrancher<View,n,Val,a,Filter,Print>
265 (home,*this);
266 }
267
268 template<class View, int n, class Val, unsigned int a,
269 class Filter, class Print>
270 const Choice*
271 ViewValBrancher<View,n,Val,a,Filter,Print>::choice(Space& home) {
272 Pos p = ViewBrancher<View,Filter,n>::pos(home);
273 View v = ViewBrancher<View,Filter,n>::view(p);
274 return new PosValChoice<Val>(*this,a,p,vsc->val(home,v,p.pos));
275 }
276
277 template<class View, int n, class Val, unsigned int a,
278 class Filter, class Print>
279 const Choice*
280 ViewValBrancher<View,n,Val,a,Filter,Print>::choice(const Space& home,
281 Archive& e) {
282 (void) home;
283 int p; e >> p;
284 Val v; e >> v;
285 return new PosValChoice<Val>(*this,a,p,v);
286 }
287
288 template<class View, int n, class Val, unsigned int a,
289 class Filter, class Print>
290 ExecStatus
291 ViewValBrancher<View,n,Val,a,Filter,Print>
292 ::commit(Space& home, const Choice& c, unsigned int b) {
293 const PosValChoice<Val>& pvc
294 = static_cast<const PosValChoice<Val>&>(c);
295 return me_failed(vsc->commit(home,b,
296 ViewBrancher<View,Filter,n>::view(pvc.pos()),
297 pvc.pos().pos,
298 pvc.val()))
299 ? ES_FAILED : ES_OK;
300 }
301
302 template<class View, int n, class Val, unsigned int a,
303 class Filter, class Print>
304 NGL*
305 ViewValBrancher<View,n,Val,a,Filter,Print>
306 ::ngl(Space& home, const Choice& c, unsigned int b) const {
307 const PosValChoice<Val>& pvc
308 = static_cast<const PosValChoice<Val>&>(c);
309 return vsc->ngl(home,b,
310 ViewBrancher<View,Filter,n>::view(pvc.pos()),pvc.val());
311 }
312
313 template<class View, int n, class Val, unsigned int a,
314 class Filter, class Print>
315 void
316 ViewValBrancher<View,n,Val,a,Filter,Print>
317 ::print(const Space& home, const Choice& c, unsigned int b,
318 std::ostream& o) const {
319 const PosValChoice<Val>& pvc
320 = static_cast<const PosValChoice<Val>&>(c);
321 View xi = ViewBrancher<View,Filter,n>::view(pvc.pos());
322 if (p)
323 p(home,*this,b,xi,pvc.pos().pos,pvc.val(),o);
324 else
325 vsc->print(home,b,xi,pvc.pos().pos,pvc.val(),o);
326 }
327
328 template<class View, int n, class Val, unsigned int a,
329 class Filter, class Print>
330 forceinline size_t
331 ViewValBrancher<View,n,Val,a,Filter,Print>::dispose(Space& home) {
332 if (vsc->notice() || f.notice() || p.notice())
333 home.ignore(*this,AP_DISPOSE,true);
334 vsc->dispose(home);
335 (void) ViewBrancher<View,Filter,n>::dispose(home);
336 return sizeof(ViewValBrancher<View,n,Val,a,Filter,Print>);
337 }
338
339 template<class View, int n, class Val, unsigned int a>
340 forceinline void
341 postviewvalbrancher(Home home,
342 ViewArray<View>& x,
343 ViewSel<View>* vs[n],
344 ValSelCommitBase<View,Val>* vsc,
345 BranchFilter<typename View::VarType> bf,
346 VarValPrint<typename View::VarType,Val> vvp) {
347 if (bf) {
348 if (vvp) {
349 ViewValBrancher<View,n,Val,a,
350 BrancherFilter<View>,BrancherPrint<View,Val> >
351 ::post(home,x,vs,vsc,bf,vvp);
352 } else {
353 ViewValBrancher<View,n,Val,a,
354 BrancherFilter<View>,BrancherNoPrint<View,Val> >
355 ::post(home,x,vs,vsc,bf,vvp);
356 }
357 } else {
358 if (vvp)
359 ViewValBrancher<View,n,Val,a,
360 BrancherNoFilter<View>,BrancherPrint<View,Val> >
361 ::post(home,x,vs,vsc,bf,vvp);
362 else
363 ViewValBrancher<View,n,Val,a,
364 BrancherNoFilter<View>,BrancherNoPrint<View,Val> >
365 ::post(home,x,vs,vsc,bf,vvp);
366 }
367 }
368
369}
370
371// STATISTICS: kernel-branch