Generated on Fri Jul 13 2018 06:08:22 for Gecode by doxygen 1.8.14
registry.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  * Main authors:
4  * Guido Tack <tack@gecode.org>
5  *
6  * Contributing authors:
7  * Mikael Lagerkvist <lagerkvist@gmail.com>
8  *
9  * Copyright:
10  * Guido Tack, 2007
11  * Mikael Lagerkvist, 2009
12  *
13  * Last modified:
14  * $Date: 2017-04-13 05:34:08 +0200 (Thu, 13 Apr 2017) $ by $Author: tack $
15  * $Revision: 15636 $
16  *
17  * This file is part of Gecode, the generic constraint
18  * development environment:
19  * http://www.gecode.org
20  *
21  * Permission is hereby granted, free of charge, to any person obtaining
22  * a copy of this software and associated documentation files (the
23  * "Software"), to deal in the Software without restriction, including
24  * without limitation the rights to use, copy, modify, merge, publish,
25  * distribute, sublicense, and/or sell copies of the Software, and to
26  * permit persons to whom the Software is furnished to do so, subject to
27  * the following conditions:
28  *
29  * The above copyright notice and this permission notice shall be
30  * included in all copies or substantial portions of the Software.
31  *
32  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39  *
40  */
41 
43 #include <gecode/kernel.hh>
44 #include <gecode/int.hh>
45 #include <gecode/minimodel.hh>
46 
47 #ifdef GECODE_HAS_SET_VARS
48 #include <gecode/set.hh>
49 #endif
50 #ifdef GECODE_HAS_FLOAT_VARS
51 #include <gecode/float.hh>
52 #endif
53 #include <gecode/flatzinc.hh>
54 
55 namespace Gecode { namespace FlatZinc {
56 
57  Registry& registry(void) {
58  static Registry r;
59  return r;
60  }
61 
62  void
64  std::map<std::string,poster>::iterator i = r.find(ce.id);
65  if (i == r.end()) {
66  throw FlatZinc::Error("Registry",
67  std::string("Constraint ")+ce.id+" not found");
68  }
69  i->second(s, ce, ce.ann);
70  }
71 
72  void
73  Registry::add(const std::string& id, poster p) {
74  r[id] = p;
75  }
76 
77  namespace {
78 
79  void p_distinct(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
80  IntVarArgs va = s.arg2intvarargs(ce[0]);
81  IntPropLevel ipl = s.ann2ipl(ann);
82  unshare(s, va);
83  distinct(s, va, ipl == IPL_DEF ? IPL_BND : ipl);
84  }
85 
86  void p_distinctOffset(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
87  IntVarArgs va = s.arg2intvarargs(ce[1]);
88  unshare(s, va);
89  AST::Array* offs = ce.args->a[0]->getArray();
90  IntArgs oa(offs->a.size());
91  for (int i=offs->a.size(); i--; ) {
92  oa[i] = offs->a[i]->getInt();
93  }
94  IntPropLevel ipl = s.ann2ipl(ann);
95  distinct(s, oa, va, ipl == IPL_DEF ? IPL_BND : ipl);
96  }
97 
98  void p_all_equal(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
99  IntVarArgs va = s.arg2intvarargs(ce[0]);
100  rel(s, va, IRT_EQ, s.ann2ipl(ann));
101  }
102 
103  void p_int_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
104  AST::Node* ann) {
105  if (ce[0]->isIntVar()) {
106  if (ce[1]->isIntVar()) {
107  rel(s, s.arg2IntVar(ce[0]), irt, s.arg2IntVar(ce[1]),
108  s.ann2ipl(ann));
109  } else {
110  rel(s, s.arg2IntVar(ce[0]), irt, ce[1]->getInt(), s.ann2ipl(ann));
111  }
112  } else {
113  rel(s, s.arg2IntVar(ce[1]), swap(irt), ce[0]->getInt(),
114  s.ann2ipl(ann));
115  }
116  }
117  void p_int_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
118  p_int_CMP(s, IRT_EQ, ce, ann);
119  }
120  void p_int_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
121  p_int_CMP(s, IRT_NQ, ce, ann);
122  }
123  void p_int_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
124  p_int_CMP(s, IRT_GQ, ce, ann);
125  }
126  void p_int_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
127  p_int_CMP(s, IRT_GR, ce, ann);
128  }
129  void p_int_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
130  p_int_CMP(s, IRT_LQ, ce, ann);
131  }
132  void p_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
133  p_int_CMP(s, IRT_LE, ce, ann);
134  }
135  void p_int_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
136  const ConExpr& ce, AST::Node* ann) {
137  if (rm == RM_EQV && ce[2]->isBool()) {
138  if (ce[2]->getBool()) {
139  p_int_CMP(s, irt, ce, ann);
140  } else {
141  p_int_CMP(s, neg(irt), ce, ann);
142  }
143  return;
144  }
145  if (ce[0]->isIntVar()) {
146  if (ce[1]->isIntVar()) {
147  rel(s, s.arg2IntVar(ce[0]), irt, s.arg2IntVar(ce[1]),
148  Reify(s.arg2BoolVar(ce[2]), rm), s.ann2ipl(ann));
149  } else {
150  rel(s, s.arg2IntVar(ce[0]), irt, ce[1]->getInt(),
151  Reify(s.arg2BoolVar(ce[2]), rm), s.ann2ipl(ann));
152  }
153  } else {
154  rel(s, s.arg2IntVar(ce[1]), swap(irt), ce[0]->getInt(),
155  Reify(s.arg2BoolVar(ce[2]), rm), s.ann2ipl(ann));
156  }
157  }
158 
159  /* Comparisons */
160  void p_int_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
161  p_int_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
162  }
163  void p_int_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
164  p_int_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
165  }
166  void p_int_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
167  p_int_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
168  }
169  void p_int_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
170  p_int_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
171  }
172  void p_int_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
173  p_int_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
174  }
175  void p_int_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
176  p_int_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
177  }
178 
179  void p_int_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
180  p_int_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
181  }
182  void p_int_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
183  p_int_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
184  }
185  void p_int_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
186  p_int_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
187  }
188  void p_int_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
189  p_int_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
190  }
191  void p_int_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
192  p_int_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
193  }
194  void p_int_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
195  p_int_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
196  }
197 
198  /* linear (in-)equations */
199  void p_int_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
200  AST::Node* ann) {
201  IntArgs ia = s.arg2intargs(ce[0]);
202  int singleIntVar;
203  if (s.isBoolArray(ce[1],singleIntVar)) {
204  if (singleIntVar != -1) {
205  if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
206  IntVar siv = s.arg2IntVar(ce[1]->getArray()->a[singleIntVar]);
207  BoolVarArgs iv = s.arg2boolvarargs(ce[1], 0, singleIntVar);
208  IntArgs ia_tmp(ia.size()-1);
209  int count = 0;
210  for (int i=0; i<ia.size(); i++) {
211  if (i != singleIntVar)
212  ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
213  }
214  IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
215  linear(s, ia_tmp, iv, t, siv, s.ann2ipl(ann));
216  } else {
217  IntVarArgs iv = s.arg2intvarargs(ce[1]);
218  linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2ipl(ann));
219  }
220  } else {
221  BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
222  linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2ipl(ann));
223  }
224  } else {
225  IntVarArgs iv = s.arg2intvarargs(ce[1]);
226  linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2ipl(ann));
227  }
228  }
229  void p_int_lin_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
230  const ConExpr& ce, AST::Node* ann) {
231  if (rm == RM_EQV && ce[2]->isBool()) {
232  if (ce[2]->getBool()) {
233  p_int_lin_CMP(s, irt, ce, ann);
234  } else {
235  p_int_lin_CMP(s, neg(irt), ce, ann);
236  }
237  return;
238  }
239  IntArgs ia = s.arg2intargs(ce[0]);
240  int singleIntVar;
241  if (s.isBoolArray(ce[1],singleIntVar)) {
242  if (singleIntVar != -1) {
243  if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
244  IntVar siv = s.arg2IntVar(ce[1]->getArray()->a[singleIntVar]);
245  BoolVarArgs iv = s.arg2boolvarargs(ce[1], 0, singleIntVar);
246  IntArgs ia_tmp(ia.size()-1);
247  int count = 0;
248  for (int i=0; i<ia.size(); i++) {
249  if (i != singleIntVar)
250  ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
251  }
252  IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
253  linear(s, ia_tmp, iv, t, siv, Reify(s.arg2BoolVar(ce[3]), rm),
254  s.ann2ipl(ann));
255  } else {
256  IntVarArgs iv = s.arg2intvarargs(ce[1]);
257  linear(s, ia, iv, irt, ce[2]->getInt(),
258  Reify(s.arg2BoolVar(ce[3]), rm), s.ann2ipl(ann));
259  }
260  } else {
261  BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
262  linear(s, ia, iv, irt, ce[2]->getInt(),
263  Reify(s.arg2BoolVar(ce[3]), rm), s.ann2ipl(ann));
264  }
265  } else {
266  IntVarArgs iv = s.arg2intvarargs(ce[1]);
267  linear(s, ia, iv, irt, ce[2]->getInt(),
268  Reify(s.arg2BoolVar(ce[3]), rm),
269  s.ann2ipl(ann));
270  }
271  }
272  void p_int_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
273  p_int_lin_CMP(s, IRT_EQ, ce, ann);
274  }
275  void p_int_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
276  p_int_lin_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
277  }
278  void p_int_lin_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
279  p_int_lin_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
280  }
281  void p_int_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
282  p_int_lin_CMP(s, IRT_NQ, ce, ann);
283  }
284  void p_int_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
285  p_int_lin_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
286  }
287  void p_int_lin_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
288  p_int_lin_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
289  }
290  void p_int_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
291  p_int_lin_CMP(s, IRT_LQ, ce, ann);
292  }
293  void p_int_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
294  p_int_lin_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
295  }
296  void p_int_lin_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
297  p_int_lin_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
298  }
299  void p_int_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
300  p_int_lin_CMP(s, IRT_LE, ce, ann);
301  }
302  void p_int_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
303  p_int_lin_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
304  }
305  void p_int_lin_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
306  p_int_lin_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
307  }
308  void p_int_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
309  p_int_lin_CMP(s, IRT_GQ, ce, ann);
310  }
311  void p_int_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
312  p_int_lin_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
313  }
314  void p_int_lin_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
315  p_int_lin_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
316  }
317  void p_int_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
318  p_int_lin_CMP(s, IRT_GR, ce, ann);
319  }
320  void p_int_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
321  p_int_lin_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
322  }
323  void p_int_lin_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
324  p_int_lin_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
325  }
326 
327  void p_bool_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
328  AST::Node* ann) {
329  IntArgs ia = s.arg2intargs(ce[0]);
330  BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
331  if (ce[2]->isIntVar())
332  linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], s.ann2ipl(ann));
333  else
334  linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2ipl(ann));
335  }
336  void p_bool_lin_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
337  const ConExpr& ce, AST::Node* ann) {
338  if (rm == RM_EQV && ce[2]->isBool()) {
339  if (ce[2]->getBool()) {
340  p_bool_lin_CMP(s, irt, ce, ann);
341  } else {
342  p_bool_lin_CMP(s, neg(irt), ce, ann);
343  }
344  return;
345  }
346  IntArgs ia = s.arg2intargs(ce[0]);
347  BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
348  if (ce[2]->isIntVar())
349  linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()],
350  Reify(s.arg2BoolVar(ce[3]), rm),
351  s.ann2ipl(ann));
352  else
353  linear(s, ia, iv, irt, ce[2]->getInt(),
354  Reify(s.arg2BoolVar(ce[3]), rm),
355  s.ann2ipl(ann));
356  }
357  void p_bool_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
358  p_bool_lin_CMP(s, IRT_EQ, ce, ann);
359  }
360  void p_bool_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
361  {
362  p_bool_lin_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
363  }
364  void p_bool_lin_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
365  {
366  p_bool_lin_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
367  }
368  void p_bool_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
369  p_bool_lin_CMP(s, IRT_NQ, ce, ann);
370  }
371  void p_bool_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
372  {
373  p_bool_lin_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
374  }
375  void p_bool_lin_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
376  {
377  p_bool_lin_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
378  }
379  void p_bool_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
380  p_bool_lin_CMP(s, IRT_LQ, ce, ann);
381  }
382  void p_bool_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
383  {
384  p_bool_lin_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
385  }
386  void p_bool_lin_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
387  {
388  p_bool_lin_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
389  }
390  void p_bool_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
391  {
392  p_bool_lin_CMP(s, IRT_LE, ce, ann);
393  }
394  void p_bool_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
395  {
396  p_bool_lin_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
397  }
398  void p_bool_lin_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
399  {
400  p_bool_lin_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
401  }
402  void p_bool_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
403  p_bool_lin_CMP(s, IRT_GQ, ce, ann);
404  }
405  void p_bool_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
406  {
407  p_bool_lin_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
408  }
409  void p_bool_lin_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
410  {
411  p_bool_lin_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
412  }
413  void p_bool_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
414  p_bool_lin_CMP(s, IRT_GR, ce, ann);
415  }
416  void p_bool_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
417  {
418  p_bool_lin_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
419  }
420  void p_bool_lin_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
421  {
422  p_bool_lin_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
423  }
424 
425  /* arithmetic constraints */
426 
427  void p_int_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
428  if (!ce[0]->isIntVar()) {
429  rel(s, ce[0]->getInt() + s.arg2IntVar(ce[1])
430  == s.arg2IntVar(ce[2]), s.ann2ipl(ann));
431  } else if (!ce[1]->isIntVar()) {
432  rel(s, s.arg2IntVar(ce[0]) + ce[1]->getInt()
433  == s.arg2IntVar(ce[2]), s.ann2ipl(ann));
434  } else if (!ce[2]->isIntVar()) {
435  rel(s, s.arg2IntVar(ce[0]) + s.arg2IntVar(ce[1])
436  == ce[2]->getInt(), s.ann2ipl(ann));
437  } else {
438  rel(s, s.arg2IntVar(ce[0]) + s.arg2IntVar(ce[1])
439  == s.arg2IntVar(ce[2]), s.ann2ipl(ann));
440  }
441  }
442 
443  void p_int_minus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
444  if (!ce[0]->isIntVar()) {
445  rel(s, ce[0]->getInt() - s.arg2IntVar(ce[1])
446  == s.arg2IntVar(ce[2]), s.ann2ipl(ann));
447  } else if (!ce[1]->isIntVar()) {
448  rel(s, s.arg2IntVar(ce[0]) - ce[1]->getInt()
449  == s.arg2IntVar(ce[2]), s.ann2ipl(ann));
450  } else if (!ce[2]->isIntVar()) {
451  rel(s, s.arg2IntVar(ce[0]) - s.arg2IntVar(ce[1])
452  == ce[2]->getInt(), s.ann2ipl(ann));
453  } else {
454  rel(s, s.arg2IntVar(ce[0]) - s.arg2IntVar(ce[1])
455  == s.arg2IntVar(ce[2]), s.ann2ipl(ann));
456  }
457  }
458 
459  void p_int_times(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
460  IntVar x0 = s.arg2IntVar(ce[0]);
461  IntVar x1 = s.arg2IntVar(ce[1]);
462  IntVar x2 = s.arg2IntVar(ce[2]);
463  mult(s, x0, x1, x2, s.ann2ipl(ann));
464  }
465  void p_int_div(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
466  IntVar x0 = s.arg2IntVar(ce[0]);
467  IntVar x1 = s.arg2IntVar(ce[1]);
468  IntVar x2 = s.arg2IntVar(ce[2]);
469  div(s,x0,x1,x2, s.ann2ipl(ann));
470  }
471  void p_int_mod(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
472  IntVar x0 = s.arg2IntVar(ce[0]);
473  IntVar x1 = s.arg2IntVar(ce[1]);
474  IntVar x2 = s.arg2IntVar(ce[2]);
475  mod(s,x0,x1,x2, s.ann2ipl(ann));
476  }
477 
478  void p_int_min(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
479  IntVar x0 = s.arg2IntVar(ce[0]);
480  IntVar x1 = s.arg2IntVar(ce[1]);
481  IntVar x2 = s.arg2IntVar(ce[2]);
482  min(s, x0, x1, x2, s.ann2ipl(ann));
483  }
484  void p_int_max(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
485  IntVar x0 = s.arg2IntVar(ce[0]);
486  IntVar x1 = s.arg2IntVar(ce[1]);
487  IntVar x2 = s.arg2IntVar(ce[2]);
488  max(s, x0, x1, x2, s.ann2ipl(ann));
489  }
490  void p_int_negate(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
491  IntVar x0 = s.arg2IntVar(ce[0]);
492  IntVar x1 = s.arg2IntVar(ce[1]);
493  rel(s, x0 == -x1, s.ann2ipl(ann));
494  }
495 
496  /* Boolean constraints */
497  void p_bool_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
498  AST::Node* ann) {
499  rel(s, s.arg2BoolVar(ce[0]), irt, s.arg2BoolVar(ce[1]),
500  s.ann2ipl(ann));
501  }
502  void p_bool_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
503  const ConExpr& ce, AST::Node* ann) {
504  rel(s, s.arg2BoolVar(ce[0]), irt, s.arg2BoolVar(ce[1]),
505  Reify(s.arg2BoolVar(ce[2]), rm), s.ann2ipl(ann));
506  }
507  void p_bool_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
508  p_bool_CMP(s, IRT_EQ, ce, ann);
509  }
510  void p_bool_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
511  p_bool_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
512  }
513  void p_bool_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
514  p_bool_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
515  }
516  void p_bool_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
517  p_bool_CMP(s, IRT_NQ, ce, ann);
518  }
519  void p_bool_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
520  p_bool_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
521  }
522  void p_bool_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
523  p_bool_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
524  }
525  void p_bool_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
526  p_bool_CMP(s, IRT_GQ, ce, ann);
527  }
528  void p_bool_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
529  p_bool_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
530  }
531  void p_bool_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
532  p_bool_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
533  }
534  void p_bool_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
535  p_bool_CMP(s, IRT_LQ, ce, ann);
536  }
537  void p_bool_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
538  p_bool_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
539  }
540  void p_bool_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
541  p_bool_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
542  }
543  void p_bool_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
544  p_bool_CMP(s, IRT_GR, ce, ann);
545  }
546  void p_bool_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
547  p_bool_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
548  }
549  void p_bool_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
550  p_bool_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
551  }
552  void p_bool_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
553  p_bool_CMP(s, IRT_LE, ce, ann);
554  }
555  void p_bool_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
556  p_bool_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
557  }
558  void p_bool_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
559  p_bool_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
560  }
561 
562 #define BOOL_OP(op) \
563  BoolVar b0 = s.arg2BoolVar(ce[0]); \
564  BoolVar b1 = s.arg2BoolVar(ce[1]); \
565  if (ce[2]->isBool()) { \
566  rel(s, b0, op, b1, ce[2]->getBool(), s.ann2ipl(ann)); \
567  } else { \
568  rel(s, b0, op, b1, s.bv[ce[2]->getBoolVar()], s.ann2ipl(ann)); \
569  }
570 
571 #define BOOL_ARRAY_OP(op) \
572  BoolVarArgs bv = s.arg2boolvarargs(ce[0]); \
573  if (ce.size()==1) { \
574  rel(s, op, bv, 1, s.ann2ipl(ann)); \
575  } else if (ce[1]->isBool()) { \
576  rel(s, op, bv, ce[1]->getBool(), s.ann2ipl(ann)); \
577  } else { \
578  rel(s, op, bv, s.bv[ce[1]->getBoolVar()], s.ann2ipl(ann)); \
579  }
580 
581  void p_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
582  BOOL_OP(BOT_OR);
583  }
584  void p_bool_or_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
585  BoolVar b0 = s.arg2BoolVar(ce[0]);
586  BoolVar b1 = s.arg2BoolVar(ce[1]);
587  BoolVar b2 = s.arg2BoolVar(ce[2]);
588  clause(s, BOT_OR, BoolVarArgs()<<b0<<b1, BoolVarArgs()<<b2, 1,
589  s.ann2ipl(ann));
590  }
591  void p_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
592  BOOL_OP(BOT_AND);
593  }
594  void p_bool_and_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
595  BoolVar b0 = s.arg2BoolVar(ce[0]);
596  BoolVar b1 = s.arg2BoolVar(ce[1]);
597  BoolVar b2 = s.arg2BoolVar(ce[2]);
598  rel(s, b2, BOT_IMP, b0, 1, s.ann2ipl(ann));
599  rel(s, b2, BOT_IMP, b1, 1, s.ann2ipl(ann));
600  }
601  void p_array_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
602  {
604  }
605  void p_array_bool_and_imp(FlatZincSpace& s, const ConExpr& ce,
606  AST::Node* ann)
607  {
608  BoolVarArgs bv = s.arg2boolvarargs(ce[0]);
609  BoolVar b1 = s.arg2BoolVar(ce[1]);
610  for (unsigned int i=bv.size(); i--;)
611  rel(s, b1, BOT_IMP, bv[i], 1, s.ann2ipl(ann));
612  }
613  void p_array_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
614  {
616  }
617  void p_array_bool_or_imp(FlatZincSpace& s, const ConExpr& ce,
618  AST::Node* ann)
619  {
620  BoolVarArgs bv = s.arg2boolvarargs(ce[0]);
621  BoolVar b1 = s.arg2BoolVar(ce[1]);
622  clause(s, BOT_OR, bv, BoolVarArgs()<<b1, 1, s.ann2ipl(ann));
623  }
624  void p_array_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
625  {
627  }
628  void p_array_bool_xor_imp(FlatZincSpace& s, const ConExpr& ce,
629  AST::Node* ann)
630  {
631  BoolVarArgs bv = s.arg2boolvarargs(ce[0]);
632  BoolVar tmp(s,0,1);
633  rel(s, BOT_XOR, bv, tmp, s.ann2ipl(ann));
634  rel(s, s.arg2BoolVar(ce[1]), BOT_IMP, tmp, 1);
635  }
636  void p_array_bool_clause(FlatZincSpace& s, const ConExpr& ce,
637  AST::Node* ann) {
638  BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
639  BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
640  clause(s, BOT_OR, bvp, bvn, 1, s.ann2ipl(ann));
641  }
642  void p_array_bool_clause_reif(FlatZincSpace& s, const ConExpr& ce,
643  AST::Node* ann) {
644  BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
645  BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
646  BoolVar b0 = s.arg2BoolVar(ce[2]);
647  clause(s, BOT_OR, bvp, bvn, b0, s.ann2ipl(ann));
648  }
649  void p_array_bool_clause_imp(FlatZincSpace& s, const ConExpr& ce,
650  AST::Node* ann) {
651  BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
652  BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
653  BoolVar b0 = s.arg2BoolVar(ce[2]);
654  clause(s, BOT_OR, bvp, bvn, b0, s.ann2ipl(ann));
655  }
656  void p_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
657  BOOL_OP(BOT_XOR);
658  }
659  void p_bool_xor_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
660  BoolVar b0 = s.arg2BoolVar(ce[0]);
661  BoolVar b1 = s.arg2BoolVar(ce[1]);
662  BoolVar b2 = s.arg2BoolVar(ce[2]);
663  clause(s, BOT_OR, BoolVarArgs()<<b0<<b1, BoolVarArgs()<<b2, 1,
664  s.ann2ipl(ann));
665  clause(s, BOT_OR, BoolVarArgs(), BoolVarArgs()<<b0<<b1<<b2, 1,
666  s.ann2ipl(ann));
667  }
668  void p_bool_l_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
669  BoolVar b0 = s.arg2BoolVar(ce[0]);
670  BoolVar b1 = s.arg2BoolVar(ce[1]);
671  if (ce[2]->isBool()) {
672  rel(s, b1, BOT_IMP, b0, ce[2]->getBool(), s.ann2ipl(ann));
673  } else {
674  rel(s, b1, BOT_IMP, b0, s.bv[ce[2]->getBoolVar()], s.ann2ipl(ann));
675  }
676  }
677  void p_bool_r_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
678  BOOL_OP(BOT_IMP);
679  }
680  void p_bool_not(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
681  BoolVar x0 = s.arg2BoolVar(ce[0]);
682  BoolVar x1 = s.arg2BoolVar(ce[1]);
683  rel(s, x0, BOT_XOR, x1, 1, s.ann2ipl(ann));
684  }
685 
686  /* element constraints */
687  void p_array_int_element(FlatZincSpace& s, const ConExpr& ce,
688  AST::Node* ann) {
689  bool isConstant = true;
690  AST::Array* a = ce[1]->getArray();
691  for (int i=a->a.size(); i--;) {
692  if (!a->a[i]->isInt()) {
693  isConstant = false;
694  break;
695  }
696  }
697  IntVar selector = s.arg2IntVar(ce[0]);
698  rel(s, selector > 0);
699  if (isConstant) {
700  IntArgs ia = s.arg2intargs(ce[1], 1);
701  element(s, ia, selector, s.arg2IntVar(ce[2]), s.ann2ipl(ann));
702  } else {
703  IntVarArgs iv = s.arg2intvarargs(ce[1], 1);
704  element(s, iv, selector, s.arg2IntVar(ce[2]), s.ann2ipl(ann));
705  }
706  }
707  void p_array_bool_element(FlatZincSpace& s, const ConExpr& ce,
708  AST::Node* ann) {
709  bool isConstant = true;
710  AST::Array* a = ce[1]->getArray();
711  for (int i=a->a.size(); i--;) {
712  if (!a->a[i]->isBool()) {
713  isConstant = false;
714  break;
715  }
716  }
717  IntVar selector = s.arg2IntVar(ce[0]);
718  rel(s, selector > 0);
719  if (isConstant) {
720  IntArgs ia = s.arg2boolargs(ce[1], 1);
721  element(s, ia, selector, s.arg2BoolVar(ce[2]), s.ann2ipl(ann));
722  } else {
723  BoolVarArgs iv = s.arg2boolvarargs(ce[1], 1);
724  element(s, iv, selector, s.arg2BoolVar(ce[2]), s.ann2ipl(ann));
725  }
726  }
727 
728  /* coercion constraints */
729  void p_bool2int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
730  BoolVar x0 = s.arg2BoolVar(ce[0]);
731  IntVar x1 = s.arg2IntVar(ce[1]);
732  if (ce[0]->isBoolVar() && ce[1]->isIntVar()) {
733  s.aliasBool2Int(ce[1]->getIntVar(), ce[0]->getBoolVar());
734  }
735  channel(s, x0, x1, s.ann2ipl(ann));
736  }
737 
738  void p_int_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
739  IntSet d = s.arg2intset(ce[1]);
740  if (ce[0]->isBoolVar()) {
741  IntSetRanges dr(d);
742  Iter::Ranges::Singleton sr(0,1);
743  Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
744  IntSet d01(i);
745  if (d01.size() == 0) {
746  s.fail();
747  } else {
748  rel(s, s.arg2BoolVar(ce[0]), IRT_GQ, d01.min());
749  rel(s, s.arg2BoolVar(ce[0]), IRT_LQ, d01.max());
750  }
751  } else {
752  dom(s, s.arg2IntVar(ce[0]), d);
753  }
754  }
755  void p_int_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
756  IntSet d = s.arg2intset(ce[1]);
757  if (ce[0]->isBoolVar()) {
758  IntSetRanges dr(d);
759  Iter::Ranges::Singleton sr(0,1);
760  Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
761  IntSet d01(i);
762  if (d01.size() == 0) {
763  rel(s, s.arg2BoolVar(ce[2]) == 0);
764  } else if (d01.max() == 0) {
765  rel(s, s.arg2BoolVar(ce[2]) == !s.arg2BoolVar(ce[0]));
766  } else if (d01.min() == 1) {
767  rel(s, s.arg2BoolVar(ce[2]) == s.arg2BoolVar(ce[0]));
768  } else {
769  rel(s, s.arg2BoolVar(ce[2]) == 1);
770  }
771  } else {
772  dom(s, s.arg2IntVar(ce[0]), d, s.arg2BoolVar(ce[2]));
773  }
774  }
775  void p_int_in_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
776  IntSet d = s.arg2intset(ce[1]);
777  if (ce[0]->isBoolVar()) {
778  IntSetRanges dr(d);
779  Iter::Ranges::Singleton sr(0,1);
780  Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
781  IntSet d01(i);
782  if (d01.size() == 0) {
783  rel(s, s.arg2BoolVar(ce[2]) == 0);
784  } else if (d01.max() == 0) {
785  rel(s, s.arg2BoolVar(ce[2]) >> !s.arg2BoolVar(ce[0]));
786  } else if (d01.min() == 1) {
787  rel(s, s.arg2BoolVar(ce[2]) >> s.arg2BoolVar(ce[0]));
788  }
789  } else {
790  dom(s, s.arg2IntVar(ce[0]), d, Reify(s.arg2BoolVar(ce[2]),RM_IMP));
791  }
792  }
793 
794  /* constraints from the standard library */
795 
796  void p_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
797  IntVar x0 = s.arg2IntVar(ce[0]);
798  IntVar x1 = s.arg2IntVar(ce[1]);
799  abs(s, x0, x1, s.ann2ipl(ann));
800  }
801 
802  void p_array_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
803  IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
804  IntVarArgs iv1 = s.arg2intvarargs(ce[1]);
805  rel(s, iv0, IRT_LE, iv1, s.ann2ipl(ann));
806  }
807 
808  void p_array_int_lq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
809  IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
810  IntVarArgs iv1 = s.arg2intvarargs(ce[1]);
811  rel(s, iv0, IRT_LQ, iv1, s.ann2ipl(ann));
812  }
813 
814  void p_array_bool_lt(FlatZincSpace& s, const ConExpr& ce,
815  AST::Node* ann) {
816  BoolVarArgs bv0 = s.arg2boolvarargs(ce[0]);
817  BoolVarArgs bv1 = s.arg2boolvarargs(ce[1]);
818  rel(s, bv0, IRT_LE, bv1, s.ann2ipl(ann));
819  }
820 
821  void p_array_bool_lq(FlatZincSpace& s, const ConExpr& ce,
822  AST::Node* ann) {
823  BoolVarArgs bv0 = s.arg2boolvarargs(ce[0]);
824  BoolVarArgs bv1 = s.arg2boolvarargs(ce[1]);
825  rel(s, bv0, IRT_LQ, bv1, s.ann2ipl(ann));
826  }
827 
828  void p_count(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
829  IntVarArgs iv = s.arg2intvarargs(ce[0]);
830  if (!ce[1]->isIntVar()) {
831  if (!ce[2]->isIntVar()) {
832  count(s, iv, ce[1]->getInt(), IRT_EQ, ce[2]->getInt(),
833  s.ann2ipl(ann));
834  } else {
835  count(s, iv, ce[1]->getInt(), IRT_EQ, s.arg2IntVar(ce[2]),
836  s.ann2ipl(ann));
837  }
838  } else if (!ce[2]->isIntVar()) {
839  count(s, iv, s.arg2IntVar(ce[1]), IRT_EQ, ce[2]->getInt(),
840  s.ann2ipl(ann));
841  } else {
842  count(s, iv, s.arg2IntVar(ce[1]), IRT_EQ, s.arg2IntVar(ce[2]),
843  s.ann2ipl(ann));
844  }
845  }
846 
847  void p_count_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
848  IntVarArgs iv = s.arg2intvarargs(ce[0]);
849  IntVar x = s.arg2IntVar(ce[1]);
850  IntVar y = s.arg2IntVar(ce[2]);
851  BoolVar b = s.arg2BoolVar(ce[3]);
852  IntVar c(s,0,Int::Limits::max);
853  count(s,iv,x,IRT_EQ,c,s.ann2ipl(ann));
854  rel(s, b == (c==y));
855  }
856  void p_count_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
857  IntVarArgs iv = s.arg2intvarargs(ce[0]);
858  IntVar x = s.arg2IntVar(ce[1]);
859  IntVar y = s.arg2IntVar(ce[2]);
860  BoolVar b = s.arg2BoolVar(ce[3]);
861  IntVar c(s,0,Int::Limits::max);
862  count(s,iv,x,IRT_EQ,c,s.ann2ipl(ann));
863  rel(s, b >> (c==y));
864  }
865 
866  void count_rel(IntRelType irt,
867  FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
868  IntVarArgs iv = s.arg2intvarargs(ce[1]);
869  count(s, iv, ce[2]->getInt(), irt, ce[0]->getInt(), s.ann2ipl(ann));
870  }
871 
872  void p_at_most(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
873  count_rel(IRT_LQ, s, ce, ann);
874  }
875 
876  void p_at_least(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
877  count_rel(IRT_GQ, s, ce, ann);
878  }
879 
880  void p_bin_packing_load(FlatZincSpace& s, const ConExpr& ce,
881  AST::Node* ann) {
882  int minIdx = ce[3]->getInt();
883  IntVarArgs load = s.arg2intvarargs(ce[0]);
884  IntVarArgs l;
885  IntVarArgs bin = s.arg2intvarargs(ce[1]);
886  for (int i=bin.size(); i--;)
887  rel(s, bin[i] >= minIdx);
888  if (minIdx > 0) {
889  for (int i=minIdx; i--;)
890  l << IntVar(s,0,0);
891  } else if (minIdx < 0) {
892  IntVarArgs bin2(bin.size());
893  for (int i=bin.size(); i--;)
894  bin2[i] = expr(s, bin[i]-minIdx, s.ann2ipl(ann));
895  bin = bin2;
896  }
897  l << load;
898  IntArgs sizes = s.arg2intargs(ce[2]);
899 
900  IntVarArgs allvars = l + bin;
901  unshare(s, allvars);
902  binpacking(s, allvars.slice(0,1,l.size()), allvars.slice(l.size(),1,bin.size()),
903  sizes, s.ann2ipl(ann));
904  }
905 
906  void p_global_cardinality(FlatZincSpace& s, const ConExpr& ce,
907  AST::Node* ann) {
908  IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
909  IntArgs cover = s.arg2intargs(ce[1]);
910  IntVarArgs iv1 = s.arg2intvarargs(ce[2]);
911 
912  Region re(s);
913  IntSet cover_s(cover);
914  IntSetRanges cover_r(cover_s);
915  IntVarRanges* iv0_ri = re.alloc<IntVarRanges>(iv0.size());
916  for (int i=iv0.size(); i--;)
917  iv0_ri[i] = IntVarRanges(iv0[i]);
918  Iter::Ranges::NaryUnion iv0_r(re,iv0_ri,iv0.size());
919  Iter::Ranges::Diff<Iter::Ranges::NaryUnion,IntSetRanges>
920  extra_r(iv0_r,cover_r);
921  Iter::Ranges::ToValues<Iter::Ranges::Diff<
922  Iter::Ranges::NaryUnion,IntSetRanges> > extra(extra_r);
923  for (; extra(); ++extra) {
924  cover << extra.val();
925  iv1 << IntVar(s,0,iv0.size());
926  }
927  IntPropLevel ipl = s.ann2ipl(ann);
928  if (ipl==IPL_DEF)
929  ipl=IPL_BND;
930  if (ipl==IPL_DOM) {
931  IntVarArgs allvars = iv0+iv1;
932  unshare(s, allvars);
933  count(s, allvars.slice(0,1,iv0.size()),
934  allvars.slice(iv0.size(),1,iv1.size()),
935  cover, ipl);
936  } else {
937  unshare(s, iv0);
938  count(s, iv0, iv1, cover, ipl);
939  }
940  }
941 
942  void p_global_cardinality_closed(FlatZincSpace& s, const ConExpr& ce,
943  AST::Node* ann) {
944  IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
945  IntArgs cover = s.arg2intargs(ce[1]);
946  IntVarArgs iv1 = s.arg2intvarargs(ce[2]);
947  unshare(s, iv0);
948  count(s, iv0, iv1, cover, s.ann2ipl(ann));
949  }
950 
951  void p_global_cardinality_low_up(FlatZincSpace& s, const ConExpr& ce,
952  AST::Node* ann) {
953  IntVarArgs x = s.arg2intvarargs(ce[0]);
954  IntArgs cover = s.arg2intargs(ce[1]);
955 
956  IntArgs lbound = s.arg2intargs(ce[2]);
957  IntArgs ubound = s.arg2intargs(ce[3]);
958  IntSetArgs y(cover.size());
959  for (int i=cover.size(); i--;)
960  y[i] = IntSet(lbound[i],ubound[i]);
961 
962  IntSet cover_s(cover);
963  Region re(s);
964  IntVarRanges* xrs = re.alloc<IntVarRanges>(x.size());
965  for (int i=x.size(); i--;)
966  xrs[i].init(x[i]);
967  Iter::Ranges::NaryUnion u(re, xrs, x.size());
968  Iter::Ranges::ToValues<Iter::Ranges::NaryUnion> uv(u);
969  for (; uv(); ++uv) {
970  if (!cover_s.in(uv.val())) {
971  cover << uv.val();
972  y << IntSet(0,x.size());
973  }
974  }
975  unshare(s, x);
976  count(s, x, y, cover, s.ann2ipl(ann));
977  }
978 
979  void p_global_cardinality_low_up_closed(FlatZincSpace& s,
980  const ConExpr& ce,
981  AST::Node* ann) {
982  IntVarArgs x = s.arg2intvarargs(ce[0]);
983  IntArgs cover = s.arg2intargs(ce[1]);
984 
985  IntArgs lbound = s.arg2intargs(ce[2]);
986  IntArgs ubound = s.arg2intargs(ce[3]);
987  IntSetArgs y(cover.size());
988  for (int i=cover.size(); i--;)
989  y[i] = IntSet(lbound[i],ubound[i]);
990  unshare(s, x);
991  count(s, x, y, cover, s.ann2ipl(ann));
992  }
993 
994  void p_minimum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
995  IntVarArgs iv = s.arg2intvarargs(ce[1]);
996  min(s, iv, s.arg2IntVar(ce[0]), s.ann2ipl(ann));
997  }
998 
999  void p_maximum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1000  IntVarArgs iv = s.arg2intvarargs(ce[1]);
1001  max(s, iv, s.arg2IntVar(ce[0]), s.ann2ipl(ann));
1002  }
1003 
1004  void p_minimum_arg(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1005  IntVarArgs iv = s.arg2intvarargs(ce[0]);
1006  argmin(s, iv, s.arg2IntVar(ce[1]), true, s.ann2ipl(ann));
1007  }
1008 
1009  void p_maximum_arg(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1010  IntVarArgs iv = s.arg2intvarargs(ce[0]);
1011  argmax(s, iv, s.arg2IntVar(ce[1]), true, s.ann2ipl(ann));
1012  }
1013 
1014  void p_regular(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1015  IntVarArgs iv = s.arg2intvarargs(ce[0]);
1016  int q = ce[1]->getInt();
1017  int symbols = ce[2]->getInt();
1018  IntArgs d = s.arg2intargs(ce[3]);
1019  int q0 = ce[4]->getInt();
1020 
1021  int noOfTrans = 0;
1022  for (int i=1; i<=q; i++) {
1023  for (int j=1; j<=symbols; j++) {
1024  if (d[(i-1)*symbols+(j-1)] > 0)
1025  noOfTrans++;
1026  }
1027  }
1028 
1029  Region re(s);
1030  DFA::Transition* t = re.alloc<DFA::Transition>(noOfTrans+1);
1031  noOfTrans = 0;
1032  for (int i=1; i<=q; i++) {
1033  for (int j=1; j<=symbols; j++) {
1034  if (d[(i-1)*symbols+(j-1)] > 0) {
1035  t[noOfTrans].i_state = i;
1036  t[noOfTrans].symbol = j;
1037  t[noOfTrans].o_state = d[(i-1)*symbols+(j-1)];
1038  noOfTrans++;
1039  }
1040  }
1041  }
1042  t[noOfTrans].i_state = -1;
1043 
1044  // Final states
1045  AST::SetLit* sl = ce[5]->getSet();
1046  int* f;
1047  if (sl->interval) {
1048  f = static_cast<int*>(malloc(sizeof(int)*(sl->max-sl->min+2)));
1049  for (int i=sl->min; i<=sl->max; i++)
1050  f[i-sl->min] = i;
1051  f[sl->max-sl->min+1] = -1;
1052  } else {
1053  f = static_cast<int*>(malloc(sizeof(int)*(sl->s.size()+1)));
1054  for (int j=sl->s.size(); j--; )
1055  f[j] = sl->s[j];
1056  f[sl->s.size()] = -1;
1057  }
1058 
1059  DFA dfa(q0,t,f);
1060  free(f);
1061  unshare(s, iv);
1062  extensional(s, iv, dfa, s.ann2ipl(ann));
1063  }
1064 
1065  void
1066  p_sort(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1067  IntVarArgs x = s.arg2intvarargs(ce[0]);
1068  IntVarArgs y = s.arg2intvarargs(ce[1]);
1069  IntVarArgs xy(x.size()+y.size());
1070  for (int i=x.size(); i--;)
1071  xy[i] = x[i];
1072  for (int i=y.size(); i--;)
1073  xy[i+x.size()] = y[i];
1074  unshare(s, xy);
1075  for (int i=x.size(); i--;)
1076  x[i] = xy[i];
1077  for (int i=y.size(); i--;)
1078  y[i] = xy[i+x.size()];
1079  sorted(s, x, y, s.ann2ipl(ann));
1080  }
1081 
1082  void
1083  p_inverse_offsets(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1084  IntVarArgs x = s.arg2intvarargs(ce[0]);
1085  unshare(s, x);
1086  int xoff = ce[1]->getInt();
1087  IntVarArgs y = s.arg2intvarargs(ce[2]);
1088  unshare(s, y);
1089  int yoff = ce[3]->getInt();
1090  channel(s, x, xoff, y, yoff, s.ann2ipl(ann));
1091  }
1092 
1093  void
1094  p_increasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1095  IntVarArgs x = s.arg2intvarargs(ce[0]);
1096  rel(s,x,IRT_LQ,s.ann2ipl(ann));
1097  }
1098 
1099  void
1100  p_increasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1101  BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1102  rel(s,x,IRT_LQ,s.ann2ipl(ann));
1103  }
1104 
1105  void
1106  p_decreasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1107  IntVarArgs x = s.arg2intvarargs(ce[0]);
1108  rel(s,x,IRT_GQ,s.ann2ipl(ann));
1109  }
1110 
1111  void
1112  p_decreasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1113  BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1114  rel(s,x,IRT_GQ,s.ann2ipl(ann));
1115  }
1116 
1117  void
1118  p_table_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1119  IntVarArgs x = s.arg2intvarargs(ce[0]);
1120  IntArgs tuples = s.arg2intargs(ce[1]);
1121  int noOfVars = x.size();
1122  int noOfTuples = tuples.size() == 0 ? 0 : (tuples.size()/noOfVars);
1123  TupleSet ts;
1124  for (int i=0; i<noOfTuples; i++) {
1125  IntArgs t(noOfVars);
1126  for (int j=0; j<x.size(); j++) {
1127  t[j] = tuples[i*noOfVars+j];
1128  }
1129  ts.add(t);
1130  }
1131  ts.finalize();
1132  extensional(s,x,ts,s.ann2ipl(ann));
1133  }
1134  void
1135  p_table_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1136  BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1137  IntArgs tuples = s.arg2boolargs(ce[1]);
1138  int noOfVars = x.size();
1139  int noOfTuples = tuples.size() == 0 ? 0 : (tuples.size()/noOfVars);
1140  TupleSet ts;
1141  for (int i=0; i<noOfTuples; i++) {
1142  IntArgs t(noOfVars);
1143  for (int j=0; j<x.size(); j++) {
1144  t[j] = tuples[i*noOfVars+j];
1145  }
1146  ts.add(t);
1147  }
1148  ts.finalize();
1149  extensional(s,x,ts,s.ann2ipl(ann));
1150  }
1151 
1152  void p_cumulative_opt(FlatZincSpace& s, const ConExpr& ce,
1153  AST::Node* ann) {
1154  IntVarArgs start = s.arg2intvarargs(ce[0]);
1155  IntArgs duration = s.arg2intargs(ce[1]);
1156  IntArgs height = s.arg2intargs(ce[2]);
1157  BoolVarArgs opt = s.arg2boolvarargs(ce[3]);
1158  int bound = ce[4]->getInt();
1159  unshare(s,start);
1160  cumulative(s,bound,start,duration,height,opt,s.ann2ipl(ann));
1161  }
1162 
1163  void p_cumulatives(FlatZincSpace& s, const ConExpr& ce,
1164  AST::Node* ann) {
1165  IntVarArgs start = s.arg2intvarargs(ce[0]);
1166  IntVarArgs duration = s.arg2intvarargs(ce[1]);
1167  IntVarArgs height = s.arg2intvarargs(ce[2]);
1168  int n = start.size();
1169  IntVar bound = s.arg2IntVar(ce[3]);
1170 
1171  if (n==0)
1172  return;
1173 
1174  if (n == 1) {
1175  rel(s, height[0] <= bound);
1176  return;
1177  }
1178 
1179  int minHeight = std::min(height[0].min(),height[1].min());
1180  int minHeight2 = std::max(height[0].min(),height[1].min());
1181  for (int i=2; i<n; i++) {
1182  if (height[i].min() < minHeight) {
1183  minHeight2 = minHeight;
1184  minHeight = height[i].min();
1185  } else if (height[i].min() < minHeight2) {
1186  minHeight2 = height[i].min();
1187  }
1188  }
1189  bool disjunctive =
1190  (minHeight > bound.max()/2) ||
1191  (minHeight2 > bound.max()/2 && minHeight+minHeight2>bound.max());
1192  if (disjunctive) {
1193  rel(s, bound >= max(height));
1194  // Unary
1195  if (duration.assigned()) {
1196  IntArgs durationI(n);
1197  for (int i=n; i--;)
1198  durationI[i] = duration[i].val();
1199  unshare(s,start);
1200  unary(s,start,durationI);
1201  } else {
1202  IntVarArgs end(n);
1203  for (int i=n; i--;)
1204  end[i] = expr(s,start[i]+duration[i]);
1205  unshare(s,start);
1206  unary(s,start,duration,end);
1207  }
1208  } else if (height.assigned()) {
1209  IntArgs heightI(n);
1210  for (int i=n; i--;)
1211  heightI[i] = height[i].val();
1212  if (duration.assigned()) {
1213  IntArgs durationI(n);
1214  for (int i=n; i--;)
1215  durationI[i] = duration[i].val();
1216  cumulative(s, bound, start, durationI, heightI);
1217  } else {
1218  IntVarArgs end(n);
1219  for (int i = n; i--; )
1220  end[i] = expr(s,start[i]+duration[i]);
1221  cumulative(s, bound, start, duration, end, heightI);
1222  }
1223  } else if (bound.assigned()) {
1224  IntArgs machine = IntArgs::create(n,0,0);
1225  IntArgs limit(1, bound.val());
1226  IntVarArgs end(n);
1227  for (int i=n; i--;)
1228  end[i] = expr(s,start[i]+duration[i]);
1229  cumulatives(s, machine, start, duration, end, height, limit, true,
1230  s.ann2ipl(ann));
1231  } else {
1234  IntVarArgs end(start.size());
1235  for (int i = start.size(); i--; ) {
1236  min = std::min(min, start[i].min());
1237  max = std::max(max, start[i].max() + duration[i].max());
1238  end[i] = expr(s, start[i] + duration[i]);
1239  }
1240  for (int time = min; time < max; ++time) {
1241  IntVarArgs x(start.size());
1242  for (int i = start.size(); i--; ) {
1243  IntVar overlaps = channel(s, expr(s, (start[i] <= time) &&
1244  (time < end[i])));
1245  x[i] = expr(s, overlaps * height[i]);
1246  }
1247  linear(s, x, IRT_LQ, bound);
1248  }
1249  }
1250  }
1251 
1252  void p_among_seq_int(FlatZincSpace& s, const ConExpr& ce,
1253  AST::Node* ann) {
1254  IntVarArgs x = s.arg2intvarargs(ce[0]);
1255  IntSet S = s.arg2intset(ce[1]);
1256  int q = ce[2]->getInt();
1257  int l = ce[3]->getInt();
1258  int u = ce[4]->getInt();
1259  unshare(s, x);
1260  sequence(s, x, S, q, l, u, s.ann2ipl(ann));
1261  }
1262 
1263  void p_among_seq_bool(FlatZincSpace& s, const ConExpr& ce,
1264  AST::Node* ann) {
1265  BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1266  bool val = ce[1]->getBool();
1267  int q = ce[2]->getInt();
1268  int l = ce[3]->getInt();
1269  int u = ce[4]->getInt();
1270  IntSet S(val, val);
1271  unshare(s, x);
1272  sequence(s, x, S, q, l, u, s.ann2ipl(ann));
1273  }
1274 
1275  void p_schedule_unary(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1276  IntVarArgs x = s.arg2intvarargs(ce[0]);
1277  IntArgs p = s.arg2intargs(ce[1]);
1278  unshare(s,x);
1279  unary(s, x, p);
1280  }
1281 
1282  void p_schedule_unary_optional(FlatZincSpace& s, const ConExpr& ce,
1283  AST::Node*) {
1284  IntVarArgs x = s.arg2intvarargs(ce[0]);
1285  IntArgs p = s.arg2intargs(ce[1]);
1286  BoolVarArgs m = s.arg2boolvarargs(ce[2]);
1287  unshare(s,x);
1288  unary(s, x, p, m);
1289  }
1290 
1291  void p_circuit(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1292  int off = ce[0]->getInt();
1293  IntVarArgs xv = s.arg2intvarargs(ce[1]);
1294  unshare(s,xv);
1295  circuit(s,off,xv,s.ann2ipl(ann));
1296  }
1297  void p_circuit_cost_array(FlatZincSpace& s, const ConExpr& ce,
1298  AST::Node *ann) {
1299  IntArgs c = s.arg2intargs(ce[0]);
1300  IntVarArgs xv = s.arg2intvarargs(ce[1]);
1301  IntVarArgs yv = s.arg2intvarargs(ce[2]);
1302  IntVar z = s.arg2IntVar(ce[3]);
1303  unshare(s,xv);
1304  circuit(s,c,xv,yv,z,s.ann2ipl(ann));
1305  }
1306  void p_circuit_cost(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1307  IntArgs c = s.arg2intargs(ce[0]);
1308  IntVarArgs xv = s.arg2intvarargs(ce[1]);
1309  IntVar z = s.arg2IntVar(ce[2]);
1310  unshare(s,xv);
1311  circuit(s,c,xv,z,s.ann2ipl(ann));
1312  }
1313 
1314  void p_nooverlap(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1315  IntVarArgs x0 = s.arg2intvarargs(ce[0]);
1316  IntVarArgs w = s.arg2intvarargs(ce[1]);
1317  IntVarArgs y0 = s.arg2intvarargs(ce[2]);
1318  IntVarArgs h = s.arg2intvarargs(ce[3]);
1319  if (w.assigned() && h.assigned()) {
1320  IntArgs iw(w.size());
1321  for (int i=w.size(); i--;)
1322  iw[i] = w[i].val();
1323  IntArgs ih(h.size());
1324  for (int i=h.size(); i--;)
1325  ih[i] = h[i].val();
1326  nooverlap(s,x0,iw,y0,ih,s.ann2ipl(ann));
1327 
1328  int miny = y0[0].min();
1329  int maxy = y0[0].max();
1330  int maxdy = ih[0];
1331  for (int i=1; i<y0.size(); i++) {
1332  miny = std::min(miny,y0[i].min());
1333  maxy = std::max(maxy,y0[i].max());
1334  maxdy = std::max(maxdy,ih[i]);
1335  }
1336  int minx = x0[0].min();
1337  int maxx = x0[0].max();
1338  int maxdx = iw[0];
1339  for (int i=1; i<x0.size(); i++) {
1340  minx = std::min(minx,x0[i].min());
1341  maxx = std::max(maxx,x0[i].max());
1342  maxdx = std::max(maxdx,iw[i]);
1343  }
1344  if (miny > Int::Limits::min && maxy < Int::Limits::max) {
1345  cumulative(s,maxdy+maxy-miny,x0,iw,ih);
1346  cumulative(s,maxdx+maxx-minx,y0,ih,iw);
1347  }
1348  } else {
1349  IntVarArgs x1(x0.size()), y1(y0.size());
1350  for (int i=x0.size(); i--; )
1351  x1[i] = expr(s, x0[i] + w[i]);
1352  for (int i=y0.size(); i--; )
1353  y1[i] = expr(s, y0[i] + h[i]);
1354  nooverlap(s,x0,w,x1,y0,h,y1,s.ann2ipl(ann));
1355  }
1356  }
1357 
1358  void p_precede(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1359  IntVarArgs x = s.arg2intvarargs(ce[0]);
1360  int p_s = ce[1]->getInt();
1361  int p_t = ce[2]->getInt();
1362  precede(s,x,p_s,p_t,s.ann2ipl(ann));
1363  }
1364 
1365  void p_nvalue(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1366  IntVarArgs x = s.arg2intvarargs(ce[1]);
1367  if (ce[0]->isIntVar()) {
1368  IntVar y = s.arg2IntVar(ce[0]);
1369  nvalues(s,x,IRT_EQ,y,s.ann2ipl(ann));
1370  } else {
1371  nvalues(s,x,IRT_EQ,ce[0]->getInt(),s.ann2ipl(ann));
1372  }
1373  }
1374 
1375  void p_among(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1376  IntVarArgs x = s.arg2intvarargs(ce[1]);
1377  IntSet v = s.arg2intset(ce[2]);
1378  if (ce[0]->isIntVar()) {
1379  IntVar n = s.arg2IntVar(ce[0]);
1380  unshare(s, x);
1381  count(s,x,v,IRT_EQ,n,s.ann2ipl(ann));
1382  } else {
1383  unshare(s, x);
1384  count(s,x,v,IRT_EQ,ce[0]->getInt(),s.ann2ipl(ann));
1385  }
1386  }
1387 
1388  void p_member_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1389  IntVarArgs x = s.arg2intvarargs(ce[0]);
1390  IntVar y = s.arg2IntVar(ce[1]);
1391  member(s,x,y,s.ann2ipl(ann));
1392  }
1393  void p_member_int_reif(FlatZincSpace& s, const ConExpr& ce,
1394  AST::Node* ann) {
1395  IntVarArgs x = s.arg2intvarargs(ce[0]);
1396  IntVar y = s.arg2IntVar(ce[1]);
1397  BoolVar b = s.arg2BoolVar(ce[2]);
1398  member(s,x,y,b,s.ann2ipl(ann));
1399  }
1400  void p_member_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1401  BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1402  BoolVar y = s.arg2BoolVar(ce[1]);
1403  member(s,x,y,s.ann2ipl(ann));
1404  }
1405  void p_member_bool_reif(FlatZincSpace& s, const ConExpr& ce,
1406  AST::Node* ann) {
1407  BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1408  BoolVar y = s.arg2BoolVar(ce[1]);
1409  member(s,x,y,s.arg2BoolVar(ce[2]),s.ann2ipl(ann));
1410  }
1411 
1412  class IntPoster {
1413  public:
1414  IntPoster(void) {
1415  registry().add("all_different_int", &p_distinct);
1416  registry().add("all_different_offset", &p_distinctOffset);
1417  registry().add("all_equal_int", &p_all_equal);
1418  registry().add("int_eq", &p_int_eq);
1419  registry().add("int_ne", &p_int_ne);
1420  registry().add("int_ge", &p_int_ge);
1421  registry().add("int_gt", &p_int_gt);
1422  registry().add("int_le", &p_int_le);
1423  registry().add("int_lt", &p_int_lt);
1424  registry().add("int_eq_reif", &p_int_eq_reif);
1425  registry().add("int_ne_reif", &p_int_ne_reif);
1426  registry().add("int_ge_reif", &p_int_ge_reif);
1427  registry().add("int_gt_reif", &p_int_gt_reif);
1428  registry().add("int_le_reif", &p_int_le_reif);
1429  registry().add("int_lt_reif", &p_int_lt_reif);
1430  registry().add("int_eq_imp", &p_int_eq_imp);
1431  registry().add("int_ne_imp", &p_int_ne_imp);
1432  registry().add("int_ge_imp", &p_int_ge_imp);
1433  registry().add("int_gt_imp", &p_int_gt_imp);
1434  registry().add("int_le_imp", &p_int_le_imp);
1435  registry().add("int_lt_imp", &p_int_lt_imp);
1436  registry().add("int_lin_eq", &p_int_lin_eq);
1437  registry().add("int_lin_eq_reif", &p_int_lin_eq_reif);
1438  registry().add("int_lin_eq_imp", &p_int_lin_eq_imp);
1439  registry().add("int_lin_ne", &p_int_lin_ne);
1440  registry().add("int_lin_ne_reif", &p_int_lin_ne_reif);
1441  registry().add("int_lin_ne_imp", &p_int_lin_ne_imp);
1442  registry().add("int_lin_le", &p_int_lin_le);
1443  registry().add("int_lin_le_reif", &p_int_lin_le_reif);
1444  registry().add("int_lin_le_imp", &p_int_lin_le_imp);
1445  registry().add("int_lin_lt", &p_int_lin_lt);
1446  registry().add("int_lin_lt_reif", &p_int_lin_lt_reif);
1447  registry().add("int_lin_lt_imp", &p_int_lin_lt_imp);
1448  registry().add("int_lin_ge", &p_int_lin_ge);
1449  registry().add("int_lin_ge_reif", &p_int_lin_ge_reif);
1450  registry().add("int_lin_ge_imp", &p_int_lin_ge_imp);
1451  registry().add("int_lin_gt", &p_int_lin_gt);
1452  registry().add("int_lin_gt_reif", &p_int_lin_gt_reif);
1453  registry().add("int_lin_gt_imp", &p_int_lin_gt_imp);
1454  registry().add("int_plus", &p_int_plus);
1455  registry().add("int_minus", &p_int_minus);
1456  registry().add("int_times", &p_int_times);
1457  registry().add("int_div", &p_int_div);
1458  registry().add("int_mod", &p_int_mod);
1459  registry().add("int_min", &p_int_min);
1460  registry().add("int_max", &p_int_max);
1461  registry().add("int_abs", &p_abs);
1462  registry().add("int_negate", &p_int_negate);
1463  registry().add("bool_eq", &p_bool_eq);
1464  registry().add("bool_eq_reif", &p_bool_eq_reif);
1465  registry().add("bool_eq_imp", &p_bool_eq_imp);
1466  registry().add("bool_ne", &p_bool_ne);
1467  registry().add("bool_ne_reif", &p_bool_ne_reif);
1468  registry().add("bool_ne_imp", &p_bool_ne_imp);
1469  registry().add("bool_ge", &p_bool_ge);
1470  registry().add("bool_ge_reif", &p_bool_ge_reif);
1471  registry().add("bool_ge_imp", &p_bool_ge_imp);
1472  registry().add("bool_le", &p_bool_le);
1473  registry().add("bool_le_reif", &p_bool_le_reif);
1474  registry().add("bool_le_imp", &p_bool_le_imp);
1475  registry().add("bool_gt", &p_bool_gt);
1476  registry().add("bool_gt_reif", &p_bool_gt_reif);
1477  registry().add("bool_gt_imp", &p_bool_gt_imp);
1478  registry().add("bool_lt", &p_bool_lt);
1479  registry().add("bool_lt_reif", &p_bool_lt_reif);
1480  registry().add("bool_lt_imp", &p_bool_lt_imp);
1481  registry().add("bool_or", &p_bool_or);
1482  registry().add("bool_or_imp", &p_bool_or_imp);
1483  registry().add("bool_and", &p_bool_and);
1484  registry().add("bool_and_imp", &p_bool_and_imp);
1485  registry().add("bool_xor", &p_bool_xor);
1486  registry().add("bool_xor_imp", &p_bool_xor_imp);
1487  registry().add("array_bool_and", &p_array_bool_and);
1488  registry().add("array_bool_and_imp", &p_array_bool_and_imp);
1489  registry().add("array_bool_or", &p_array_bool_or);
1490  registry().add("array_bool_or_imp", &p_array_bool_or_imp);
1491  registry().add("array_bool_xor", &p_array_bool_xor);
1492  registry().add("array_bool_xor_imp", &p_array_bool_xor_imp);
1493  registry().add("bool_clause", &p_array_bool_clause);
1494  registry().add("bool_clause_reif", &p_array_bool_clause_reif);
1495  registry().add("bool_clause_imp", &p_array_bool_clause_imp);
1496  registry().add("bool_left_imp", &p_bool_l_imp);
1497  registry().add("bool_right_imp", &p_bool_r_imp);
1498  registry().add("bool_not", &p_bool_not);
1499  registry().add("array_int_element", &p_array_int_element);
1500  registry().add("array_var_int_element", &p_array_int_element);
1501  registry().add("array_bool_element", &p_array_bool_element);
1502  registry().add("array_var_bool_element", &p_array_bool_element);
1503  registry().add("bool2int", &p_bool2int);
1504  registry().add("int_in", &p_int_in);
1505  registry().add("int_in_reif", &p_int_in_reif);
1506  registry().add("int_in_imp", &p_int_in_imp);
1507 #ifndef GECODE_HAS_SET_VARS
1508  registry().add("set_in", &p_int_in);
1509  registry().add("set_in_reif", &p_int_in_reif);
1510  registry().add("set_in_imp", &p_int_in_imp);
1511 #endif
1512 
1513  registry().add("array_int_lt", &p_array_int_lt);
1514  registry().add("array_int_lq", &p_array_int_lq);
1515  registry().add("array_bool_lt", &p_array_bool_lt);
1516  registry().add("array_bool_lq", &p_array_bool_lq);
1517  registry().add("count", &p_count);
1518  registry().add("count_reif", &p_count_reif);
1519  registry().add("count_imp", &p_count_imp);
1520  registry().add("at_least_int", &p_at_least);
1521  registry().add("at_most_int", &p_at_most);
1522  registry().add("gecode_bin_packing_load", &p_bin_packing_load);
1523  registry().add("gecode_global_cardinality", &p_global_cardinality);
1524  registry().add("gecode_global_cardinality_closed",
1525  &p_global_cardinality_closed);
1526  registry().add("global_cardinality_low_up",
1527  &p_global_cardinality_low_up);
1528  registry().add("global_cardinality_low_up_closed",
1529  &p_global_cardinality_low_up_closed);
1530  registry().add("array_int_minimum", &p_minimum);
1531  registry().add("array_int_maximum", &p_maximum);
1532  registry().add("gecode_minimum_arg_int", &p_minimum_arg);
1533  registry().add("gecode_maximum_arg_int", &p_maximum_arg);
1534  registry().add("array_int_maximum", &p_maximum);
1535  registry().add("gecode_regular", &p_regular);
1536  registry().add("sort", &p_sort);
1537  registry().add("inverse_offsets", &p_inverse_offsets);
1538  registry().add("increasing_int", &p_increasing_int);
1539  registry().add("increasing_bool", &p_increasing_bool);
1540  registry().add("decreasing_int", &p_decreasing_int);
1541  registry().add("decreasing_bool", &p_decreasing_bool);
1542  registry().add("gecode_table_int", &p_table_int);
1543  registry().add("gecode_table_bool", &p_table_bool);
1544  registry().add("cumulatives", &p_cumulatives);
1545  registry().add("gecode_among_seq_int", &p_among_seq_int);
1546  registry().add("gecode_among_seq_bool", &p_among_seq_bool);
1547 
1548  registry().add("bool_lin_eq", &p_bool_lin_eq);
1549  registry().add("bool_lin_ne", &p_bool_lin_ne);
1550  registry().add("bool_lin_le", &p_bool_lin_le);
1551  registry().add("bool_lin_lt", &p_bool_lin_lt);
1552  registry().add("bool_lin_ge", &p_bool_lin_ge);
1553  registry().add("bool_lin_gt", &p_bool_lin_gt);
1554 
1555  registry().add("bool_lin_eq_reif", &p_bool_lin_eq_reif);
1556  registry().add("bool_lin_eq_imp", &p_bool_lin_eq_imp);
1557  registry().add("bool_lin_ne_reif", &p_bool_lin_ne_reif);
1558  registry().add("bool_lin_ne_imp", &p_bool_lin_ne_imp);
1559  registry().add("bool_lin_le_reif", &p_bool_lin_le_reif);
1560  registry().add("bool_lin_le_imp", &p_bool_lin_le_imp);
1561  registry().add("bool_lin_lt_reif", &p_bool_lin_lt_reif);
1562  registry().add("bool_lin_lt_imp", &p_bool_lin_lt_imp);
1563  registry().add("bool_lin_ge_reif", &p_bool_lin_ge_reif);
1564  registry().add("bool_lin_ge_imp", &p_bool_lin_ge_imp);
1565  registry().add("bool_lin_gt_reif", &p_bool_lin_gt_reif);
1566  registry().add("bool_lin_gt_imp", &p_bool_lin_gt_imp);
1567 
1568  registry().add("gecode_schedule_unary", &p_schedule_unary);
1569  registry().add("gecode_schedule_unary_optional", &p_schedule_unary_optional);
1570  registry().add("gecode_schedule_cumulative_optional", &p_cumulative_opt);
1571 
1572  registry().add("gecode_circuit", &p_circuit);
1573  registry().add("gecode_circuit_cost_array", &p_circuit_cost_array);
1574  registry().add("gecode_circuit_cost", &p_circuit_cost);
1575  registry().add("gecode_nooverlap", &p_nooverlap);
1576  registry().add("gecode_precede", &p_precede);
1577  registry().add("nvalue",&p_nvalue);
1578  registry().add("among",&p_among);
1579  registry().add("member_int",&p_member_int);
1580  registry().add("gecode_member_int_reif",&p_member_int_reif);
1581  registry().add("member_bool",&p_member_bool);
1582  registry().add("gecode_member_bool_reif",&p_member_bool_reif);
1583  }
1584  };
1585  IntPoster __int_poster;
1586 
1587 #ifdef GECODE_HAS_SET_VARS
1588  void p_set_OP(FlatZincSpace& s, SetOpType op,
1589  const ConExpr& ce, AST::Node *) {
1590  rel(s, s.arg2SetVar(ce[0]), op, s.arg2SetVar(ce[1]),
1591  SRT_EQ, s.arg2SetVar(ce[2]));
1592  }
1593  void p_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1594  p_set_OP(s, SOT_UNION, ce, ann);
1595  }
1596  void p_set_intersect(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1597  p_set_OP(s, SOT_INTER, ce, ann);
1598  }
1599  void p_set_diff(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1600  p_set_OP(s, SOT_MINUS, ce, ann);
1601  }
1602 
1603  void p_set_symdiff(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1604  SetVar x = s.arg2SetVar(ce[0]);
1605  SetVar y = s.arg2SetVar(ce[1]);
1606 
1607  SetVarLubRanges xub(x);
1608  IntSet xubs(xub);
1609  SetVar x_y(s,IntSet::empty,xubs);
1610  rel(s, x, SOT_MINUS, y, SRT_EQ, x_y);
1611 
1612  SetVarLubRanges yub(y);
1613  IntSet yubs(yub);
1614  SetVar y_x(s,IntSet::empty,yubs);
1615  rel(s, y, SOT_MINUS, x, SRT_EQ, y_x);
1616 
1617  rel(s, x_y, SOT_UNION, y_x, SRT_EQ, s.arg2SetVar(ce[2]));
1618  }
1619 
1620  void p_array_set_OP(FlatZincSpace& s, SetOpType op,
1621  const ConExpr& ce, AST::Node *) {
1622  SetVarArgs xs = s.arg2setvarargs(ce[0]);
1623  rel(s, op, xs, s.arg2SetVar(ce[1]));
1624  }
1625  void p_array_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1626  p_array_set_OP(s, SOT_UNION, ce, ann);
1627  }
1628  void p_array_set_partition(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
1629  p_array_set_OP(s, SOT_DUNION, ce, ann);
1630  }
1631 
1632 
1633  void p_set_rel(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
1634  rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]));
1635  }
1636 
1637  void p_set_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1638  p_set_rel(s, SRT_EQ, ce);
1639  }
1640  void p_set_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1641  p_set_rel(s, SRT_NQ, ce);
1642  }
1643  void p_set_subset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1644  p_set_rel(s, SRT_SUB, ce);
1645  }
1646  void p_set_superset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1647  p_set_rel(s, SRT_SUP, ce);
1648  }
1649  void p_set_le(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1650  p_set_rel(s, SRT_LQ, ce);
1651  }
1652  void p_set_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1653  p_set_rel(s, SRT_LE, ce);
1654  }
1655  void p_set_card(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1656  if (!ce[1]->isIntVar()) {
1657  cardinality(s, s.arg2SetVar(ce[0]), ce[1]->getInt(),
1658  ce[1]->getInt());
1659  } else {
1660  cardinality(s, s.arg2SetVar(ce[0]), s.arg2IntVar(ce[1]));
1661  }
1662  }
1663  void p_set_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1664  if (!ce[1]->isSetVar()) {
1665  IntSet d = s.arg2intset(ce[1]);
1666  if (ce[0]->isBoolVar()) {
1667  IntSetRanges dr(d);
1668  Iter::Ranges::Singleton sr(0,1);
1669  Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
1670  IntSet d01(i);
1671  if (d01.size() == 0) {
1672  s.fail();
1673  } else {
1674  rel(s, s.arg2BoolVar(ce[0]), IRT_GQ, d01.min());
1675  rel(s, s.arg2BoolVar(ce[0]), IRT_LQ, d01.max());
1676  }
1677  } else {
1678  dom(s, s.arg2IntVar(ce[0]), d);
1679  }
1680  } else {
1681  if (!ce[0]->isIntVar()) {
1682  dom(s, s.arg2SetVar(ce[1]), SRT_SUP, ce[0]->getInt());
1683  } else {
1684  rel(s, s.arg2SetVar(ce[1]), SRT_SUP, s.arg2IntVar(ce[0]));
1685  }
1686  }
1687  }
1688  void p_set_rel_reif(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
1689  rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]),
1690  s.arg2BoolVar(ce[2]));
1691  }
1692 
1693  void p_set_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1694  p_set_rel_reif(s,SRT_EQ,ce);
1695  }
1696  void p_set_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1697  p_set_rel_reif(s,SRT_LQ,ce);
1698  }
1699  void p_set_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1700  p_set_rel_reif(s,SRT_LE,ce);
1701  }
1702  void p_set_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1703  p_set_rel_reif(s,SRT_NQ,ce);
1704  }
1705  void p_set_subset_reif(FlatZincSpace& s, const ConExpr& ce,
1706  AST::Node *) {
1707  p_set_rel_reif(s,SRT_SUB,ce);
1708  }
1709  void p_set_superset_reif(FlatZincSpace& s, const ConExpr& ce,
1710  AST::Node *) {
1711  p_set_rel_reif(s,SRT_SUP,ce);
1712  }
1713  void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann, ReifyMode rm) {
1714  if (!ce[1]->isSetVar()) {
1715  if (rm==RM_EQV) {
1716  p_int_in_reif(s,ce,ann);
1717  } else {
1718  assert(rm==RM_IMP);
1719  p_int_in_imp(s,ce,ann);
1720  }
1721  } else {
1722  if (!ce[0]->isIntVar()) {
1723  dom(s, s.arg2SetVar(ce[1]), SRT_SUP, ce[0]->getInt(),
1724  Reify(s.arg2BoolVar(ce[2]),rm));
1725  } else {
1726  rel(s, s.arg2SetVar(ce[1]), SRT_SUP, s.arg2IntVar(ce[0]),
1727  Reify(s.arg2BoolVar(ce[2]),rm));
1728  }
1729  }
1730  }
1731  void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1732  p_set_in_reif(s,ce,ann,RM_EQV);
1733  }
1734  void p_set_in_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1735  p_set_in_reif(s,ce,ann,RM_IMP);
1736  }
1737  void p_set_disjoint(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1738  rel(s, s.arg2SetVar(ce[0]), SRT_DISJ, s.arg2SetVar(ce[1]));
1739  }
1740 
1741  void p_link_set_to_booleans(FlatZincSpace& s, const ConExpr& ce,
1742  AST::Node *) {
1743  SetVar x = s.arg2SetVar(ce[0]);
1744  int idx = ce[2]->getInt();
1745  assert(idx >= 0);
1746  rel(s, x || IntSet(Set::Limits::min,idx-1));
1747  BoolVarArgs y = s.arg2boolvarargs(ce[1],idx);
1748  unshare(s, y);
1749  channel(s, y, x);
1750  }
1751 
1752  void p_array_set_element(FlatZincSpace& s, const ConExpr& ce,
1753  AST::Node*) {
1754  bool isConstant = true;
1755  AST::Array* a = ce[1]->getArray();
1756  for (int i=a->a.size(); i--;) {
1757  if (a->a[i]->isSetVar()) {
1758  isConstant = false;
1759  break;
1760  }
1761  }
1762  IntVar selector = s.arg2IntVar(ce[0]);
1763  rel(s, selector > 0);
1764  if (isConstant) {
1765  IntSetArgs sv = s.arg2intsetargs(ce[1],1);
1766  element(s, sv, selector, s.arg2SetVar(ce[2]));
1767  } else {
1768  SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
1769  element(s, sv, selector, s.arg2SetVar(ce[2]));
1770  }
1771  }
1772 
1773  void p_array_set_element_op(FlatZincSpace& s, const ConExpr& ce,
1774  AST::Node*, SetOpType op,
1775  const IntSet& universe =
1777  bool isConstant = true;
1778  AST::Array* a = ce[1]->getArray();
1779  for (int i=a->a.size(); i--;) {
1780  if (a->a[i]->isSetVar()) {
1781  isConstant = false;
1782  break;
1783  }
1784  }
1785  SetVar selector = s.arg2SetVar(ce[0]);
1786  dom(s, selector, SRT_DISJ, 0);
1787  if (isConstant) {
1788  IntSetArgs sv = s.arg2intsetargs(ce[1], 1);
1789  element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
1790  } else {
1791  SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
1792  element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
1793  }
1794  }
1795 
1796  void p_array_set_element_union(FlatZincSpace& s, const ConExpr& ce,
1797  AST::Node* ann) {
1798  p_array_set_element_op(s, ce, ann, SOT_UNION);
1799  }
1800 
1801  void p_array_set_element_intersect(FlatZincSpace& s, const ConExpr& ce,
1802  AST::Node* ann) {
1803  p_array_set_element_op(s, ce, ann, SOT_INTER);
1804  }
1805 
1806  void p_array_set_element_intersect_in(FlatZincSpace& s,
1807  const ConExpr& ce,
1808  AST::Node* ann) {
1809  IntSet d = s.arg2intset(ce[3]);
1810  p_array_set_element_op(s, ce, ann, SOT_INTER, d);
1811  }
1812 
1813  void p_array_set_element_partition(FlatZincSpace& s, const ConExpr& ce,
1814  AST::Node* ann) {
1815  p_array_set_element_op(s, ce, ann, SOT_DUNION);
1816  }
1817 
1818  void p_set_convex(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1819  convex(s, s.arg2SetVar(ce[0]));
1820  }
1821 
1822  void p_array_set_seq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
1823  SetVarArgs sv = s.arg2setvarargs(ce[0]);
1824  sequence(s, sv);
1825  }
1826 
1827  void p_array_set_seq_union(FlatZincSpace& s, const ConExpr& ce,
1828  AST::Node *) {
1829  SetVarArgs sv = s.arg2setvarargs(ce[0]);
1830  sequence(s, sv, s.arg2SetVar(ce[1]));
1831  }
1832 
1833  void p_int_set_channel(FlatZincSpace& s, const ConExpr& ce,
1834  AST::Node *) {
1835  int xoff=ce[1]->getInt();
1836  assert(xoff >= 0);
1837  int yoff=ce[3]->getInt();
1838  assert(yoff >= 0);
1839  IntVarArgs xv = s.arg2intvarargs(ce[0], xoff);
1840  SetVarArgs yv = s.arg2setvarargs(ce[2], yoff, 1, IntSet(0, xoff-1));
1841  IntSet xd(yoff,yv.size()-1);
1842  for (int i=xoff; i<xv.size(); i++) {
1843  dom(s, xv[i], xd);
1844  }
1845  IntSet yd(xoff,xv.size()-1);
1846  for (int i=yoff; i<yv.size(); i++) {
1847  dom(s, yv[i], SRT_SUB, yd);
1848  }
1849  channel(s,xv,yv);
1850  }
1851 
1852  void p_range(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1853  int xoff=ce[1]->getInt();
1854  assert(xoff >= 0);
1855  IntVarArgs xv = s.arg2intvarargs(ce[0],xoff);
1856  element(s, SOT_UNION, xv, s.arg2SetVar(ce[2]), s.arg2SetVar(ce[3]));
1857  }
1858 
1859  void p_weights(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1860  IntArgs e = s.arg2intargs(ce[0]);
1861  IntArgs w = s.arg2intargs(ce[1]);
1862  SetVar x = s.arg2SetVar(ce[2]);
1863  IntVar y = s.arg2IntVar(ce[3]);
1864  weights(s,e,w,x,y);
1865  }
1866 
1867  void p_inverse_set(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1868  int xoff = ce[2]->getInt();
1869  int yoff = ce[3]->getInt();
1870  SetVarArgs x = s.arg2setvarargs(ce[0],xoff);
1871  SetVarArgs y = s.arg2setvarargs(ce[1],yoff);
1872  channel(s, x, y);
1873  }
1874 
1875  void p_precede_set(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1876  SetVarArgs x = s.arg2setvarargs(ce[0]);
1877  int p_s = ce[1]->getInt();
1878  int p_t = ce[2]->getInt();
1879  precede(s,x,p_s,p_t);
1880  }
1881 
1882  class SetPoster {
1883  public:
1884  SetPoster(void) {
1885  registry().add("set_eq", &p_set_eq);
1886  registry().add("set_le", &p_set_le);
1887  registry().add("set_lt", &p_set_lt);
1888  registry().add("equal", &p_set_eq);
1889  registry().add("set_ne", &p_set_ne);
1890  registry().add("set_union", &p_set_union);
1891  registry().add("array_set_element", &p_array_set_element);
1892  registry().add("array_var_set_element", &p_array_set_element);
1893  registry().add("set_intersect", &p_set_intersect);
1894  registry().add("set_diff", &p_set_diff);
1895  registry().add("set_symdiff", &p_set_symdiff);
1896  registry().add("set_subset", &p_set_subset);
1897  registry().add("set_superset", &p_set_superset);
1898  registry().add("set_card", &p_set_card);
1899  registry().add("set_in", &p_set_in);
1900  registry().add("set_eq_reif", &p_set_eq_reif);
1901  registry().add("set_le_reif", &p_set_le_reif);
1902  registry().add("set_lt_reif", &p_set_lt_reif);
1903  registry().add("equal_reif", &p_set_eq_reif);
1904  registry().add("set_ne_reif", &p_set_ne_reif);
1905  registry().add("set_subset_reif", &p_set_subset_reif);
1906  registry().add("set_superset_reif", &p_set_superset_reif);
1907  registry().add("set_in_reif", &p_set_in_reif);
1908  registry().add("set_in_imp", &p_set_in_imp);
1909  registry().add("disjoint", &p_set_disjoint);
1910  registry().add("gecode_link_set_to_booleans",
1911  &p_link_set_to_booleans);
1912 
1913  registry().add("array_set_union", &p_array_set_union);
1914  registry().add("array_set_partition", &p_array_set_partition);
1915  registry().add("set_convex", &p_set_convex);
1916  registry().add("array_set_seq", &p_array_set_seq);
1917  registry().add("array_set_seq_union", &p_array_set_seq_union);
1918  registry().add("gecode_array_set_element_union",
1919  &p_array_set_element_union);
1920  registry().add("gecode_array_set_element_intersect",
1921  &p_array_set_element_intersect);
1922  registry().add("gecode_array_set_element_intersect_in",
1923  &p_array_set_element_intersect_in);
1924  registry().add("gecode_array_set_element_partition",
1925  &p_array_set_element_partition);
1926  registry().add("gecode_int_set_channel",
1927  &p_int_set_channel);
1928  registry().add("gecode_range",
1929  &p_range);
1930  registry().add("gecode_set_weights",
1931  &p_weights);
1932  registry().add("gecode_inverse_set", &p_inverse_set);
1933  registry().add("gecode_precede_set", &p_precede_set);
1934  }
1935  };
1936  SetPoster __set_poster;
1937 #endif
1938 
1939 #ifdef GECODE_HAS_FLOAT_VARS
1940 
1941  void p_int2float(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1942  IntVar x0 = s.arg2IntVar(ce[0]);
1943  FloatVar x1 = s.arg2FloatVar(ce[1]);
1944  channel(s, x0, x1);
1945  }
1946 
1947  void p_float_lin_cmp(FlatZincSpace& s, FloatRelType frt,
1948  const ConExpr& ce, AST::Node*) {
1949  FloatValArgs fa = s.arg2floatargs(ce[0]);
1950  FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
1951  linear(s, fa, fv, frt, ce[2]->getFloat());
1952  }
1953  void p_float_lin_cmp_reif(FlatZincSpace& s, FloatRelType frt,
1954  const ConExpr& ce, AST::Node*) {
1955  FloatValArgs fa = s.arg2floatargs(ce[0]);
1956  FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
1957  linear(s, fa, fv, frt, ce[2]->getFloat(), s.arg2BoolVar(ce[3]));
1958  }
1959  void p_float_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1960  p_float_lin_cmp(s,FRT_EQ,ce,ann);
1961  }
1962  void p_float_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce,
1963  AST::Node* ann) {
1964  p_float_lin_cmp_reif(s,FRT_EQ,ce,ann);
1965  }
1966  void p_float_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1967  p_float_lin_cmp(s,FRT_LQ,ce,ann);
1968  }
1969  void p_float_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
1970  p_float_lin_cmp(s,FRT_LE,ce,ann);
1971  }
1972  void p_float_lin_le_reif(FlatZincSpace& s, const ConExpr& ce,
1973  AST::Node* ann) {
1974  p_float_lin_cmp_reif(s,FRT_LQ,ce,ann);
1975  }
1976  void p_float_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce,
1977  AST::Node* ann) {
1978  p_float_lin_cmp_reif(s,FRT_LE,ce,ann);
1979  }
1980 
1981  void p_float_times(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1982  FloatVar x = s.arg2FloatVar(ce[0]);
1983  FloatVar y = s.arg2FloatVar(ce[1]);
1984  FloatVar z = s.arg2FloatVar(ce[2]);
1985  mult(s,x,y,z);
1986  }
1987 
1988  void p_float_div(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1989  FloatVar x = s.arg2FloatVar(ce[0]);
1990  FloatVar y = s.arg2FloatVar(ce[1]);
1991  FloatVar z = s.arg2FloatVar(ce[2]);
1992  div(s,x,y,z);
1993  }
1994 
1995  void p_float_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
1996  FloatVar x = s.arg2FloatVar(ce[0]);
1997  FloatVar y = s.arg2FloatVar(ce[1]);
1998  FloatVar z = s.arg2FloatVar(ce[2]);
1999  rel(s,x+y==z);
2000  }
2001 
2002  void p_float_sqrt(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2003  FloatVar x = s.arg2FloatVar(ce[0]);
2004  FloatVar y = s.arg2FloatVar(ce[1]);
2005  sqrt(s,x,y);
2006  }
2007 
2008  void p_float_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2009  FloatVar x = s.arg2FloatVar(ce[0]);
2010  FloatVar y = s.arg2FloatVar(ce[1]);
2011  abs(s,x,y);
2012  }
2013 
2014  void p_float_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2015  FloatVar x = s.arg2FloatVar(ce[0]);
2016  FloatVar y = s.arg2FloatVar(ce[1]);
2017  rel(s,x,FRT_EQ,y);
2018  }
2019  void p_float_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2020  FloatVar x = s.arg2FloatVar(ce[0]);
2021  FloatVar y = s.arg2FloatVar(ce[1]);
2022  BoolVar b = s.arg2BoolVar(ce[2]);
2023  rel(s,x,FRT_EQ,y,b);
2024  }
2025  void p_float_le(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2026  FloatVar x = s.arg2FloatVar(ce[0]);
2027  FloatVar y = s.arg2FloatVar(ce[1]);
2028  rel(s,x,FRT_LQ,y);
2029  }
2030  void p_float_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2031  FloatVar x = s.arg2FloatVar(ce[0]);
2032  FloatVar y = s.arg2FloatVar(ce[1]);
2033  BoolVar b = s.arg2BoolVar(ce[2]);
2034  rel(s,x,FRT_LQ,y,b);
2035  }
2036  void p_float_max(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2037  FloatVar x = s.arg2FloatVar(ce[0]);
2038  FloatVar y = s.arg2FloatVar(ce[1]);
2039  FloatVar z = s.arg2FloatVar(ce[2]);
2040  max(s,x,y,z);
2041  }
2042  void p_float_min(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2043  FloatVar x = s.arg2FloatVar(ce[0]);
2044  FloatVar y = s.arg2FloatVar(ce[1]);
2045  FloatVar z = s.arg2FloatVar(ce[2]);
2046  min(s,x,y,z);
2047  }
2048  void p_float_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2049  FloatVar x = s.arg2FloatVar(ce[0]);
2050  FloatVar y = s.arg2FloatVar(ce[1]);
2051  rel(s, x, FRT_LQ, y);
2052  rel(s, x, FRT_EQ, y, BoolVar(s,0,0));
2053  }
2054 
2055  void p_float_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2056  FloatVar x = s.arg2FloatVar(ce[0]);
2057  FloatVar y = s.arg2FloatVar(ce[1]);
2058  BoolVar b = s.arg2BoolVar(ce[2]);
2059  BoolVar b0(s,0,1);
2060  BoolVar b1(s,0,1);
2061  rel(s, b == (b0 && !b1));
2062  rel(s, x, FRT_LQ, y, b0);
2063  rel(s, x, FRT_EQ, y, b1);
2064  }
2065 
2066  void p_float_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2067  FloatVar x = s.arg2FloatVar(ce[0]);
2068  FloatVar y = s.arg2FloatVar(ce[1]);
2069  rel(s, x, FRT_EQ, y, BoolVar(s,0,0));
2070  }
2071 
2072 #ifdef GECODE_HAS_MPFR
2073 #define P_FLOAT_OP(Op) \
2074  void p_float_ ## Op (FlatZincSpace& s, const ConExpr& ce, AST::Node*) {\
2075  FloatVar x = s.arg2FloatVar(ce[0]);\
2076  FloatVar y = s.arg2FloatVar(ce[1]);\
2077  Op(s,x,y);\
2078  }
2079  P_FLOAT_OP(acos)
2080  P_FLOAT_OP(asin)
2081  P_FLOAT_OP(atan)
2082  P_FLOAT_OP(cos)
2083  P_FLOAT_OP(exp)
2084  P_FLOAT_OP(sin)
2085  P_FLOAT_OP(tan)
2086  // P_FLOAT_OP(sinh)
2087  // P_FLOAT_OP(tanh)
2088  // P_FLOAT_OP(cosh)
2089 #undef P_FLOAT_OP
2090 
2091  void p_float_ln(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2092  FloatVar x = s.arg2FloatVar(ce[0]);
2093  FloatVar y = s.arg2FloatVar(ce[1]);
2094  log(s,x,y);
2095  }
2096  void p_float_log10(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2097  FloatVar x = s.arg2FloatVar(ce[0]);
2098  FloatVar y = s.arg2FloatVar(ce[1]);
2099  log(s,10.0,x,y);
2100  }
2101  void p_float_log2(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
2102  FloatVar x = s.arg2FloatVar(ce[0]);
2103  FloatVar y = s.arg2FloatVar(ce[1]);
2104  log(s,2.0,x,y);
2105  }
2106 
2107 #endif
2108 
2109  class FloatPoster {
2110  public:
2111  FloatPoster(void) {
2112  registry().add("int2float",&p_int2float);
2113  registry().add("float_abs",&p_float_abs);
2114  registry().add("float_sqrt",&p_float_sqrt);
2115  registry().add("float_eq",&p_float_eq);
2116  registry().add("float_eq_reif",&p_float_eq_reif);
2117  registry().add("float_le",&p_float_le);
2118  registry().add("float_le_reif",&p_float_le_reif);
2119  registry().add("float_lt",&p_float_lt);
2120  registry().add("float_lt_reif",&p_float_lt_reif);
2121  registry().add("float_ne",&p_float_ne);
2122  registry().add("float_times",&p_float_times);
2123  registry().add("float_div",&p_float_div);
2124  registry().add("float_plus",&p_float_plus);
2125  registry().add("float_max",&p_float_max);
2126  registry().add("float_min",&p_float_min);
2127 
2128  registry().add("float_lin_eq",&p_float_lin_eq);
2129  registry().add("float_lin_eq_reif",&p_float_lin_eq_reif);
2130  registry().add("float_lin_le",&p_float_lin_le);
2131  registry().add("float_lin_lt",&p_float_lin_lt);
2132  registry().add("float_lin_le_reif",&p_float_lin_le_reif);
2133  registry().add("float_lin_lt_reif",&p_float_lin_lt_reif);
2134 
2135 #ifdef GECODE_HAS_MPFR
2136  registry().add("float_acos",&p_float_acos);
2137  registry().add("float_asin",&p_float_asin);
2138  registry().add("float_atan",&p_float_atan);
2139  registry().add("float_cos",&p_float_cos);
2140  // registry().add("float_cosh",&p_float_cosh);
2141  registry().add("float_exp",&p_float_exp);
2142  registry().add("float_ln",&p_float_ln);
2143  registry().add("float_log10",&p_float_log10);
2144  registry().add("float_log2",&p_float_log2);
2145  registry().add("float_sin",&p_float_sin);
2146  // registry().add("float_sinh",&p_float_sinh);
2147  registry().add("float_tan",&p_float_tan);
2148  // registry().add("float_tanh",&p_float_tanh);
2149 #endif
2150  }
2151  } __float_poster;
2152 #endif
2153 
2154  }
2155 }}
2156 
2157 // STATISTICS: flatzinc-any
Bounds propagation.
Definition: int.hh:959
void mod(Home home, IntVar x0, IntVar x1, IntVar x2, IntPropLevel ipl)
Post propagator for .
Definition: arithmetic.cpp:267
static IntArgs create(int n, int start, int inc=1)
Allocate array with n elements such that for all .
Definition: array.hpp:72
Post propagator for SetVar SetOpType op
Definition: set.hh:784
NodeType t
Type of node.
Definition: bool-expr.cpp:234
SetRelType
Common relation types for sets.
Definition: set.hh:645
void mult(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:92
void post(FlatZincSpace &s, const ConExpr &ce)
Post constraint specified by ce.
Definition: registry.cpp:63
NNF * l
Left subtree.
Definition: bool-expr.cpp:244
void sorted(Home home, const IntVarArgs &x, const IntVarArgs &y, const IntVarArgs &z, IntPropLevel)
Post propagator that y is x sorted in increasing order.
Definition: sorted.cpp:43
int size(void) const
Return size of array (number of elements)
Definition: array.hpp:1669
union Gecode::@579::NNF::@61 u
Union depending on nodetype t.
const int min
Smallest allowed integer in integer set.
Definition: set.hh:103
Map from constraint identifier to constraint posting functions.
Definition: registry.hh:48
void sequence(Home home, const IntVarArgs &x, const IntSet &s, int q, int l, int u, IntPropLevel)
Post propagator for .
Definition: sequence.cpp:51
void log(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void channel(Home home, FloatVar x0, IntVar x1)
Post propagator for channeling a float and an integer variable .
Definition: channel.cpp:45
const FloatNum max
Largest allowed float value.
Definition: float.hh:848
void count(Home home, const IntVarArgs &x, int n, IntRelType irt, int m, IntPropLevel)
Post propagator for .
Definition: count.cpp:44
Less or equal ( )
Definition: float.hh:1072
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:53
void abs(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition: arithmetic.cpp:45
Less or equal ( )
Definition: int.hh:909
Conjunction.
Definition: int.hh:932
void member(Home home, const IntVarArgs &x, IntVar y, IntPropLevel)
Post domain consistent propagator for .
Definition: member.cpp:43
void dom(Home home, FloatVar x, FloatVal n)
Propagates .
Definition: dom.cpp:44
void linear(Home home, const FloatVarArgs &x, FloatRelType frt, FloatVal c)
Post propagator for .
Definition: linear.cpp:45
Implication.
Definition: int.hh:934
void circuit(Home home, int offset, const IntVarArgs &x, IntPropLevel ipl)
Post propagator such that x forms a circuit.
Definition: circuit.cpp:45
void argmin(Home home, const IntVarArgs &x, IntVar y, bool tiebreak, IntPropLevel)
Post propagator for .
Definition: arithmetic.cpp:167
Less ( )
Definition: float.hh:1073
SetOpType
Common operations for sets.
Definition: set.hh:662
Greater ( )
Definition: int.hh:912
Superset ( )
Definition: set.hh:649
void binpacking(Home home, const IntVarArgs &l, const IntVarArgs &b, const IntArgs &s, IntPropLevel)
Post propagator for bin packing.
Definition: bin-packing.cpp:45
const int max
Largest allowed integer in integer set.
Definition: set.hh:101
ArgArray< IntSet > IntSetArgs
Passing set arguments.
Definition: int.hh:601
const int max
Largest allowed integer value.
Definition: int.hh:116
Greater or equal ( )
Definition: int.hh:911
Difference.
Definition: set.hh:666
Exclusive or.
Definition: int.hh:936
const int min
Smallest allowed integer value.
Definition: int.hh:118
Gecode::IntSet d(v, 7)
struct Gecode::@579::NNF::@61::@63 a
For atomic nodes.
Gecode::FloatVal c(-8, 8)
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:236
const FloatNum min
Smallest allowed float value.
Definition: float.hh:850
Gecode::IntArgs i(4, 1, 2, 3, 4)
IntRelType neg(IntRelType irt)
Return negated relation type of irt.
Definition: irt.hpp:56
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:238
Equality ( )
Definition: int.hh:907
void unshare(Home home, IntVarArgs &x, IntPropLevel ipl)
Replace multiple variable occurences in x by fresh variables.
Definition: unshare.cpp:133
Options opt
The options.
Definition: test.cpp:101
IntPropLevel ann2ipl(AST::Node *ann)
Convert ann to integer propagation level.
Definition: flatzinc.cpp:2162
void nvalues(Home home, const IntVarArgs &x, IntRelType irt, int y, IntPropLevel)
Post propagator for .
Definition: nvalues.cpp:44
IntRelType
Relation types for integers.
Definition: int.hh:906
FloatRelType
Relation types for floats.
Definition: float.hh:1069
Less or equal ( )
Definition: set.hh:652
Simple propagation levels.
Definition: int.hh:957
void extensional(Home home, const IntVarArgs &x, DFA dfa, IntPropLevel)
Post domain consistent propagator for extensional constraint described by a DFA.
Definition: extensional.cpp:45
void sqrt(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Definition: arithmetic.cpp:106
struct Gecode::@579::NNF::@61::@62 b
For binary nodes (and, or, eqv)
void distinct(Home home, const IntVarArgs &x, IntPropLevel ipl)
Post propagator for for all .
Definition: distinct.cpp:50
Subset ( )
Definition: set.hh:648
void argmax(Home home, const IntVarArgs &x, IntVar y, bool tiebreak, IntPropLevel)
Post propagator for .
Definition: arithmetic.cpp:114
#define BOOL_OP(op)
Definition: registry.cpp:562
Intersection
Definition: set.hh:665
Less ( )
Definition: int.hh:910
Post propagator for SetVar SetOpType SetVar SetRelType SetVar z
Definition: set.hh:784
Less ( )
Definition: set.hh:653
Disjunction.
Definition: int.hh:933
IntVarArgs arg2intvarargs(AST::Node *arg, int offset=0)
Convert arg to IntVarArgs.
Definition: flatzinc.cpp:2003
void convex(Home home, SetVar x)
Definition: convex.cpp:45
void asin(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
AST::Array * ann
Constraint annotations.
Definition: conexpr.hh:54
Passing integer variables.
Definition: int.hh:639
Passing integer arguments.
Definition: int.hh:610
Equality ( )
Definition: float.hh:1070
static const IntSet empty
Empty set.
Definition: int.hh:265
BoolVar expr(Home home, const BoolExpr &e, IntPropLevel ipl)
Post Boolean expression and return its value.
Definition: bool-expr.cpp:632
void nooverlap(Home home, const IntVarArgs &x, const IntArgs &w, const IntVarArgs &y, const IntArgs &h, IntPropLevel)
Post propagator for rectangle packing.
Definition: no-overlap.cpp:55
LinIntExpr cardinality(const SetExpr &e)
Cardinality of set expression.
Definition: set-expr.cpp:818
Post propagator for SetVar SetOpType SetVar SetRelType r
Definition: set.hh:784
const int v[7]
Definition: distinct.cpp:263
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:71
void cos(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
IntPropLevel
Propagation levels for integer propagators.
Definition: int.hh:955
Union.
Definition: set.hh:663
Post propagator for f(x \diamond_{\mathit{op}} y) \sim_r z \f$ void rel(Home home
Post propagator for SetVar SetOpType SetVar y
Definition: set.hh:784
void div(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:131
void tan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
Disjoint union.
Definition: set.hh:664
void precede(Home home, const IntVarArgs &x, int s, int t, IntPropLevel)
Post propagator that s precedes t in x.
Definition: precede.cpp:47
void rel(Home home, FloatVar x0, FloatRelType frt, FloatVal n)
Propagates .
Definition: rel.cpp:47
Exception class for FlatZinc errors
Definition: flatzinc.hh:626
Domain propagation Preferences: prefer speed or memory.
Definition: int.hh:960
Equality ( )
Definition: set.hh:646
Disjoint ( )
Definition: set.hh:650
Post propagator for SetVar x
Definition: set.hh:784
void add(const std::string &id, poster p)
Add posting function p with identifier id.
Definition: registry.cpp:73
#define BOOL_ARRAY_OP(op)
Definition: registry.cpp:571
A space that can be initialized with a FlatZinc model.
Definition: flatzinc.hh:401
Disequality ( )
Definition: set.hh:647
Gecode toplevel namespace
void weights(Home home, IntSharedArray elements, IntSharedArray weights, SetVar x, IntVar y)
Definition: int.cpp:296
Implication for reification.
Definition: int.hh:843
void sin(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
A node in a FlatZinc abstract syntax tree.
Definition: ast.hh:71
Disequality ( )
Definition: int.hh:908
void acos(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void exp(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
void cumulative(Home home, int c, const TaskTypeArgs &t, const IntVarArgs &s, const IntArgs &p, const IntArgs &u, IntPropLevel ipl)
Post propagators for scheduling tasks on cumulative resources.
Definition: cumulative.cpp:357
ReifyMode
Mode for reification.
Definition: int.hh:829
void unary(Home home, const IntVarArgs &s, const IntArgs &p, IntPropLevel ipl)
Post propagators for scheduling tasks on unary resources.
Definition: unary.cpp:48
#define P_FLOAT_OP(Op)
Definition: registry.cpp:2073
void element(Home home, IntSharedArray c, IntVar x0, IntVar x1, IntPropLevel)
Post domain consistent propagator for .
Definition: element.cpp:43
Registry & registry(void)
Return global registry object.
Definition: registry.cpp:57
void atan(Home home, FloatVar x0, FloatVar x1)
Post propagator for .
std::string id
Identifier for the constraint.
Definition: conexpr.hh:50
T * a
Element array.
Definition: array.hpp:531
void clause(Home home, BoolOpType o, const BoolVarArgs &x, const BoolVarArgs &y, int n, IntPropLevel)
Post domain consistent propagator for Boolean clause with positive variables x and negative variables...
Definition: bool.cpp:910
Equivalence for reification (default)
Definition: int.hh:836
IntRelType swap(IntRelType irt)
Return swapped relation type of irt.
Definition: irt.hpp:41
void cumulatives(Home home, const IntVarArgs &m, const IntVarArgs &s, const IntVarArgs &p, const IntVarArgs &e, const IntVarArgs &u, const IntArgs &c, bool at_most, IntPropLevel cl)
Post propagators for the cumulatives constraint.
Abstract representation of a constraint.
Definition: conexpr.hh:47