~ubuntu-branches/debian/stretch/gecode/stretch

« back to all changes in this revision

Viewing changes to gecode/flatzinc/flatzinc.cpp

  • Committer: Package Import Robot
  • Author(s): Kari Pahula
  • Date: 2013-05-25 15:57:32 UTC
  • mfrom: (1.1.17)
  • Revision ID: package-import@ubuntu.com-20130525155732-bltd8lu9my9borhk
Tags: 4.0.0-2
Give make check LD_LIBRARY_PATH=. to make test work without gecode
already installed, to fix FTBFS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *  Main authors:
4
4
 *     Guido Tack <tack@gecode.org>
5
5
 *
 
6
 *  Contributing authors:
 
7
 *     Gabriel Hjort Blindell <gabriel.hjort.blindell@gmail.com>
 
8
 *
6
9
 *  Copyright:
7
 
 *     Guido Tack, 2007
 
10
 *     Guido Tack, 2007-2012
 
11
 *     Gabriel Hjort Blindell, 2012
8
12
 *
9
13
 *  Last modified:
10
 
 *     $Date: 2012-03-21 16:25:08 +1100 (Wed, 21 Mar 2012) $ by $Author: tack $
11
 
 *     $Revision: 12605 $
 
14
 *     $Date: 2013-03-07 20:40:42 +0100 (Thu, 07 Mar 2013) $ by $Author: schulte $
 
15
 *     $Revision: 13462 $
12
16
 *
13
17
 *  This file is part of Gecode, the generic constraint
14
18
 *  development environment:
47
51
 
48
52
namespace Gecode { namespace FlatZinc {
49
53
 
 
54
  /**
 
55
   * \brief Branching on the introduced variables
 
56
   *
 
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.
 
60
   *
 
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.
 
64
   *
 
65
   */
 
66
  class AuxVarBrancher : public Brancher {
 
67
  protected:
 
68
    /// Flag whether brancher is done
 
69
    bool done;
 
70
    /// Construct brancher
 
71
    AuxVarBrancher(Home home) : Brancher(home), done(false) {}
 
72
    /// Copy constructor
 
73
    AuxVarBrancher(Space& home, bool share, AuxVarBrancher& b)
 
74
      : Brancher(home, share, b), done(b.done) {}
 
75
 
 
76
    /// %Choice that only signals failure or success
 
77
    class Choice : public Gecode::Choice {
 
78
    public:
 
79
      /// Whether brancher should fail
 
80
      bool 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);
 
87
      }
 
88
      /// Archive into \a e
 
89
      virtual void archive(Archive& e) const {
 
90
        Gecode::Choice::archive(e);
 
91
        e.put(fail);
 
92
      }
 
93
    };
 
94
 
 
95
 
 
96
  public:
 
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;
 
108
#endif
 
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;
 
112
#endif
 
113
      // No non-assigned variables left
 
114
      return false;
 
115
    }
 
116
    /// Return choice
 
117
    virtual Choice* choice(Space& home) {
 
118
      done = true;
 
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());
 
125
#endif
 
126
#ifdef GECODE_HAS_FLOAT_VARS
 
127
      branch(fzs,fzs.fv_aux,FLOAT_VAR_AFC_SIZE_MAX(),FLOAT_VAL_SPLIT_MIN());
 
128
#endif
 
129
      Search::Options opt; opt.clone = false;
 
130
      FlatZincSpace* sol = dfs(&fzs, opt);
 
131
      if (sol) {
 
132
        delete sol;
 
133
        return new Choice(*this,false);
 
134
      } else {
 
135
        return new Choice(*this,true);
 
136
      }
 
137
    }
 
138
    /// Return choice
 
139
    virtual Choice* choice(const Space&, Archive& e) {
 
140
      bool fail; e >> fail;
 
141
      return new Choice(*this, fail);
 
142
    }
 
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;
 
146
    }
 
147
    /// Copy brancher
 
148
    virtual Actor* copy(Space& home, bool share) {
 
149
      return new (home) AuxVarBrancher(home, share, *this);
 
150
    }
 
151
    /// Post brancher
 
152
    static void post(Home home) {
 
153
      (void) new (home) AuxVarBrancher(home);
 
154
    }
 
155
    /// Delete brancher and return its size
 
156
    virtual size_t dispose(Space&) {
 
157
      return sizeof(*this);
 
158
    }      
 
159
  };
 
160
 
 
161
 
50
162
  IntSet vs2is(IntVarSpec* vs) {
51
163
    if (vs->assigned) {
52
164
      return IntSet(vs->i,vs->i);
91
203
    return 1;
92
204
  }
93
205
 
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,
112
 
          INT_VAR_DEGREE_MAX);
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));
 
228
      }
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));
 
237
      }
 
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));
123
246
    }
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());
128
251
  }
129
252
 
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")
133
 
        return INT_VAL_MIN;
 
256
        return INT_VAL_MIN();
134
257
      if (s->id == "indomain_max")
135
 
        return INT_VAL_MAX;
 
258
        return INT_VAL_MAX();
136
259
      if (s->id == "indomain_median")
137
 
        return INT_VAL_MED;
 
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")
143
 
        return INT_VAL_RND;
 
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);
 
268
      }
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;
149
 
        return INT_VAL_MED;
 
274
        return INT_VAL_MED();
150
275
      }
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();
155
280
      }
156
281
    }
157
282
    std::cerr << "Warning, ignored search annotation: ";
158
283
    ann->print(std::cerr);
159
284
    std::cerr << std::endl;
160
 
    return INT_VAL_MIN;
 
285
    return INT_VAL_MIN();
161
286
  }
162
287
 
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);
 
299
      }
173
300
    }
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();
178
305
  }
179
306
 
180
307
#ifdef GECODE_HAS_SET_VARS
181
 
  SetVarBranch ann2svarsel(AST::Node* ann) {
 
308
  SetVarBranch ann2svarsel(AST::Node* ann, int seed, double decay) {
 
309
    (void) seed;
182
310
    if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
183
311
      if (s->id == "input_order")
184
 
        return SET_VAR_NONE;
 
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);
193
337
    }
194
338
    std::cerr << "Warning, ignored search annotation: ";
195
339
    ann->print(std::cerr);
196
340
    std::cerr << std::endl;
197
 
    return SET_VAR_NONE;
 
341
    return SET_VAR_NONE();
198
342
  }
199
343
 
200
 
  SetValBranch ann2svalsel(AST::Node* ann) {
 
344
  SetValBranch ann2svalsel(AST::Node* ann, int seed) {
 
345
    (void) 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;
210
 
    }
211
 
    std::cerr << "Warning, ignored search annotation: ";
212
 
    ann->print(std::cerr);
213
 
    std::cerr << std::endl;
214
 
    return SET_VAL_MIN_INC;
215
 
  }
 
354
        return SET_VAL_MAX_EXC();
 
355
    }
 
356
    std::cerr << "Warning, ignored search annotation: ";
 
357
    ann->print(std::cerr);
 
358
    std::cerr << std::endl;
 
359
    return SET_VAL_MIN_INC();
 
360
  }
 
361
#endif
 
362
 
 
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));
 
384
      }
 
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));
 
401
    }
 
402
    std::cerr << "Warning, ignored search annotation: ";
 
403
    ann->print(std::cerr);
 
404
    std::cerr << std::endl;
 
405
    return TieBreak<FloatVarBranch>(FLOAT_VAR_NONE());
 
406
  }
 
407
 
 
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();
 
414
    }
 
415
    std::cerr << "Warning, ignored search annotation: ";
 
416
    ann->print(std::cerr);
 
417
    std::cerr << std::endl;
 
418
    return FLOAT_VAL_SPLIT_MIN();
 
419
  }
 
420
 
216
421
#endif
217
422
 
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;
 
430
      
 
431
      if (needAuxVars) {
 
432
        IntVarArgs iva;
 
433
        for (int i=0; i<f.iv_aux.size(); i++) {
 
434
          if (!f.iv_aux[i].assigned()) {
 
435
            iva << IntVar();
 
436
            iva[iva.size()-1].update(*this, share, f.iv_aux[i]);
 
437
          }
 
438
        }
 
439
        iv_aux = IntVarArray(*this, iva);
 
440
      }
 
441
      
224
442
      bv.update(*this, share, f.bv);
225
443
      boolVarCount = f.boolVarCount;
 
444
      if (needAuxVars) {
 
445
        BoolVarArgs bva;
 
446
        for (int i=0; i<f.bv_aux.size(); i++) {
 
447
          if (!f.bv_aux[i].assigned()) {
 
448
            bva << BoolVar();
 
449
            bva[bva.size()-1].update(*this, share, f.bv_aux[i]);
 
450
          }
 
451
        }
 
452
        bv_aux = BoolVarArray(*this, bva);
 
453
      }
 
454
 
226
455
#ifdef GECODE_HAS_SET_VARS
227
456
      sv.update(*this, share, f.sv);
228
457
      setVarCount = f.setVarCount;
 
458
      if (needAuxVars) {
 
459
        SetVarArgs sva;
 
460
        for (int i=0; i<f.sv_aux.size(); i++) {
 
461
          if (!f.sv_aux[i].assigned()) {
 
462
            sva << SetVar();
 
463
            sva[sva.size()-1].update(*this, share, f.sv_aux[i]);
 
464
          }
 
465
        }
 
466
        sv_aux = SetVarArray(*this, sva);
 
467
      }
 
468
#endif
 
469
#ifdef GECODE_HAS_FLOAT_VARS
 
470
      fv.update(*this, share, f.fv);
 
471
      floatVarCount = f.floatVarCount;
 
472
      if (needAuxVars) {
 
473
        FloatVarArgs fva;
 
474
        for (int i=0; i<f.fv_aux.size(); i++) {
 
475
          if (!f.fv_aux[i].assigned()) {
 
476
            fva << FloatVar();
 
477
            fva[fva.size()-1].update(*this, share, f.fv_aux[i]);
 
478
          }
 
479
        }
 
480
        fv_aux = FloatVarArray(*this, fva);
 
481
      }
229
482
#endif
230
483
    }
231
484
  
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) {}
235
488
 
236
489
  void
237
490
  FlatZincSpace::init(int intVars, int boolVars,
238
 
#ifdef GECODE_HAS_SET_VARS
239
 
                                 int setVars) {
240
 
#else
241
 
                                 int) {
242
 
#endif
 
491
                      int setVars, int floatVars) {
 
492
    (void) setVars;
 
493
    (void) floatVars;
 
494
 
243
495
    intVarCount = 0;
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
251
503
    setVarCount = 0;
252
504
    sv = SetVarArray(*this, setVars);
253
 
    sv_introduced = std::vector<bool>(setVars);
 
505
    sv_introduced = std::vector<bool>(2*setVars);
 
506
#endif
 
507
#ifdef GECODE_HAS_FLOAT_VARS
 
508
    floatVarCount = 0;
 
509
    fv = FloatVarArray(*this, floatVars);
 
510
    fv_introduced = std::vector<bool>(2*floatVars);
254
511
#endif
255
512
  }
256
513
 
267
524
        iv[intVarCount++] = IntVar(*this, dom);
268
525
      }
269
526
    }
270
 
    iv_introduced[intVarCount-1] = vs->introduced;
 
527
    iv_introduced[2*(intVarCount-1)] = vs->introduced;
 
528
    iv_introduced[2*(intVarCount-1)+1] = vs->funcDep;
271
529
    iv_boolalias[intVarCount-1] = -1;
272
530
  }
273
531
 
287
545
    } else {
288
546
      bv[boolVarCount++] = BoolVar(*this, vs2bsl(vs), vs2bsh(vs));
289
547
    }
290
 
    bv_introduced[boolVarCount-1] = vs->introduced;
 
548
    bv_introduced[2*(boolVarCount-1)] = vs->introduced;
 
549
    bv_introduced[2*(boolVarCount-1)+1] = vs->funcDep;
291
550
  }
292
551
 
293
552
#ifdef GECODE_HAS_SET_VARS
327
586
                                 IntSet(Set::Limits::min, 
328
587
                                        Set::Limits::max));
329
588
    }
330
 
    sv_introduced[setVarCount-1] = vs->introduced;
 
589
    sv_introduced[2*(setVarCount-1)] = vs->introduced;
 
590
    sv_introduced[2*(setVarCount-1)+1] = vs->funcDep;
331
591
  }
332
592
#else
333
593
  void
336
596
  }
337
597
#endif
338
598
 
 
599
#ifdef GECODE_HAS_FLOAT_VARS
 
600
  void
 
601
  FlatZincSpace::newFloatVar(FloatVarSpec* vs) {
 
602
    if (vs->alias) {
 
603
      fv[floatVarCount++] = fv[vs->i];
 
604
    } else {
 
605
      double dmin, dmax;
 
606
      if (vs->domain()) {
 
607
        dmin = vs->domain.some().first;
 
608
        dmax = vs->domain.some().second;
 
609
        if (dmin > dmax) {
 
610
          fail();
 
611
          return;
 
612
        }
 
613
      } else {
 
614
        dmin = Float::Limits::min;
 
615
        dmax = Float::Limits::max;
 
616
      }
 
617
      fv[floatVarCount++] = FloatVar(*this, dmin, dmax);
 
618
    }
 
619
    fv_introduced[2*(floatVarCount-1)] = vs->introduced;
 
620
    fv_introduced[2*(floatVarCount-1)+1] = vs->funcDep;
 
621
  }
 
622
#else
 
623
  void
 
624
  FlatZincSpace::newFloatVar(FloatVarSpec*) {
 
625
    throw FlatZinc::Error("Gecode", "float variables not supported");
 
626
  }
 
627
#endif
 
628
 
339
629
  void
340
630
  FlatZincSpace::postConstraint(const ConExpr& ce, AST::Node* ann) {
341
631
    try {
362
652
  }
363
653
 
364
654
  void
365
 
  FlatZincSpace::createBranchers(AST::Node* ann, int seed,
 
655
  FlatZincSpace::createBranchers(AST::Node* ann, int seed, double decay,
366
656
                                 bool ignoreUnknown,
367
657
                                 std::ostream& err) {
368
 
    VarBranchOptions varbo;
369
 
    varbo.seed = seed;
370
 
    ValBranchOptions valbo;
371
 
    valbo.seed = seed;
372
658
    if (ann) {
373
659
      std::vector<AST::Node*> flatAnn;
374
660
      if (ann->isArray()) {
381
667
        if (flatAnn[i]->isCall("gecode_search")) {
382
668
          AST::Call* c = flatAnn[i]->getCall();
383
669
          branchWithPlugin(c->args);
384
 
        } else try {
 
670
        } else if (flatAnn[i]->isCall("int_search")) {
385
671
          AST::Call *call = flatAnn[i]->getCall("int_search");
386
672
          AST::Array *args = call->getArgs(4);
387
673
          AST::Array *vars = args->a[0]->getArray();
396
682
              continue;
397
683
            va[k++] = iv[vars->a[i]->getIntVar()];
398
684
          }
399
 
          branch(*this, va, ann2ivarsel(args->a[1]), ann2ivalsel(args->a[2]),
400
 
                 varbo,valbo);
401
 
        } catch (AST::TypeError& e) {
402
 
        try {
 
685
          branch(*this, va, 
 
686
                 ann2ivarsel(args->a[1],seed,decay), 
 
687
                 ann2ivalsel(args->a[2],seed));
 
688
        } else if (flatAnn[i]->isCall("int_assign")) {
403
689
          AST::Call *call = flatAnn[i]->getCall("int_assign");
404
690
          AST::Array *args = call->getArgs(2);
405
691
          AST::Array *vars = args->a[0]->getArray();
414
700
              continue;
415
701
            va[k++] = iv[vars->a[i]->getIntVar()];
416
702
          }
417
 
          assign(*this, va, ann2asnivalsel(args->a[1]));
418
 
        } catch (AST::TypeError& e) {
419
 
          (void) e;
420
 
          try {
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())
427
 
                k--;
428
 
            BoolVarArgs va(k);
429
 
            k=0;
430
 
            for (unsigned int i=0; i<vars->a.size(); i++) {
431
 
              if (vars->a[i]->isBool())
432
 
                continue;
433
 
              va[k++] = bv[vars->a[i]->getBoolVar()];
434
 
            }
435
 
            branch(*this, va, ann2ivarsel(args->a[1]), 
436
 
                   ann2ivalsel(args->a[2]), varbo, valbo);
437
 
          } catch (AST::TypeError& e) {
438
 
            (void) 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())
 
711
              k--;
 
712
          BoolVarArgs va(k);
 
713
          k=0;
 
714
          for (unsigned int i=0; i<vars->a.size(); i++) {
 
715
            if (vars->a[i]->isBool())
 
716
              continue;
 
717
            va[k++] = bv[vars->a[i]->getBoolVar()];
 
718
          }
 
719
          branch(*this, va, 
 
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
440
 
            try {
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())
447
 
                  k--;
448
 
              SetVarArgs va(k);
449
 
              k=0;
450
 
              for (unsigned int i=0; i<vars->a.size(); i++) {
451
 
                if (vars->a[i]->isSet())
452
 
                  continue;
453
 
                va[k++] = sv[vars->a[i]->getSetVar()];
454
 
              }
455
 
              branch(*this, va, ann2svarsel(args->a[1]), 
456
 
                     ann2svalsel(args->a[2]), varbo, valbo);
457
 
            } catch (AST::TypeError& e) {
458
 
              (void) e;
459
 
              if (!ignoreUnknown) {
460
 
                err << "Warning, ignored search annotation: ";
461
 
                flatAnn[i]->print(err);
462
 
                err << std::endl;
463
 
              }
464
 
            }
 
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())
 
730
              k--;
 
731
          SetVarArgs va(k);
 
732
          k=0;
 
733
          for (unsigned int i=0; i<vars->a.size(); i++) {
 
734
            if (vars->a[i]->isSet())
 
735
              continue;
 
736
            va[k++] = sv[vars->a[i]->getSetVar()];
 
737
          }
 
738
          branch(*this, va, 
 
739
                 ann2svarsel(args->a[1],seed,decay), 
 
740
                 ann2svalsel(args->a[2],seed));
465
741
#else
466
 
            if (!ignoreUnknown) {
467
 
              err << "Warning, ignored search annotation: ";
468
 
              flatAnn[i]->print(err);
469
 
              err << std::endl;
470
 
            }
471
 
#endif
472
 
          }
473
 
        }
 
742
          if (!ignoreUnknown) {
 
743
            err << "Warning, ignored search annotation: ";
 
744
            flatAnn[i]->print(err);
 
745
            err << std::endl;
 
746
          }
 
747
#endif
 
748
        }
 
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())
 
757
              k--;
 
758
          FloatVarArgs va(k);
 
759
          k=0;
 
760
          for (unsigned int i=0; i<vars->a.size(); i++) {
 
761
            if (vars->a[i]->isFloat())
 
762
              continue;
 
763
            va[k++] = fv[vars->a[i]->getFloatVar()];
 
764
          }
 
765
          branch(*this, va,
 
766
                 ann2fvarsel(args->a[2],seed,decay), 
 
767
                 ann2fvalsel(args->a[3]));
 
768
        }
 
769
#endif
 
770
        else {
 
771
          if (!ignoreUnknown) {
 
772
            err << "Warning, ignored search annotation: ";
 
773
            flatAnn[i]->print(err);
 
774
            err << std::endl;
 
775
          }
474
776
        }
475
777
      }
476
778
    }
477
779
    int introduced = 0;
 
780
    int funcdep = 0;
478
781
    for (int i=iv.size(); i--;)
479
 
      if (iv_introduced[i])
480
 
        introduced++;
481
 
    IntVarArgs iv_sol(iv.size()-introduced);
 
782
      if (iv_introduced[2*i]) {
 
783
        if (iv_introduced[2*i+1]) {
 
784
          funcdep++;
 
785
        } else {
 
786
          introduced++;
 
787
        }
 
788
      }
 
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])
485
 
        iv_tmp[j++] = iv[i];
486
 
      else
 
792
      if (iv_introduced[2*i]) {
 
793
        if (!iv_introduced[2*i+1]) {
 
794
          iv_tmp[j++] = iv[i];
 
795
        }
 
796
      } else {
487
797
        iv_sol[k++] = iv[i];
 
798
      }
488
799
 
489
800
    introduced = 0;
 
801
    funcdep = 0;
490
802
    for (int i=bv.size(); i--;)
491
 
      if (bv_introduced[i])
492
 
        introduced++;
493
 
    BoolVarArgs bv_sol(bv.size()-introduced);
 
803
      if (bv_introduced[2*i]) {
 
804
        if (bv_introduced[2*i+1]) {
 
805
          funcdep++;
 
806
        } else {
 
807
          introduced++;
 
808
        }
 
809
      }
 
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])
497
 
        bv_tmp[j++] = bv[i];
498
 
      else
 
813
      if (bv_introduced[2*i]) {
 
814
        if (!bv_introduced[2*i+1]) {
 
815
          bv_tmp[j++] = bv[i];
 
816
        }
 
817
      } else {
499
818
        bv_sol[k++] = bv[i];
500
 
 
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);
 
819
      }
 
820
 
 
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
 
824
    introduced = 0;
 
825
    funcdep = 0;
 
826
    for (int i=fv.size(); i--;)
 
827
      if (fv_introduced[2*i]) {
 
828
        if (fv_introduced[2*i+1]) {
 
829
          funcdep++;
 
830
        } else {
 
831
          introduced++;
 
832
        }
 
833
      }
 
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]) {
 
839
          fv_tmp[j++] = fv[i];
 
840
        }
 
841
      } else {
 
842
        fv_sol[k++] = fv[i];
 
843
      }
 
844
 
 
845
    branch(*this, fv_sol, FLOAT_VAR_SIZE_MIN(), FLOAT_VAL_SPLIT_MIN());
 
846
#endif
503
847
#ifdef GECODE_HAS_SET_VARS
504
848
    introduced = 0;
 
849
    funcdep = 0;
505
850
    for (int i=sv.size(); i--;)
506
 
      if (sv_introduced[i])
507
 
        introduced++;
508
 
    SetVarArgs sv_sol(sv.size()-introduced);
 
851
      if (sv_introduced[2*i]) {
 
852
        if (sv_introduced[2*i+1]) {
 
853
          funcdep++;
 
854
        } else {
 
855
          introduced++;
 
856
        }
 
857
      }
 
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])
512
 
        sv_tmp[j++] = sv[i];
513
 
      else
 
861
      if (sv_introduced[2*i]) {
 
862
        if (!sv_introduced[2*i+1]) {
 
863
          sv_tmp[j++] = sv[i];
 
864
        }
 
865
      } else {
514
866
        sv_sol[k++] = sv[i];
515
 
    branch(*this, sv_sol, SET_VAR_SIZE_AFC_MIN, SET_VAL_MIN_INC);
 
867
      }
 
868
 
 
869
    branch(*this, sv_sol, SET_VAR_AFC_SIZE_MAX(0.99), SET_VAL_MIN_INC());
516
870
#endif
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);
521
 
#endif
 
874
    sv_aux = SetVarArray(*this, sv_tmp);
 
875
#endif
 
876
#ifdef GECODE_HAS_FLOAT_VARS
 
877
    fv_aux = FloatVarArray(*this, fv_tmp);
 
878
#endif
 
879
    AuxVarBrancher::post(*this);
522
880
  }
523
881
 
524
882
  AST::Array*
586
944
  class GistEngine<DFS<S> > {
587
945
  public:
588
946
    static void explore(S* root, const FlatZincOptions& opt,
589
 
                        Gist::Inspector* i) {
 
947
                        Gist::Inspector* i, Gist::Comparator* c) {
590
948
      Gecode::Gist::Options o;
591
949
      o.c_d = opt.c_d(); o.a_d = opt.a_d();
592
950
      o.inspect.click(i);
 
951
      o.inspect.compare(c);
593
952
      (void) Gecode::Gist::dfs(root, o);
594
953
    }
595
954
  };
599
958
  class GistEngine<BAB<S> > {
600
959
  public:
601
960
    static void explore(S* root, const FlatZincOptions& opt,
602
 
                        Gist::Inspector* i) {
603
 
      Gecode::Gist::Options o;
604
 
      o.c_d = opt.c_d(); o.a_d = opt.a_d();
605
 
      o.inspect.click(i);
606
 
      (void) Gecode::Gist::bab(root, o);
607
 
    }
608
 
  };
609
 
 
610
 
  /// Specialization for Restart
611
 
  template<typename S>
612
 
  class GistEngine<Restart<S> > {
613
 
  public:
614
 
    static void explore(S* root, const FlatZincOptions& opt,
615
 
                        Gist::Inspector* i) {
616
 
      Gecode::Gist::Options o;
617
 
      o.c_d = opt.c_d(); o.a_d = opt.a_d();
618
 
      o.inspect.click(i);
 
961
                        Gist::Inspector* i, Gist::Comparator* c) {
 
962
      Gecode::Gist::Options o;
 
963
      o.c_d = opt.c_d(); o.a_d = opt.a_d();
 
964
      o.inspect.click(i);
 
965
      o.inspect.compare(c);
619
966
      (void) Gecode::Gist::bab(root, o);
620
967
    }
621
968
  };
653
1000
    Gecode::Gist::TextOutput::finalize();
654
1001
  }
655
1002
 
 
1003
  template<class S>
 
1004
  class FZPrintingComparator
 
1005
  : public Gecode::Gist::VarComparator<S> {
 
1006
  private:
 
1007
    const Printer& p;
 
1008
  public:
 
1009
    /// Constructor
 
1010
    FZPrintingComparator(const Printer& p0);
 
1011
 
 
1012
    /// Use the compare method of the template class S to compare two spaces
 
1013
    virtual void compare(const Space& s0, const Space& s1);
 
1014
  };
 
1015
 
 
1016
  template<class S>
 
1017
  FZPrintingComparator<S>::FZPrintingComparator(const Printer& p0)
 
1018
  : Gecode::Gist::VarComparator<S>("Gecode/FlatZinc"), p(p0) {}
 
1019
 
 
1020
  template<class S>
 
1021
  void
 
1022
  FZPrintingComparator<S>::compare(const Space& s0, const Space& s1) {
 
1023
    this->init();
 
1024
    try {
 
1025
      dynamic_cast<const S&>(s0).compare(dynamic_cast<const S&>(s1),
 
1026
                                         this->getStream(), p);
 
1027
    } catch (Exception& e) {
 
1028
      this->getStream() << "Exception: " << e.what();
 
1029
    }
 
1030
    this->getStream() << std::endl;
 
1031
  }
 
1032
 
656
1033
#endif
657
1034
 
 
1035
 
658
1036
  template<template<class> class Engine>
659
1037
  void
660
1038
  FlatZincSpace::runEngine(std::ostream& out, const Printer& p,
661
 
                            const FlatZincOptions& opt, Support::Timer& t_total) {
 
1039
                           const FlatZincOptions& opt, Support::Timer& t_total) {
 
1040
    if (opt.restart()==RM_NONE) {
 
1041
      runMeta<Engine,Driver::EngineToMeta>(out,p,opt,t_total);
 
1042
    } else {
 
1043
      runMeta<Engine,RBS>(out,p,opt,t_total);
 
1044
    }
 
1045
  }
 
1046
 
 
1047
  template<template<class> class Engine,
 
1048
           template<template<class> class,class> class Meta>
 
1049
  void
 
1050
  FlatZincSpace::runMeta(std::ostream& out, const Printer& p,
 
1051
                         const FlatZincOptions& opt, Support::Timer& t_total) {
662
1052
#ifdef GECODE_HAS_GIST
663
1053
    if (opt.mode() == SM_GIST) {
664
1054
      FZPrintingInspector<FlatZincSpace> pi(p);
665
 
      (void) GistEngine<Engine<FlatZincSpace> >::explore(this,opt,&pi);
 
1055
      FZPrintingComparator<FlatZincSpace> pc(p);
 
1056
      (void) GistEngine<Engine<FlatZincSpace> >::explore(this,opt,&pi,&pc);
666
1057
      return;
667
1058
    }
668
1059
#endif
674
1065
      n_p = propagators();
675
1066
    }
676
1067
    Search::Options o;
677
 
    o.stop = Driver::Cutoff::create(opt.node(), opt.fail(), opt.time(), 
678
 
                                    true);
 
1068
    o.stop = Driver::CombinedStop::create(opt.node(), opt.fail(), opt.time(), 
 
1069
                                          true);
679
1070
    o.c_d = opt.c_d();
680
1071
    o.a_d = opt.a_d();
681
1072
    o.threads = opt.threads();
682
 
    Driver::Cutoff::installCtrlHandler(true);
683
 
    Engine<FlatZincSpace> se(this,o);
 
1073
    o.cutoff  = Driver::createCutoff(opt);
 
1074
    if (opt.interrupt())
 
1075
      Driver::CombinedStop::installCtrlHandler(true);
 
1076
    Meta<Engine,FlatZincSpace> se(this,o);
684
1077
    int noOfSolutions = _method == SAT ? opt.solutions() : 0;
685
1078
    bool printAll = _method == SAT || opt.allSolutions();
686
1079
    int findSol = noOfSolutions;
710
1103
    }
711
1104
    delete sol;
712
1105
    stopped:
713
 
    Driver::Cutoff::installCtrlHandler(false);
 
1106
    if (opt.interrupt())
 
1107
      Driver::CombinedStop::installCtrlHandler(false);
714
1108
    if (opt.mode() == SM_STAT) {
715
1109
      Gecode::Search::Statistics stat = se.statistics();
716
1110
      out << endl
728
1122
           << "%%  propagations:  " << sstat.propagate+stat.propagate << endl
729
1123
           << "%%  nodes:         " << stat.node << endl
730
1124
           << "%%  failures:      " << stat.fail << endl
 
1125
           << "%%  restarts:      " << stat.restart << endl
731
1126
           << "%%  peak depth:    " << stat.depth << endl
732
1127
           << "%%  peak memory:   "
733
1128
           << static_cast<int>((stat.memory+1023) / 1024) << " KB"
766
1161
  }
767
1162
#else
768
1163
  void
769
 
  FlatZincSpace::branchWithPlugin(AST::Node* ann) {
 
1164
  FlatZincSpace::branchWithPlugin(AST::Node*) {
770
1165
    throw FlatZinc::Error("FlatZinc",
771
1166
      "Branching with plugins not supported (requires Qt support)");
772
1167
  }
778
1173
    switch (_method) {
779
1174
    case MIN:
780
1175
    case MAX:
781
 
      if (opt.search() == FlatZincOptions::FZ_SEARCH_BAB)
782
 
        runEngine<BAB>(out,p,opt,t_total);
783
 
      else
784
 
        runEngine<Restart>(out,p,opt,t_total);
 
1176
      runEngine<BAB>(out,p,opt,t_total);
785
1177
      break;
786
1178
    case SAT:
787
1179
      runEngine<DFS>(out,p,opt,t_total);
820
1212
#ifdef GECODE_HAS_SET_VARS
821
1213
    , sv
822
1214
#endif
 
1215
#ifdef GECODE_HAS_FLOAT_VARS
 
1216
    , fv
 
1217
#endif
 
1218
    );
 
1219
  }
 
1220
 
 
1221
  void
 
1222
  FlatZincSpace::compare(const Space& s, std::ostream& out) const {
 
1223
    (void) s; (void) out;
 
1224
#ifdef GECODE_HAS_GIST
 
1225
    const FlatZincSpace& fs = dynamic_cast<const FlatZincSpace&>(s);
 
1226
    for (int i = 0; i < iv.size(); ++i) {
 
1227
      std::stringstream ss;
 
1228
      ss << "iv[" << i << "]";
 
1229
      std::string result(Gecode::Gist::Comparator::compare(ss.str(), iv[i],
 
1230
                                                           fs.iv[i]));
 
1231
      if (result.length() > 0) out << result << std::endl;
 
1232
    }
 
1233
    for (int i = 0; i < bv.size(); ++i) {
 
1234
      std::stringstream ss;
 
1235
      ss << "bv[" << i << "]";
 
1236
      std::string result(Gecode::Gist::Comparator::compare(ss.str(), bv[i],
 
1237
                                                           fs.bv[i]));
 
1238
      if (result.length() > 0) out << result << std::endl;
 
1239
    }
 
1240
#ifdef GECODE_HAS_SET_VARS
 
1241
    for (int i = 0; i < sv.size(); ++i) {
 
1242
      std::stringstream ss;
 
1243
      ss << "sv[" << i << "]";
 
1244
      std::string result(Gecode::Gist::Comparator::compare(ss.str(), sv[i],
 
1245
                                                           fs.sv[i]));
 
1246
      if (result.length() > 0) out << result << std::endl;
 
1247
    }
 
1248
#endif
 
1249
#ifdef GECODE_HAS_FLOAT_VARS
 
1250
    for (int i = 0; i < fv.size(); ++i) {
 
1251
      std::stringstream ss;
 
1252
      ss << "fv[" << i << "]";
 
1253
      std::string result(Gecode::Gist::Comparator::compare(ss.str(), fv[i],
 
1254
                                                           fs.fv[i]));
 
1255
      if (result.length() > 0) out << result << std::endl;
 
1256
    }
 
1257
#endif
 
1258
#endif
 
1259
  }
 
1260
 
 
1261
  void
 
1262
  FlatZincSpace::compare(const FlatZincSpace& s, std::ostream& out,
 
1263
                         const Printer& p) const {
 
1264
    p.printDiff(out, iv, s.iv, bv, s.bv
 
1265
#ifdef GECODE_HAS_SET_VARS
 
1266
     , sv, s.sv
 
1267
#endif
 
1268
#ifdef GECODE_HAS_FLOAT_VARS
 
1269
     , fv, s.fv
 
1270
#endif
823
1271
    );
824
1272
  }
825
1273
 
829
1277
#ifdef GECODE_HAS_SET_VARS
830
1278
    , sv
831
1279
#endif
 
1280
#ifdef GECODE_HAS_FLOAT_VARS
 
1281
    , fv
 
1282
#endif
832
1283
    );
833
1284
  }
834
1285
 
 
1286
  IntArgs
 
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--;)
 
1291
      ia[i] = 0;
 
1292
    for (int i=a->a.size(); i--;)
 
1293
      ia[i+offset] = a->a[i]->getInt();
 
1294
    return ia;
 
1295
  }
 
1296
  IntArgs
 
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--;)
 
1301
      ia[i] = 0;
 
1302
    for (int i=a->a.size(); i--;)
 
1303
      ia[i+offset] = a->a[i]->getBool();
 
1304
    return ia;
 
1305
  }
 
1306
  IntSet
 
1307
  FlatZincSpace::arg2intset(AST::Node* n) {
 
1308
    AST::SetLit* sl = n->getSet();
 
1309
    IntSet d;
 
1310
    if (sl->interval) {
 
1311
      d = IntSet(sl->min, sl->max);
 
1312
    } else {
 
1313
      Region re(*this);
 
1314
      int* is = re.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
 
1315
      for (int i=sl->s.size(); i--; )
 
1316
        is[i] = sl->s[i];
 
1317
      d = IntSet(is, sl->s.size());
 
1318
    }
 
1319
    return d;
 
1320
  }
 
1321
  IntSetArgs
 
1322
  FlatZincSpace::arg2intsetargs(AST::Node* arg, int offset) {
 
1323
    AST::Array* a = arg->getArray();
 
1324
    if (a->a.size() == 0) {
 
1325
      IntSetArgs emptyIa(0);
 
1326
      return emptyIa;
 
1327
    }
 
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]);
 
1333
    }
 
1334
    return ia;
 
1335
  }
 
1336
  IntVarArgs
 
1337
  FlatZincSpace::arg2intvarargs(AST::Node* arg, int offset) {
 
1338
    AST::Array* a = arg->getArray();
 
1339
    if (a->a.size() == 0) {
 
1340
      IntVarArgs emptyIa(0);
 
1341
      return emptyIa;
 
1342
    }
 
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()];        
 
1349
      } else {
 
1350
        int value = a->a[i]->getInt();
 
1351
        IntVar iv(*this, value, value);
 
1352
        ia[i+offset] = iv;        
 
1353
      }
 
1354
    }
 
1355
    return ia;
 
1356
  }
 
1357
  BoolVarArgs
 
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);
 
1362
      return emptyIa;
 
1363
    }
 
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++) {
 
1368
      if (i==siv)
 
1369
        continue;
 
1370
      if (a->a[i]->isBool()) {
 
1371
        bool value = a->a[i]->getBool();
 
1372
        BoolVar iv(*this, value, value);
 
1373
        ia[offset++] = iv;
 
1374
      } else if (a->a[i]->isIntVar() &&
 
1375
                 aliasBool2Int(a->a[i]->getIntVar()) != -1) {
 
1376
        ia[offset++] = bv[aliasBool2Int(a->a[i]->getIntVar())];
 
1377
      } else {
 
1378
        ia[offset++] = bv[a->a[i]->getBoolVar()];
 
1379
      }
 
1380
    }
 
1381
    return ia;
 
1382
  }
 
1383
  BoolVar
 
1384
  FlatZincSpace::arg2BoolVar(AST::Node* n) {
 
1385
    BoolVar x0;
 
1386
    if (n->isBool()) {
 
1387
      x0 = BoolVar(*this, n->getBool(), n->getBool());
 
1388
    }
 
1389
    else {
 
1390
      x0 = bv[n->getBoolVar()];
 
1391
    }
 
1392
    return x0;
 
1393
  }
 
1394
  IntVar
 
1395
  FlatZincSpace::arg2IntVar(AST::Node* n) {
 
1396
    IntVar x0;
 
1397
    if (n->isIntVar()) {
 
1398
      x0 = iv[n->getIntVar()];
 
1399
    } else {
 
1400
      x0 = IntVar(*this, n->getInt(), n->getInt());            
 
1401
    }
 
1402
    return x0;
 
1403
  }
 
1404
  bool
 
1405
  FlatZincSpace::isBoolArray(AST::Node* b, int& singleInt) {
 
1406
    AST::Array* a = b->getArray();
 
1407
    singleInt = -1;
 
1408
    if (a->a.size() == 0)
 
1409
      return true;
 
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) {
 
1415
            return false;
 
1416
          }
 
1417
          singleInt = i;
 
1418
        }
 
1419
      } else {
 
1420
        return false;
 
1421
      }
 
1422
    }
 
1423
    return singleInt==-1 || a->a.size() > 1;
 
1424
  }
 
1425
#ifdef GECODE_HAS_SET_VARS
 
1426
  SetVar
 
1427
  FlatZincSpace::arg2SetVar(AST::Node* n) {
 
1428
    SetVar x0;
 
1429
    if (!n->isSetVar()) {
 
1430
      IntSet d = arg2intset(n);
 
1431
      x0 = SetVar(*this, d, d);
 
1432
    } else {
 
1433
      x0 = sv[n->getSetVar()];
 
1434
    }
 
1435
    return x0;
 
1436
  }
 
1437
  SetVarArgs
 
1438
  FlatZincSpace::arg2setvarargs(AST::Node* arg, int offset, int doffset,
 
1439
                                const IntSet& od) {
 
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);
 
1445
    }
 
1446
    for (int i=a->a.size(); i--;) {
 
1447
      ia[i+offset] = arg2SetVar(a->a[i]);
 
1448
    }
 
1449
    return ia;
 
1450
  }
 
1451
#endif
 
1452
#ifdef GECODE_HAS_FLOAT_VARS
 
1453
  FloatValArgs
 
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--;)
 
1458
      fa[i] = 0.0;
 
1459
    for (int i=a->a.size(); i--;)
 
1460
      fa[i+offset] = a->a[i]->getFloat();
 
1461
    return fa;
 
1462
  }
 
1463
  FloatVarArgs
 
1464
  FlatZincSpace::arg2floatvarargs(AST::Node* arg, int offset) {
 
1465
    AST::Array* a = arg->getArray();
 
1466
    if (a->a.size() == 0) {
 
1467
      FloatVarArgs emptyFa(0);
 
1468
      return emptyFa;
 
1469
    }
 
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()];        
 
1476
      } else {
 
1477
        double value = a->a[i]->getFloat();
 
1478
        FloatVar fv(*this, value, value);
 
1479
        fa[i+offset] = fv;
 
1480
      }
 
1481
    }
 
1482
    return fa;
 
1483
  }
 
1484
  FloatVar
 
1485
  FlatZincSpace::arg2FloatVar(AST::Node* n) {
 
1486
    FloatVar x0;
 
1487
    if (n->isFloatVar()) {
 
1488
      x0 = fv[n->getFloatVar()];
 
1489
    } else {
 
1490
      x0 = FloatVar(*this, n->getFloat(), n->getFloat());
 
1491
    }
 
1492
    return x0;
 
1493
  }
 
1494
#endif
 
1495
  IntConLevel
 
1496
  FlatZincSpace::ann2icl(AST::Node* ann) {
 
1497
    if (ann) {
 
1498
      if (ann->hasAtom("val"))
 
1499
        return ICL_VAL;
 
1500
      if (ann->hasAtom("domain"))
 
1501
        return ICL_DOM;
 
1502
      if (ann->hasAtom("bounds") ||
 
1503
          ann->hasAtom("boundsR") ||
 
1504
          ann->hasAtom("boundsD") ||
 
1505
          ann->hasAtom("boundsZ"))
 
1506
        return ICL_BND;
 
1507
    }
 
1508
    return ICL_DEF;
 
1509
  }
 
1510
 
 
1511
 
835
1512
  void
836
1513
  Printer::init(AST::Array* output) {
837
1514
    _output = output;
845
1522
#ifdef GECODE_HAS_SET_VARS
846
1523
                       , const Gecode::SetVarArray& sv
847
1524
#endif
 
1525
#ifdef GECODE_HAS_FLOAT_VARS
 
1526
                       ,
 
1527
                       const Gecode::FloatVarArray& fv
 
1528
#endif
848
1529
                       ) const {
849
1530
    int k;
850
1531
    if (ai->isInt(k)) {
885
1566
        out << min << ".." << max;
886
1567
      }
887
1568
#endif
888
 
    } else if (ai->isBool()) {
889
 
      out << (ai->getBool() ? "true" : "false");
890
 
    } else if (ai->isSet()) {
891
 
      AST::SetLit* s = ai->getSet();
892
 
      if (s->interval) {
893
 
        out << s->min << ".." << s->max;
894
 
      } else {
895
 
        out << "{";
896
 
        for (unsigned int i=0; i<s->s.size(); i++) {
897
 
          out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
898
 
        }
899
 
      }
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) {
904
 
          switch (s[i+1]) {
905
 
          case 'n': out << "\n"; break;
906
 
          case '\\': out << "\\"; break;
907
 
          case 't': out << "\t"; break;
908
 
          default: out << "\\" << s[i+1];
909
 
          }
910
 
          i++;
911
 
        } else {
912
 
          out << s[i];
913
 
        }
914
 
      }
915
 
    }
 
1569
#ifdef GECODE_HAS_FLOAT_VARS
 
1570
    } else if (ai->isFloatVar()) {
 
1571
      out << fv[ai->getFloatVar()];
 
1572
#endif
 
1573
    } else if (ai->isBool()) {
 
1574
      out << (ai->getBool() ? "true" : "false");
 
1575
    } else if (ai->isSet()) {
 
1576
      AST::SetLit* s = ai->getSet();
 
1577
      if (s->interval) {
 
1578
        out << s->min << ".." << s->max;
 
1579
      } else {
 
1580
        out << "{";
 
1581
        for (unsigned int i=0; i<s->s.size(); i++) {
 
1582
          out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
 
1583
        }
 
1584
      }
 
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) {
 
1589
          switch (s[i+1]) {
 
1590
          case 'n': out << "\n"; break;
 
1591
          case '\\': out << "\\"; break;
 
1592
          case 't': out << "\t"; break;
 
1593
          default: out << "\\" << s[i+1];
 
1594
          }
 
1595
          i++;
 
1596
        } else {
 
1597
          out << s[i];
 
1598
        }
 
1599
      }
 
1600
    }
 
1601
  }
 
1602
 
 
1603
  void
 
1604
  Printer::printElemDiff(std::ostream& out,
 
1605
                       AST::Node* ai,
 
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
 
1613
#endif
 
1614
#ifdef GECODE_HAS_FLOAT_VARS
 
1615
                       , const Gecode::FloatVarArray& fv1,
 
1616
                       const Gecode::FloatVarArray& fv2
 
1617
#endif
 
1618
                       ) const {
 
1619
#ifdef GECODE_HAS_GIST
 
1620
    using namespace Gecode::Gist;
 
1621
    int k;
 
1622
    if (ai->isInt(k)) {
 
1623
      out << k;
 
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 '='
 
1629
        out << res;
 
1630
      } else {
 
1631
        out << iv1[ai->getIntVar()];
 
1632
      }
 
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 '='
 
1638
        out << res;
 
1639
      } else {
 
1640
        out << bv1[ai->getBoolVar()];
 
1641
      }
 
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 '='
 
1648
        out << res;
 
1649
      } else {
 
1650
        out << sv1[ai->getSetVar()];
 
1651
      }
 
1652
#endif
 
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 '='
 
1659
        out << res;
 
1660
      } else {
 
1661
        out << fv1[ai->getFloatVar()];
 
1662
      }
 
1663
#endif
 
1664
    } else if (ai->isBool()) {
 
1665
      out << (ai->getBool() ? "true" : "false");
 
1666
    } else if (ai->isSet()) {
 
1667
      AST::SetLit* s = ai->getSet();
 
1668
      if (s->interval) {
 
1669
        out << s->min << ".." << s->max;
 
1670
      } else {
 
1671
        out << "{";
 
1672
        for (unsigned int i=0; i<s->s.size(); i++) {
 
1673
          out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
 
1674
        }
 
1675
      }
 
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) {
 
1680
          switch (s[i+1]) {
 
1681
          case 'n': out << "\n"; break;
 
1682
          case '\\': out << "\\"; break;
 
1683
          case 't': out << "\t"; break;
 
1684
          default: out << "\\" << s[i+1];
 
1685
          }
 
1686
          i++;
 
1687
        } else {
 
1688
          out << s[i];
 
1689
        }
 
1690
      }
 
1691
    }
 
1692
#endif
916
1693
  }
917
1694
 
918
1695
  void
923
1700
                   ,
924
1701
                   const Gecode::SetVarArray& sv
925
1702
#endif
 
1703
#ifdef GECODE_HAS_FLOAT_VARS
 
1704
                   ,
 
1705
                   const Gecode::FloatVarArray& fv
 
1706
#endif
926
1707
                   ) const {
927
1708
    if (_output == NULL)
928
1709
      return;
937
1718
#ifdef GECODE_HAS_SET_VARS
938
1719
          ,sv
939
1720
#endif
 
1721
#ifdef GECODE_HAS_FLOAT_VARS
 
1722
          ,fv
 
1723
#endif
940
1724
          );
941
1725
          if (j<size-1)
942
1726
            out << ", ";
947
1731
#ifdef GECODE_HAS_SET_VARS
948
1732
        ,sv
949
1733
#endif
 
1734
#ifdef GECODE_HAS_FLOAT_VARS
 
1735
          ,fv
 
1736
#endif
 
1737
        );
 
1738
      }
 
1739
    }
 
1740
  }
 
1741
 
 
1742
  void
 
1743
  Printer::printDiff(std::ostream& out,
 
1744
                   const Gecode::IntVarArray& iv1,
 
1745
                   const Gecode::IntVarArray& iv2,
 
1746
                   const Gecode::BoolVarArray& bv1,
 
1747
                   const Gecode::BoolVarArray& bv2
 
1748
#ifdef GECODE_HAS_SET_VARS
 
1749
                   ,
 
1750
                   const Gecode::SetVarArray& sv1,
 
1751
                   const Gecode::SetVarArray& sv2
 
1752
#endif
 
1753
#ifdef GECODE_HAS_FLOAT_VARS
 
1754
                   ,
 
1755
                   const Gecode::FloatVarArray& fv1,
 
1756
                   const Gecode::FloatVarArray& fv2
 
1757
#endif
 
1758
                   ) const {
 
1759
    if (_output == NULL)
 
1760
      return;
 
1761
    for (unsigned int i=0; i< _output->a.size(); i++) {
 
1762
      AST::Node* ai = _output->a[i];
 
1763
      if (ai->isArray()) {
 
1764
        AST::Array* aia = ai->getArray();
 
1765
        int size = aia->a.size();
 
1766
        out << "[";
 
1767
        for (int j=0; j<size; j++) {
 
1768
          printElemDiff(out,aia->a[j],iv1,iv2,bv1,bv2
 
1769
#ifdef GECODE_HAS_SET_VARS
 
1770
            ,sv1,sv2
 
1771
#endif
 
1772
#ifdef GECODE_HAS_FLOAT_VARS
 
1773
            ,fv1,fv2
 
1774
#endif
 
1775
          );
 
1776
          if (j<size-1)
 
1777
            out << ", ";
 
1778
        }
 
1779
        out << "]";
 
1780
      } else {
 
1781
        printElemDiff(out,ai,iv1,iv2,bv1,bv2
 
1782
#ifdef GECODE_HAS_SET_VARS
 
1783
          ,sv1,sv2
 
1784
#endif
 
1785
#ifdef GECODE_HAS_FLOAT_VARS
 
1786
            ,fv1,fv2
 
1787
#endif
950
1788
        );
951
1789
      }
952
1790
    }
955
1793
  void
956
1794
  Printer::shrinkElement(AST::Node* node,
957
1795
                         std::map<int,int>& iv, std::map<int,int>& bv, 
958
 
                         std::map<int,int>& sv) {
 
1796
                         std::map<int,int>& sv, std::map<int,int>& fv) {
959
1797
    if (node->isIntVar()) {
960
1798
      AST::IntVar* x = static_cast<AST::IntVar*>(node);
961
1799
      if (iv.find(x->i) == iv.end()) {
977
1815
        sv[x->i] = newi;
978
1816
      }
979
1817
      x->i = sv[x->i];      
 
1818
    } else if (node->isFloatVar()) {
 
1819
      AST::FloatVar* x = static_cast<AST::FloatVar*>(node);
 
1820
      if (fv.find(x->i) == fv.end()) {
 
1821
        int newi = fv.size();
 
1822
        fv[x->i] = newi;
 
1823
      }
 
1824
      x->i = fv[x->i];      
980
1825
    }
981
1826
  }
982
1827
 
989
1834
                        ,
990
1835
                        Gecode::SetVarArray& sv
991
1836
#endif
 
1837
#ifdef GECODE_HAS_FLOAT_VARS
 
1838
                        ,
 
1839
                        Gecode::FloatVarArray& fv
 
1840
#endif
992
1841
                       ) {
993
1842
    if (_output == NULL) {
994
1843
      if (optVar == -1) {
1003
1852
#ifdef GECODE_HAS_SET_VARS
1004
1853
      sv = SetVarArray(home, 0);
1005
1854
#endif
 
1855
#ifdef GECODE_HAS_FLOAT_VARS
 
1856
      fv = FloatVarArray(home,0);
 
1857
#endif
1006
1858
      return;
1007
1859
    }
1008
1860
    std::map<int,int> iv_new;
1009
1861
    std::map<int,int> bv_new;
1010
1862
    std::map<int,int> sv_new;
 
1863
    std::map<int,int> fv_new;
1011
1864
 
1012
1865
    if (optVar != -1) {
1013
1866
      iv_new[optVar] = 0;
1019
1872
      if (ai->isArray()) {
1020
1873
        AST::Array* aia = ai->getArray();
1021
1874
        for (unsigned int j=0; j<aia->a.size(); j++) {
1022
 
          shrinkElement(aia->a[j],iv_new,bv_new,sv_new);
 
1875
          shrinkElement(aia->a[j],iv_new,bv_new,sv_new,fv_new);
1023
1876
        }
1024
1877
      } else {
1025
 
        shrinkElement(ai,iv_new,bv_new,sv_new);
 
1878
        shrinkElement(ai,iv_new,bv_new,sv_new,fv_new);
1026
1879
      }
1027
1880
    }
1028
1881
 
1045
1898
    }
1046
1899
    sv = SetVarArray(home, sva);
1047
1900
#endif
 
1901
 
 
1902
#ifdef GECODE_HAS_FLOAT_VARS
 
1903
    FloatVarArgs fva(fv_new.size());
 
1904
    for (map<int,int>::iterator i=fv_new.begin(); i != fv_new.end(); ++i) {
 
1905
      fva[(*i).second] = fv[(*i).first];
 
1906
    }
 
1907
    fv = FloatVarArray(home, fva);
 
1908
#endif
1048
1909
  }
1049
1910
 
1050
1911
  Printer::~Printer(void) {