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 * Guido Tack <tack@gecode.org>
6 *
7 * Copyright:
8 * Christian Schulte, 2009
9 * Guido Tack, 2010
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
36#include <gecode/int/unary.hh>
37#include <gecode/int/distinct.hh>
38
39#include <algorithm>
40
41namespace Gecode {
42
43 void
44 unary(Home home, const IntVarArgs& s, const IntArgs& p, IntPropLevel ipl) {
45 using namespace Gecode::Int;
46 using namespace Gecode::Int::Unary;
47 if (same(s))
48 throw Int::ArgumentSame("Int::unary");
49 if (s.size() != p.size())
50 throw Int::ArgumentSizeMismatch("Int::unary");
51 for (int i=0; i<p.size(); i++) {
52 Int::Limits::nonnegative(p[i],"Int::unary");
53 Int::Limits::check(static_cast<long long int>(s[i].max()) + p[i],
54 "Int::unary");
55 }
56 GECODE_POST;
57 bool allOne = true;
58 for (int i=0; i<p.size(); i++) {
59 if (p[i] != 1) {
60 allOne = false;
61 break;
62 }
63 }
64 if (allOne) {
65 ViewArray<IntView> xv(home,s);
66 switch (vbd(ipl)) {
67 case IPL_BND:
68 GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,xv));
69 break;
70 case IPL_DOM:
71 GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv));
72 break;
73 default:
74 GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,xv));
75 }
76 } else {
77 TaskArray<ManFixPTask> t(home,s.size());
78 for (int i=0; i<s.size(); i++)
79 t[i].init(s[i],p[i]);
80 GECODE_ES_FAIL(manpost(home,t,ipl));
81 }
82 }
83
84 void
85 unary(Home home, const TaskTypeArgs& t,
86 const IntVarArgs& flex, const IntArgs& fix, IntPropLevel ipl) {
87 using namespace Gecode::Int;
88 using namespace Gecode::Int::Unary;
89 if ((flex.size() != fix.size()) || (flex.size() != t.size()))
90 throw Int::ArgumentSizeMismatch("Int::unary");
91 for (int i=0; i<fix.size(); i++) {
92 if (t[i] == TT_FIXP)
93 Int::Limits::nonnegative(fix[i],"Int::unary");
94 else
95 Int::Limits::check(fix[i],"Int::unary");
96 Int::Limits::check(static_cast<long long int>(flex[i].max()) + fix[i],
97 "Int::unary");
98 }
99 GECODE_POST;
100 bool fixp = true;
101 for (int i=0; i<t.size(); i++)
102 if (t[i] != TT_FIXP) {
103 fixp = false; break;
104 }
105 if (fixp) {
106 unary(home, flex, fix, ipl);
107 } else {
108 TaskArray<ManFixPSETask> tasks(home,flex.size());
109 for (int i=0; i<flex.size(); i++)
110 tasks[i].init(t[i],flex[i],fix[i]);
111 GECODE_ES_FAIL(manpost(home,tasks,ipl));
112 }
113 }
114
115 void
116 unary(Home home, const IntVarArgs& s, const IntArgs& p,
117 const BoolVarArgs& m, IntPropLevel ipl) {
118 using namespace Gecode::Int;
119 using namespace Gecode::Int::Unary;
120 if (same(s))
121 throw Int::ArgumentSame("Int::unary");
122 if ((s.size() != p.size()) || (s.size() != m.size()))
123 throw Int::ArgumentSizeMismatch("Int::unary");
124 for (int i=0; i<p.size(); i++) {
125 Int::Limits::nonnegative(p[i],"Int::unary");
126 Int::Limits::check(static_cast<long long int>(s[i].max()) + p[i],
127 "Int::unary");
128 }
129 bool allMandatory = true;
130 for (int i=0; i<m.size(); i++) {
131 if (!m[i].one()) {
132 allMandatory = false;
133 break;
134 }
135 }
136 if (allMandatory) {
137 unary(home,s,p,ipl);
138 } else {
139 GECODE_POST;
140 TaskArray<OptFixPTask> t(home,s.size());
141 for (int i=0; i<s.size(); i++)
142 t[i].init(s[i],p[i],m[i]);
143 GECODE_ES_FAIL(optpost(home,t,ipl));
144 }
145 }
146
147 void
148 unary(Home home, const TaskTypeArgs& t,
149 const IntVarArgs& flex, const IntArgs& fix, const BoolVarArgs& m,
150 IntPropLevel ipl) {
151 using namespace Gecode::Int;
152 using namespace Gecode::Int::Unary;
153 if ((flex.size() != fix.size()) || (flex.size() != t.size()) ||
154 (flex.size() != m.size()))
155 throw Int::ArgumentSizeMismatch("Int::unary");
156 bool fixp = true;
157 for (int i=0; i<fix.size(); i++) {
158 if (t[i] == TT_FIXP) {
159 Int::Limits::nonnegative(fix[i],"Int::unary");
160 } else {
161 fixp = false;
162 Int::Limits::check(fix[i],"Int::unary");
163 }
164 Int::Limits::check(static_cast<long long int>(flex[i].max()) + fix[i],
165 "Int::unary");
166 }
167 GECODE_POST;
168 bool allMandatory = true;
169 for (int i=0; i<m.size(); i++) {
170 if (!m[i].one()) {
171 allMandatory = false;
172 break;
173 }
174 }
175 if (allMandatory) {
176 unary(home,t,flex,fix,ipl);
177 } else {
178 if (fixp) {
179 TaskArray<OptFixPTask> tasks(home,flex.size());
180 for (int i=0; i<flex.size(); i++)
181 tasks[i].init(flex[i],fix[i],m[i]);
182 GECODE_ES_FAIL(optpost(home,tasks,ipl));
183 } else {
184 TaskArray<OptFixPSETask> tasks(home,flex.size());
185 for (int i=0; i<flex.size(); i++)
186 tasks[i].init(t[i],flex[i],fix[i],m[i]);
187 GECODE_ES_FAIL(optpost(home,tasks,ipl));
188 }
189 }
190 }
191
192 void
193 unary(Home home, const IntVarArgs& s, const IntVarArgs& p,
194 const IntVarArgs& e, IntPropLevel ipl) {
195 using namespace Gecode::Int;
196 using namespace Gecode::Int::Unary;
197 if ((s.size() != p.size()) || (s.size() != e.size()))
198 throw Int::ArgumentSizeMismatch("Int::unary");
199 GECODE_POST;
200 for (int i=0; i<p.size(); i++) {
201 IntView pi(p[i]);
202 GECODE_ME_FAIL(pi.gq(home,0));
203 }
204 bool fixP = true;
205 for (int i=0; i<p.size(); i++) {
206 if (!p[i].assigned()) {
207 fixP = false;
208 break;
209 }
210 }
211 if (fixP) {
212 IntArgs pp(p.size());
213 for (int i=0; i<p.size(); i++)
214 pp[i] = p[i].val();
215 unary(home,s,pp,ipl);
216 } else {
217 TaskArray<ManFlexTask> t(home,s.size());
218 for (int i=0; i<s.size(); i++)
219 t[i].init(s[i],p[i],e[i]);
220 GECODE_ES_FAIL(manpost(home,t,ipl));
221 }
222 }
223
224 void
225 unary(Home home, const IntVarArgs& s, const IntVarArgs& p,
226 const IntVarArgs& e, const BoolVarArgs& m, IntPropLevel ipl) {
227 using namespace Gecode::Int;
228 using namespace Gecode::Int::Unary;
229 if ((s.size() != p.size()) || (s.size() != m.size()) ||
230 (s.size() != e.size()))
231 throw Int::ArgumentSizeMismatch("Int::unary");
232 GECODE_POST;
233 for (int i=0; i<p.size(); i++) {
234 IntView pi(p[i]);
235 GECODE_ME_FAIL(pi.gq(home,0));
236 }
237 bool allMandatory = true;
238 for (int i=0; i<m.size(); i++) {
239 if (!m[i].one()) {
240 allMandatory = false;
241 break;
242 }
243 }
244 if (allMandatory) {
245 unary(home,s,p,e,ipl);
246 } else {
247 TaskArray<OptFlexTask> t(home,s.size());
248 for (int i=0; i<s.size(); i++)
249 t[i].init(s[i],p[i],e[i],m[i]);
250 GECODE_ES_FAIL(optpost(home,t,ipl));
251 }
252 }
253
254}
255
256// STATISTICS: int-post