48
52
namespace Gecode { namespace FlatZinc {
55
* \brief Branching on the introduced variables
57
* This brancher makes sure that when a solution is found for the model
58
* variables, all introduced variables are either assigned, or the solution
59
* can be extended to a solution of the introduced variables.
61
* The advantage over simply branching over the introduced variables is that
62
* only one such extension will be searched for, instead of enumerating all
63
* possible (equivalent) extensions.
66
class AuxVarBrancher : public Brancher {
68
/// Flag whether brancher is done
70
/// Construct brancher
71
AuxVarBrancher(Home home) : Brancher(home), done(false) {}
73
AuxVarBrancher(Space& home, bool share, AuxVarBrancher& b)
74
: Brancher(home, share, b), done(b.done) {}
76
/// %Choice that only signals failure or success
77
class Choice : public Gecode::Choice {
79
/// Whether brancher should fail
81
/// Initialize choice for brancher \a b
82
Choice(const Brancher& b, bool fail0)
83
: Gecode::Choice(b,1), fail(fail0) {}
84
/// Report size occupied
85
virtual size_t size(void) const {
86
return sizeof(Choice);
89
virtual void archive(Archive& e) const {
90
Gecode::Choice::archive(e);
97
/// Check status of brancher, return true if alternatives left.
98
virtual bool status(const Space& _home) const {
99
if (done) return false;
100
const FlatZincSpace& home = static_cast<const FlatZincSpace&>(_home);
101
for (int i=0; i<home.iv_aux.size(); i++)
102
if (!home.iv_aux[i].assigned()) return true;
103
for (int i=0; i<home.bv_aux.size(); i++)
104
if (!home.bv_aux[i].assigned()) return true;
105
#ifdef GECODE_HAS_SET_VARS
106
for (int i=0; i<home.sv_aux.size(); i++)
107
if (!home.sv_aux[i].assigned()) return true;
109
#ifdef GECODE_HAS_FLOAT_VARS
110
for (int i=0; i<home.fv_aux.size(); i++)
111
if (!home.fv_aux[i].assigned()) return true;
113
// No non-assigned variables left
117
virtual Choice* choice(Space& home) {
119
FlatZincSpace& fzs = static_cast<FlatZincSpace&>(*home.clone());
120
fzs.needAuxVars = false;
121
branch(fzs,fzs.iv_aux,INT_VAR_AFC_SIZE_MAX(),INT_VAL_MIN());
122
branch(fzs,fzs.bv_aux,INT_VAR_AFC_MAX(),INT_VAL_MIN());
123
#ifdef GECODE_HAS_SET_VARS
124
branch(fzs,fzs.sv_aux,SET_VAR_AFC_SIZE_MAX(),SET_VAL_MIN_INC());
126
#ifdef GECODE_HAS_FLOAT_VARS
127
branch(fzs,fzs.fv_aux,FLOAT_VAR_AFC_SIZE_MAX(),FLOAT_VAL_SPLIT_MIN());
129
Search::Options opt; opt.clone = false;
130
FlatZincSpace* sol = dfs(&fzs, opt);
133
return new Choice(*this,false);
135
return new Choice(*this,true);
139
virtual Choice* choice(const Space&, Archive& e) {
140
bool fail; e >> fail;
141
return new Choice(*this, fail);
143
/// Perform commit for choice \a c
144
virtual ExecStatus commit(Space&, const Gecode::Choice& c, unsigned int) {
145
return static_cast<const Choice&>(c).fail ? ES_FAILED : ES_OK;
148
virtual Actor* copy(Space& home, bool share) {
149
return new (home) AuxVarBrancher(home, share, *this);
152
static void post(Home home) {
153
(void) new (home) AuxVarBrancher(home);
155
/// Delete brancher and return its size
156
virtual size_t dispose(Space&) {
157
return sizeof(*this);
50
162
IntSet vs2is(IntVarSpec* vs) {
51
163
if (vs->assigned) {
52
164
return IntSet(vs->i,vs->i);
94
TieBreakVarBranch<IntVarBranch> ann2ivarsel(AST::Node* ann) {
206
TieBreak<IntVarBranch> ann2ivarsel(AST::Node* ann, int seed, double decay) {
95
207
if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
96
208
if (s->id == "input_order")
97
return TieBreakVarBranch<IntVarBranch>(INT_VAR_NONE);
209
return TieBreak<IntVarBranch>(INT_VAR_NONE());
98
210
if (s->id == "first_fail")
99
return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_MIN);
211
return TieBreak<IntVarBranch>(INT_VAR_SIZE_MIN());
100
212
if (s->id == "anti_first_fail")
101
return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_MAX);
213
return TieBreak<IntVarBranch>(INT_VAR_SIZE_MAX());
102
214
if (s->id == "smallest")
103
return TieBreakVarBranch<IntVarBranch>(INT_VAR_MIN_MIN);
215
return TieBreak<IntVarBranch>(INT_VAR_MIN_MIN());
104
216
if (s->id == "largest")
105
return TieBreakVarBranch<IntVarBranch>(INT_VAR_MAX_MAX);
217
return TieBreak<IntVarBranch>(INT_VAR_MAX_MAX());
106
218
if (s->id == "occurrence")
107
return TieBreakVarBranch<IntVarBranch>(INT_VAR_DEGREE_MAX);
219
return TieBreak<IntVarBranch>(INT_VAR_DEGREE_MAX());
108
220
if (s->id == "max_regret")
109
return TieBreakVarBranch<IntVarBranch>(INT_VAR_REGRET_MIN_MAX);
221
return TieBreak<IntVarBranch>(INT_VAR_REGRET_MIN_MAX());
110
222
if (s->id == "most_constrained")
111
return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_MIN,
113
if (s->id == "random")
114
return TieBreakVarBranch<IntVarBranch>(INT_VAR_RND);
223
return TieBreak<IntVarBranch>(INT_VAR_SIZE_MIN(),
224
INT_VAR_DEGREE_MAX());
225
if (s->id == "random") {
226
Rnd r(static_cast<unsigned int>(seed));
227
return TieBreak<IntVarBranch>(INT_VAR_RND(r));
115
229
if (s->id == "afc_min")
116
return TieBreakVarBranch<IntVarBranch>(INT_VAR_AFC_MIN);
230
return TieBreak<IntVarBranch>(INT_VAR_AFC_MIN(decay));
117
231
if (s->id == "afc_max")
118
return TieBreakVarBranch<IntVarBranch>(INT_VAR_AFC_MAX);
119
if (s->id == "size_afc_min")
120
return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_AFC_MIN);
121
if (s->id == "size_afc_max")
122
return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_AFC_MAX);
232
return TieBreak<IntVarBranch>(INT_VAR_AFC_MAX(decay));
233
if (s->id == "afc_size_min")
234
return TieBreak<IntVarBranch>(INT_VAR_AFC_SIZE_MIN(decay));
235
if (s->id == "afc_size_max") {
236
return TieBreak<IntVarBranch>(INT_VAR_AFC_SIZE_MAX(decay));
238
if (s->id == "activity_min")
239
return TieBreak<IntVarBranch>(INT_VAR_ACTIVITY_MIN(decay));
240
if (s->id == "activity_max")
241
return TieBreak<IntVarBranch>(INT_VAR_ACTIVITY_MAX(decay));
242
if (s->id == "activity_size_min")
243
return TieBreak<IntVarBranch>(INT_VAR_ACTIVITY_SIZE_MIN(decay));
244
if (s->id == "activity_size_max")
245
return TieBreak<IntVarBranch>(INT_VAR_ACTIVITY_SIZE_MAX(decay));
124
247
std::cerr << "Warning, ignored search annotation: ";
125
248
ann->print(std::cerr);
126
249
std::cerr << std::endl;
127
return TieBreakVarBranch<IntVarBranch>(INT_VAR_NONE);
250
return TieBreak<IntVarBranch>(INT_VAR_NONE());
130
IntValBranch ann2ivalsel(AST::Node* ann) {
253
IntValBranch ann2ivalsel(AST::Node* ann, int seed) {
131
254
if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
132
255
if (s->id == "indomain_min")
256
return INT_VAL_MIN();
134
257
if (s->id == "indomain_max")
258
return INT_VAL_MAX();
136
259
if (s->id == "indomain_median")
260
return INT_VAL_MED();
138
261
if (s->id == "indomain_split")
139
return INT_VAL_SPLIT_MIN;
262
return INT_VAL_SPLIT_MIN();
140
263
if (s->id == "indomain_reverse_split")
141
return INT_VAL_SPLIT_MAX;
142
if (s->id == "indomain_random")
264
return INT_VAL_SPLIT_MAX();
265
if (s->id == "indomain_random") {
266
Rnd r(static_cast<unsigned int>(seed));
267
return INT_VAL_RND(r);
144
269
if (s->id == "indomain")
145
return INT_VALUES_MIN;
270
return INT_VALUES_MIN();
146
271
if (s->id == "indomain_middle") {
147
272
std::cerr << "Warning, replacing unsupported annotation "
148
273
<< "indomain_middle with indomain_median" << std::endl;
274
return INT_VAL_MED();
151
276
if (s->id == "indomain_interval") {
152
277
std::cerr << "Warning, replacing unsupported annotation "
153
278
<< "indomain_interval with indomain_split" << std::endl;
154
return INT_VAL_SPLIT_MIN;
279
return INT_VAL_SPLIT_MIN();
157
282
std::cerr << "Warning, ignored search annotation: ";
158
283
ann->print(std::cerr);
159
284
std::cerr << std::endl;
285
return INT_VAL_MIN();
163
IntAssign ann2asnivalsel(AST::Node* ann) {
288
IntAssign ann2asnivalsel(AST::Node* ann, int seed) {
164
289
if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
165
290
if (s->id == "indomain_min")
166
return INT_ASSIGN_MIN;
291
return INT_ASSIGN_MIN();
167
292
if (s->id == "indomain_max")
168
return INT_ASSIGN_MAX;
293
return INT_ASSIGN_MAX();
169
294
if (s->id == "indomain_median")
170
return INT_ASSIGN_MED;
171
if (s->id == "indomain_random")
172
return INT_ASSIGN_RND;
295
return INT_ASSIGN_MED();
296
if (s->id == "indomain_random") {
297
Rnd r(static_cast<unsigned int>(seed));
298
return INT_ASSIGN_RND(r);
174
301
std::cerr << "Warning, ignored search annotation: ";
175
302
ann->print(std::cerr);
176
303
std::cerr << std::endl;
177
return INT_ASSIGN_MIN;
304
return INT_ASSIGN_MIN();
180
307
#ifdef GECODE_HAS_SET_VARS
181
SetVarBranch ann2svarsel(AST::Node* ann) {
308
SetVarBranch ann2svarsel(AST::Node* ann, int seed, double decay) {
182
310
if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
183
311
if (s->id == "input_order")
312
return SET_VAR_NONE();
185
313
if (s->id == "first_fail")
186
return SET_VAR_SIZE_MIN;
314
return SET_VAR_SIZE_MIN();
187
315
if (s->id == "anti_first_fail")
188
return SET_VAR_SIZE_MAX;
316
return SET_VAR_SIZE_MAX();
189
317
if (s->id == "smallest")
190
return SET_VAR_MIN_MIN;
318
return SET_VAR_MIN_MIN();
191
319
if (s->id == "largest")
192
return SET_VAR_MAX_MAX;
320
return SET_VAR_MAX_MAX();
321
if (s->id == "afc_min")
322
return SET_VAR_AFC_MIN(decay);
323
if (s->id == "afc_max")
324
return SET_VAR_AFC_MAX(decay);
325
if (s->id == "afc_size_min")
326
return SET_VAR_AFC_SIZE_MIN(decay);
327
if (s->id == "afc_size_max")
328
return SET_VAR_AFC_SIZE_MAX(decay);
329
if (s->id == "activity_min")
330
return SET_VAR_ACTIVITY_MIN(decay);
331
if (s->id == "activity_max")
332
return SET_VAR_ACTIVITY_MAX(decay);
333
if (s->id == "activity_size_min")
334
return SET_VAR_ACTIVITY_SIZE_MIN(decay);
335
if (s->id == "activity_size_max")
336
return SET_VAR_ACTIVITY_SIZE_MAX(decay);
194
338
std::cerr << "Warning, ignored search annotation: ";
195
339
ann->print(std::cerr);
196
340
std::cerr << std::endl;
341
return SET_VAR_NONE();
200
SetValBranch ann2svalsel(AST::Node* ann) {
344
SetValBranch ann2svalsel(AST::Node* ann, int seed) {
201
346
if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
202
347
if (s->id == "indomain_min")
203
return SET_VAL_MIN_INC;
348
return SET_VAL_MIN_INC();
204
349
if (s->id == "indomain_max")
205
return SET_VAL_MAX_INC;
350
return SET_VAL_MAX_INC();
206
351
if (s->id == "outdomain_min")
207
return SET_VAL_MIN_EXC;
352
return SET_VAL_MIN_EXC();
208
353
if (s->id == "outdomain_max")
209
return SET_VAL_MAX_EXC;
211
std::cerr << "Warning, ignored search annotation: ";
212
ann->print(std::cerr);
213
std::cerr << std::endl;
214
return SET_VAL_MIN_INC;
354
return SET_VAL_MAX_EXC();
356
std::cerr << "Warning, ignored search annotation: ";
357
ann->print(std::cerr);
358
std::cerr << std::endl;
359
return SET_VAL_MIN_INC();
363
#ifdef GECODE_HAS_FLOAT_VARS
364
TieBreak<FloatVarBranch> ann2fvarsel(AST::Node* ann, int seed, double decay) {
365
if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
366
if (s->id == "input_order")
367
return TieBreak<FloatVarBranch>(FLOAT_VAR_NONE());
368
if (s->id == "first_fail")
369
return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MIN());
370
if (s->id == "anti_first_fail")
371
return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MAX());
372
if (s->id == "smallest")
373
return TieBreak<FloatVarBranch>(FLOAT_VAR_MIN_MIN());
374
if (s->id == "largest")
375
return TieBreak<FloatVarBranch>(FLOAT_VAR_MAX_MAX());
376
if (s->id == "occurrence")
377
return TieBreak<FloatVarBranch>(FLOAT_VAR_DEGREE_MAX());
378
if (s->id == "most_constrained")
379
return TieBreak<FloatVarBranch>(FLOAT_VAR_SIZE_MIN(),
380
FLOAT_VAR_DEGREE_MAX());
381
if (s->id == "random") {
382
Rnd r(static_cast<unsigned int>(seed));
383
return TieBreak<FloatVarBranch>(FLOAT_VAR_RND(r));
385
if (s->id == "afc_min")
386
return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_MIN(decay));
387
if (s->id == "afc_max")
388
return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_MAX(decay));
389
if (s->id == "afc_size_min")
390
return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_SIZE_MIN(decay));
391
if (s->id == "afc_size_max")
392
return TieBreak<FloatVarBranch>(FLOAT_VAR_AFC_SIZE_MAX(decay));
393
if (s->id == "activity_min")
394
return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTIVITY_MIN(decay));
395
if (s->id == "activity_max")
396
return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTIVITY_MAX(decay));
397
if (s->id == "activity_size_min")
398
return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTIVITY_SIZE_MIN(decay));
399
if (s->id == "activity_size_max")
400
return TieBreak<FloatVarBranch>(FLOAT_VAR_ACTIVITY_SIZE_MAX(decay));
402
std::cerr << "Warning, ignored search annotation: ";
403
ann->print(std::cerr);
404
std::cerr << std::endl;
405
return TieBreak<FloatVarBranch>(FLOAT_VAR_NONE());
408
FloatValBranch ann2fvalsel(AST::Node* ann) {
409
if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
410
if (s->id == "indomain_split")
411
return FLOAT_VAL_SPLIT_MIN();
412
if (s->id == "indomain_reverse_split")
413
return FLOAT_VAL_SPLIT_MAX();
415
std::cerr << "Warning, ignored search annotation: ";
416
ann->print(std::cerr);
417
std::cerr << std::endl;
418
return FLOAT_VAL_SPLIT_MIN();
218
423
FlatZincSpace::FlatZincSpace(bool share, FlatZincSpace& f)
219
: Space(share, f), _solveAnnotations(NULL), iv_boolalias(NULL) {
424
: Space(share, f), _solveAnnotations(NULL), iv_boolalias(NULL),
425
needAuxVars(f.needAuxVars) {
220
426
_optVar = f._optVar;
221
427
_method = f._method;
222
428
iv.update(*this, share, f.iv);
223
429
intVarCount = f.intVarCount;
433
for (int i=0; i<f.iv_aux.size(); i++) {
434
if (!f.iv_aux[i].assigned()) {
436
iva[iva.size()-1].update(*this, share, f.iv_aux[i]);
439
iv_aux = IntVarArray(*this, iva);
224
442
bv.update(*this, share, f.bv);
225
443
boolVarCount = f.boolVarCount;
446
for (int i=0; i<f.bv_aux.size(); i++) {
447
if (!f.bv_aux[i].assigned()) {
449
bva[bva.size()-1].update(*this, share, f.bv_aux[i]);
452
bv_aux = BoolVarArray(*this, bva);
226
455
#ifdef GECODE_HAS_SET_VARS
227
456
sv.update(*this, share, f.sv);
228
457
setVarCount = f.setVarCount;
460
for (int i=0; i<f.sv_aux.size(); i++) {
461
if (!f.sv_aux[i].assigned()) {
463
sva[sva.size()-1].update(*this, share, f.sv_aux[i]);
466
sv_aux = SetVarArray(*this, sva);
469
#ifdef GECODE_HAS_FLOAT_VARS
470
fv.update(*this, share, f.fv);
471
floatVarCount = f.floatVarCount;
474
for (int i=0; i<f.fv_aux.size(); i++) {
475
if (!f.fv_aux[i].assigned()) {
477
fva[fva.size()-1].update(*this, share, f.fv_aux[i]);
480
fv_aux = FloatVarArray(*this, fva);
232
485
FlatZincSpace::FlatZincSpace(void)
233
: intVarCount(-1), boolVarCount(-1), setVarCount(-1), _optVar(-1),
234
_solveAnnotations(NULL) {}
486
: intVarCount(-1), boolVarCount(-1), floatVarCount(-1), setVarCount(-1),
487
_optVar(-1), _solveAnnotations(NULL), needAuxVars(true) {}
237
490
FlatZincSpace::init(int intVars, int boolVars,
238
#ifdef GECODE_HAS_SET_VARS
491
int setVars, int floatVars) {
244
496
iv = IntVarArray(*this, intVars);
245
iv_introduced = std::vector<bool>(intVars);
497
iv_introduced = std::vector<bool>(2*intVars);
246
498
iv_boolalias = alloc<int>(intVars+(intVars==0?1:0));
247
499
boolVarCount = 0;
248
500
bv = BoolVarArray(*this, boolVars);
249
bv_introduced = std::vector<bool>(boolVars);
501
bv_introduced = std::vector<bool>(2*boolVars);
250
502
#ifdef GECODE_HAS_SET_VARS
252
504
sv = SetVarArray(*this, setVars);
253
sv_introduced = std::vector<bool>(setVars);
505
sv_introduced = std::vector<bool>(2*setVars);
507
#ifdef GECODE_HAS_FLOAT_VARS
509
fv = FloatVarArray(*this, floatVars);
510
fv_introduced = std::vector<bool>(2*floatVars);
415
701
va[k++] = iv[vars->a[i]->getIntVar()];
417
assign(*this, va, ann2asnivalsel(args->a[1]));
418
} catch (AST::TypeError& e) {
421
AST::Call *call = flatAnn[i]->getCall("bool_search");
422
AST::Array *args = call->getArgs(4);
423
AST::Array *vars = args->a[0]->getArray();
424
int k=vars->a.size();
425
for (int i=vars->a.size(); i--;)
426
if (vars->a[i]->isBool())
430
for (unsigned int i=0; i<vars->a.size(); i++) {
431
if (vars->a[i]->isBool())
433
va[k++] = bv[vars->a[i]->getBoolVar()];
435
branch(*this, va, ann2ivarsel(args->a[1]),
436
ann2ivalsel(args->a[2]), varbo, valbo);
437
} catch (AST::TypeError& e) {
703
assign(*this, va, ann2asnivalsel(args->a[1],seed));
704
} else if (flatAnn[i]->isCall("bool_search")) {
705
AST::Call *call = flatAnn[i]->getCall("bool_search");
706
AST::Array *args = call->getArgs(4);
707
AST::Array *vars = args->a[0]->getArray();
708
int k=vars->a.size();
709
for (int i=vars->a.size(); i--;)
710
if (vars->a[i]->isBool())
714
for (unsigned int i=0; i<vars->a.size(); i++) {
715
if (vars->a[i]->isBool())
717
va[k++] = bv[vars->a[i]->getBoolVar()];
720
ann2ivarsel(args->a[1],seed,decay),
721
ann2ivalsel(args->a[2],seed));
722
} else if (flatAnn[i]->isCall("set_search")) {
439
723
#ifdef GECODE_HAS_SET_VARS
441
AST::Call *call = flatAnn[i]->getCall("set_search");
442
AST::Array *args = call->getArgs(4);
443
AST::Array *vars = args->a[0]->getArray();
444
int k=vars->a.size();
445
for (int i=vars->a.size(); i--;)
446
if (vars->a[i]->isSet())
450
for (unsigned int i=0; i<vars->a.size(); i++) {
451
if (vars->a[i]->isSet())
453
va[k++] = sv[vars->a[i]->getSetVar()];
455
branch(*this, va, ann2svarsel(args->a[1]),
456
ann2svalsel(args->a[2]), varbo, valbo);
457
} catch (AST::TypeError& e) {
459
if (!ignoreUnknown) {
460
err << "Warning, ignored search annotation: ";
461
flatAnn[i]->print(err);
724
AST::Call *call = flatAnn[i]->getCall("set_search");
725
AST::Array *args = call->getArgs(4);
726
AST::Array *vars = args->a[0]->getArray();
727
int k=vars->a.size();
728
for (int i=vars->a.size(); i--;)
729
if (vars->a[i]->isSet())
733
for (unsigned int i=0; i<vars->a.size(); i++) {
734
if (vars->a[i]->isSet())
736
va[k++] = sv[vars->a[i]->getSetVar()];
739
ann2svarsel(args->a[1],seed,decay),
740
ann2svalsel(args->a[2],seed));
466
if (!ignoreUnknown) {
467
err << "Warning, ignored search annotation: ";
468
flatAnn[i]->print(err);
742
if (!ignoreUnknown) {
743
err << "Warning, ignored search annotation: ";
744
flatAnn[i]->print(err);
749
#ifdef GECODE_HAS_FLOAT_VARS
750
else if (flatAnn[i]->isCall("float_search")) {
751
AST::Call *call = flatAnn[i]->getCall("float_search");
752
AST::Array *args = call->getArgs(5);
753
AST::Array *vars = args->a[0]->getArray();
754
int k=vars->a.size();
755
for (int i=vars->a.size(); i--;)
756
if (vars->a[i]->isFloat())
760
for (unsigned int i=0; i<vars->a.size(); i++) {
761
if (vars->a[i]->isFloat())
763
va[k++] = fv[vars->a[i]->getFloatVar()];
766
ann2fvarsel(args->a[2],seed,decay),
767
ann2fvalsel(args->a[3]));
771
if (!ignoreUnknown) {
772
err << "Warning, ignored search annotation: ";
773
flatAnn[i]->print(err);
477
779
int introduced = 0;
478
781
for (int i=iv.size(); i--;)
479
if (iv_introduced[i])
481
IntVarArgs iv_sol(iv.size()-introduced);
782
if (iv_introduced[2*i]) {
783
if (iv_introduced[2*i+1]) {
789
IntVarArgs iv_sol(iv.size()-(introduced+funcdep));
482
790
IntVarArgs iv_tmp(introduced);
483
791
for (int i=iv.size(), j=0, k=0; i--;)
484
if (iv_introduced[i])
792
if (iv_introduced[2*i]) {
793
if (!iv_introduced[2*i+1]) {
487
797
iv_sol[k++] = iv[i];
490
802
for (int i=bv.size(); i--;)
491
if (bv_introduced[i])
493
BoolVarArgs bv_sol(bv.size()-introduced);
803
if (bv_introduced[2*i]) {
804
if (bv_introduced[2*i+1]) {
810
BoolVarArgs bv_sol(bv.size()-(introduced+funcdep));
494
811
BoolVarArgs bv_tmp(introduced);
495
812
for (int i=bv.size(), j=0, k=0; i--;)
496
if (bv_introduced[i])
813
if (bv_introduced[2*i]) {
814
if (!bv_introduced[2*i+1]) {
499
818
bv_sol[k++] = bv[i];
501
branch(*this, iv_sol, INT_VAR_SIZE_AFC_MIN, INT_VAL_MIN);
502
branch(*this, bv_sol, INT_VAR_AFC_MAX, INT_VAL_MIN);
821
branch(*this, iv_sol, INT_VAR_AFC_SIZE_MAX(0.99), INT_VAL_MIN());
822
branch(*this, bv_sol, INT_VAR_AFC_MAX(0.99), INT_VAL_MIN());
823
#ifdef GECODE_HAS_FLOAT_VARS
826
for (int i=fv.size(); i--;)
827
if (fv_introduced[2*i]) {
828
if (fv_introduced[2*i+1]) {
834
FloatVarArgs fv_sol(fv.size()-(introduced+funcdep));
835
FloatVarArgs fv_tmp(introduced);
836
for (int i=fv.size(), j=0, k=0; i--;)
837
if (fv_introduced[2*i]) {
838
if (!fv_introduced[2*i+1]) {
845
branch(*this, fv_sol, FLOAT_VAR_SIZE_MIN(), FLOAT_VAL_SPLIT_MIN());
503
847
#ifdef GECODE_HAS_SET_VARS
505
850
for (int i=sv.size(); i--;)
506
if (sv_introduced[i])
508
SetVarArgs sv_sol(sv.size()-introduced);
851
if (sv_introduced[2*i]) {
852
if (sv_introduced[2*i+1]) {
858
SetVarArgs sv_sol(sv.size()-(introduced+funcdep));
509
859
SetVarArgs sv_tmp(introduced);
510
860
for (int i=sv.size(), j=0, k=0; i--;)
511
if (sv_introduced[i])
861
if (sv_introduced[2*i]) {
862
if (!sv_introduced[2*i+1]) {
514
866
sv_sol[k++] = sv[i];
515
branch(*this, sv_sol, SET_VAR_SIZE_AFC_MIN, SET_VAL_MIN_INC);
869
branch(*this, sv_sol, SET_VAR_AFC_SIZE_MAX(0.99), SET_VAL_MIN_INC());
517
branch(*this, iv_tmp, INT_VAR_SIZE_AFC_MIN, INT_VAL_MIN);
518
branch(*this, bv_tmp, INT_VAR_AFC_MAX, INT_VAL_MIN);
871
iv_aux = IntVarArray(*this, iv_tmp);
872
bv_aux = BoolVarArray(*this, bv_tmp);
519
873
#ifdef GECODE_HAS_SET_VARS
520
branch(*this, sv_tmp, SET_VAR_SIZE_AFC_MIN, SET_VAL_MIN_INC);
874
sv_aux = SetVarArray(*this, sv_tmp);
876
#ifdef GECODE_HAS_FLOAT_VARS
877
fv_aux = FloatVarArray(*this, fv_tmp);
879
AuxVarBrancher::post(*this);
829
1277
#ifdef GECODE_HAS_SET_VARS
1280
#ifdef GECODE_HAS_FLOAT_VARS
1287
FlatZincSpace::arg2intargs(AST::Node* arg, int offset) {
1288
AST::Array* a = arg->getArray();
1289
IntArgs ia(a->a.size()+offset);
1290
for (int i=offset; i--;)
1292
for (int i=a->a.size(); i--;)
1293
ia[i+offset] = a->a[i]->getInt();
1297
FlatZincSpace::arg2boolargs(AST::Node* arg, int offset) {
1298
AST::Array* a = arg->getArray();
1299
IntArgs ia(a->a.size()+offset);
1300
for (int i=offset; i--;)
1302
for (int i=a->a.size(); i--;)
1303
ia[i+offset] = a->a[i]->getBool();
1307
FlatZincSpace::arg2intset(AST::Node* n) {
1308
AST::SetLit* sl = n->getSet();
1311
d = IntSet(sl->min, sl->max);
1314
int* is = re.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
1315
for (int i=sl->s.size(); i--; )
1317
d = IntSet(is, sl->s.size());
1322
FlatZincSpace::arg2intsetargs(AST::Node* arg, int offset) {
1323
AST::Array* a = arg->getArray();
1324
if (a->a.size() == 0) {
1325
IntSetArgs emptyIa(0);
1328
IntSetArgs ia(a->a.size()+offset);
1329
for (int i=offset; i--;)
1330
ia[i] = IntSet::empty;
1331
for (int i=a->a.size(); i--;) {
1332
ia[i+offset] = arg2intset(a->a[i]);
1337
FlatZincSpace::arg2intvarargs(AST::Node* arg, int offset) {
1338
AST::Array* a = arg->getArray();
1339
if (a->a.size() == 0) {
1340
IntVarArgs emptyIa(0);
1343
IntVarArgs ia(a->a.size()+offset);
1344
for (int i=offset; i--;)
1345
ia[i] = IntVar(*this, 0, 0);
1346
for (int i=a->a.size(); i--;) {
1347
if (a->a[i]->isIntVar()) {
1348
ia[i+offset] = iv[a->a[i]->getIntVar()];
1350
int value = a->a[i]->getInt();
1351
IntVar iv(*this, value, value);
1358
FlatZincSpace::arg2boolvarargs(AST::Node* arg, int offset, int siv) {
1359
AST::Array* a = arg->getArray();
1360
if (a->a.size() == 0) {
1361
BoolVarArgs emptyIa(0);
1364
BoolVarArgs ia(a->a.size()+offset-(siv==-1?0:1));
1365
for (int i=offset; i--;)
1366
ia[i] = BoolVar(*this, 0, 0);
1367
for (int i=0; i<static_cast<int>(a->a.size()); i++) {
1370
if (a->a[i]->isBool()) {
1371
bool value = a->a[i]->getBool();
1372
BoolVar iv(*this, value, value);
1374
} else if (a->a[i]->isIntVar() &&
1375
aliasBool2Int(a->a[i]->getIntVar()) != -1) {
1376
ia[offset++] = bv[aliasBool2Int(a->a[i]->getIntVar())];
1378
ia[offset++] = bv[a->a[i]->getBoolVar()];
1384
FlatZincSpace::arg2BoolVar(AST::Node* n) {
1387
x0 = BoolVar(*this, n->getBool(), n->getBool());
1390
x0 = bv[n->getBoolVar()];
1395
FlatZincSpace::arg2IntVar(AST::Node* n) {
1397
if (n->isIntVar()) {
1398
x0 = iv[n->getIntVar()];
1400
x0 = IntVar(*this, n->getInt(), n->getInt());
1405
FlatZincSpace::isBoolArray(AST::Node* b, int& singleInt) {
1406
AST::Array* a = b->getArray();
1408
if (a->a.size() == 0)
1410
for (int i=a->a.size(); i--;) {
1411
if (a->a[i]->isBoolVar() || a->a[i]->isBool()) {
1412
} else if (a->a[i]->isIntVar()) {
1413
if (aliasBool2Int(a->a[i]->getIntVar()) == -1) {
1414
if (singleInt != -1) {
1423
return singleInt==-1 || a->a.size() > 1;
1425
#ifdef GECODE_HAS_SET_VARS
1427
FlatZincSpace::arg2SetVar(AST::Node* n) {
1429
if (!n->isSetVar()) {
1430
IntSet d = arg2intset(n);
1431
x0 = SetVar(*this, d, d);
1433
x0 = sv[n->getSetVar()];
1438
FlatZincSpace::arg2setvarargs(AST::Node* arg, int offset, int doffset,
1440
AST::Array* a = arg->getArray();
1441
SetVarArgs ia(a->a.size()+offset);
1442
for (int i=offset; i--;) {
1443
IntSet d = i<doffset ? od : IntSet::empty;
1444
ia[i] = SetVar(*this, d, d);
1446
for (int i=a->a.size(); i--;) {
1447
ia[i+offset] = arg2SetVar(a->a[i]);
1452
#ifdef GECODE_HAS_FLOAT_VARS
1454
FlatZincSpace::arg2floatargs(AST::Node* arg, int offset) {
1455
AST::Array* a = arg->getArray();
1456
FloatValArgs fa(a->a.size()+offset);
1457
for (int i=offset; i--;)
1459
for (int i=a->a.size(); i--;)
1460
fa[i+offset] = a->a[i]->getFloat();
1464
FlatZincSpace::arg2floatvarargs(AST::Node* arg, int offset) {
1465
AST::Array* a = arg->getArray();
1466
if (a->a.size() == 0) {
1467
FloatVarArgs emptyFa(0);
1470
FloatVarArgs fa(a->a.size()+offset);
1471
for (int i=offset; i--;)
1472
fa[i] = FloatVar(*this, 0.0, 0.0);
1473
for (int i=a->a.size(); i--;) {
1474
if (a->a[i]->isFloatVar()) {
1475
fa[i+offset] = fv[a->a[i]->getFloatVar()];
1477
double value = a->a[i]->getFloat();
1478
FloatVar fv(*this, value, value);
1485
FlatZincSpace::arg2FloatVar(AST::Node* n) {
1487
if (n->isFloatVar()) {
1488
x0 = fv[n->getFloatVar()];
1490
x0 = FloatVar(*this, n->getFloat(), n->getFloat());
1496
FlatZincSpace::ann2icl(AST::Node* ann) {
1498
if (ann->hasAtom("val"))
1500
if (ann->hasAtom("domain"))
1502
if (ann->hasAtom("bounds") ||
1503
ann->hasAtom("boundsR") ||
1504
ann->hasAtom("boundsD") ||
1505
ann->hasAtom("boundsZ"))
836
1513
Printer::init(AST::Array* output) {
837
1514
_output = output;
885
1566
out << min << ".." << max;
888
} else if (ai->isBool()) {
889
out << (ai->getBool() ? "true" : "false");
890
} else if (ai->isSet()) {
891
AST::SetLit* s = ai->getSet();
893
out << s->min << ".." << s->max;
896
for (unsigned int i=0; i<s->s.size(); i++) {
897
out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
900
} else if (ai->isString()) {
901
std::string s = ai->getString();
902
for (unsigned int i=0; i<s.size(); i++) {
903
if (s[i] == '\\' && i<s.size()-1) {
905
case 'n': out << "\n"; break;
906
case '\\': out << "\\"; break;
907
case 't': out << "\t"; break;
908
default: out << "\\" << s[i+1];
1569
#ifdef GECODE_HAS_FLOAT_VARS
1570
} else if (ai->isFloatVar()) {
1571
out << fv[ai->getFloatVar()];
1573
} else if (ai->isBool()) {
1574
out << (ai->getBool() ? "true" : "false");
1575
} else if (ai->isSet()) {
1576
AST::SetLit* s = ai->getSet();
1578
out << s->min << ".." << s->max;
1581
for (unsigned int i=0; i<s->s.size(); i++) {
1582
out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
1585
} else if (ai->isString()) {
1586
std::string s = ai->getString();
1587
for (unsigned int i=0; i<s.size(); i++) {
1588
if (s[i] == '\\' && i<s.size()-1) {
1590
case 'n': out << "\n"; break;
1591
case '\\': out << "\\"; break;
1592
case 't': out << "\t"; break;
1593
default: out << "\\" << s[i+1];
1604
Printer::printElemDiff(std::ostream& out,
1606
const Gecode::IntVarArray& iv1,
1607
const Gecode::IntVarArray& iv2,
1608
const Gecode::BoolVarArray& bv1,
1609
const Gecode::BoolVarArray& bv2
1610
#ifdef GECODE_HAS_SET_VARS
1611
, const Gecode::SetVarArray& sv1,
1612
const Gecode::SetVarArray& sv2
1614
#ifdef GECODE_HAS_FLOAT_VARS
1615
, const Gecode::FloatVarArray& fv1,
1616
const Gecode::FloatVarArray& fv2
1619
#ifdef GECODE_HAS_GIST
1620
using namespace Gecode::Gist;
1624
} else if (ai->isIntVar()) {
1625
std::string res(Comparator::compare("",iv1[ai->getIntVar()],
1626
iv2[ai->getIntVar()]));
1627
if (res.length() > 0) {
1628
res.erase(0, 1); // Remove '='
1631
out << iv1[ai->getIntVar()];
1633
} else if (ai->isBoolVar()) {
1634
std::string res(Comparator::compare("",bv1[ai->getBoolVar()],
1635
bv2[ai->getBoolVar()]));
1636
if (res.length() > 0) {
1637
res.erase(0, 1); // Remove '='
1640
out << bv1[ai->getBoolVar()];
1642
#ifdef GECODE_HAS_SET_VARS
1643
} else if (ai->isSetVar()) {
1644
std::string res(Comparator::compare("",sv1[ai->getSetVar()],
1645
sv2[ai->getSetVar()]));
1646
if (res.length() > 0) {
1647
res.erase(0, 1); // Remove '='
1650
out << sv1[ai->getSetVar()];
1653
#ifdef GECODE_HAS_FLOAT_VARS
1654
} else if (ai->isFloatVar()) {
1655
std::string res(Comparator::compare("",fv1[ai->getFloatVar()],
1656
fv2[ai->getFloatVar()]));
1657
if (res.length() > 0) {
1658
res.erase(0, 1); // Remove '='
1661
out << fv1[ai->getFloatVar()];
1664
} else if (ai->isBool()) {
1665
out << (ai->getBool() ? "true" : "false");
1666
} else if (ai->isSet()) {
1667
AST::SetLit* s = ai->getSet();
1669
out << s->min << ".." << s->max;
1672
for (unsigned int i=0; i<s->s.size(); i++) {
1673
out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
1676
} else if (ai->isString()) {
1677
std::string s = ai->getString();
1678
for (unsigned int i=0; i<s.size(); i++) {
1679
if (s[i] == '\\' && i<s.size()-1) {
1681
case 'n': out << "\n"; break;
1682
case '\\': out << "\\"; break;
1683
case 't': out << "\t"; break;
1684
default: out << "\\" << s[i+1];