Generated on for Gecode by doxygen 1.15.0
flatzinc.cpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Guido Tack <tack@gecode.dev>
5 *
6 * Contributing authors:
7 * Gabriel Hjort Blindell <gabriel.hjort.blindell@gmail.com>
8 * Nathan Tran <kieron.qtran@gmail.com>
9 *
10 * Copyright:
11 * Guido Tack, 2007-2012
12 * Gabriel Hjort Blindell, 2012
13 * Nathan Tran, 2025
14 *
15 * This file is part of Gecode, the generic constraint
16 * development environment:
17 * http://www.gecode.dev
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining
20 * a copy of this software and associated documentation files (the
21 * "Software"), to deal in the Software without restriction, including
22 * without limitation the rights to use, copy, modify, merge, publish,
23 * distribute, sublicense, and/or sell copies of the Software, and to
24 * permit persons to whom the Software is furnished to do so, subject to
25 * the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be
28 * included in all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 *
38 */
39
40#include <gecode/flatzinc.hh>
45
46#include <gecode/search.hh>
47
48#include <vector>
49#include <string>
50#include <sstream>
51#include <limits>
52#include <memory>
53#include <unordered_set>
54
55
56namespace std {
57
59 template<> struct hash<Gecode::TupleSet> {
61 forceinline size_t
62 operator()(const Gecode::TupleSet& x) const {
63 return x.hash();
64 }
65 };
66
68 template<> struct hash<Gecode::SharedArray<int> > {
70 forceinline size_t
72 size_t seed = static_cast<size_t>(x.size());
73 for (int i=x.size(); i--; )
74 Gecode::cmb_hash(seed, x[i]);
75 return seed;
76 }
77 };
78
80 template<> struct hash<Gecode::DFA> {
82 forceinline size_t operator()(const Gecode::DFA& d) const {
83 return d.hash();
84 }
85 };
86
87}
88
89namespace Gecode { namespace FlatZinc {
90
91 // Default random number generator
93
106 class AuxVarBrancher : public Brancher {
107 protected:
109 bool done;
112 IntValBranch int_valsel0,
113 TieBreak<BoolVarBranch> bool_varsel0,
114 BoolValBranch bool_valsel0
116 ,
117 SetVarBranch set_varsel0,
118 SetValBranch set_valsel0
119#endif
121 ,
122 TieBreak<FloatVarBranch> float_varsel0,
123 FloatValBranch float_valsel0
124#endif
125 )
126 : Brancher(home), done(false),
127 int_varsel(int_varsel0), int_valsel(int_valsel0),
128 bool_varsel(bool_varsel0), bool_valsel(bool_valsel0)
130 , set_varsel(set_varsel0), set_valsel(set_valsel0)
131#endif
133 , float_varsel(float_varsel0), float_valsel(float_valsel0)
134#endif
135 {}
136
138 : Brancher(home, b), done(b.done) {}
139
141 class Choice : public Gecode::Choice {
142 public:
144 bool fail;
146 Choice(const Brancher& b, bool fail0)
147 : Gecode::Choice(b,1), fail(fail0) {}
148
149 virtual size_t size(void) const {
150 return sizeof(Choice);
151 }
152
153 virtual void archive(Archive& e) const {
155 e.put(fail);
156 }
157 };
158
163#ifdef GECODE_HAS_SET_VARS
166#endif
167#ifdef GECODE_HAS_FLOAT_VARS
170#endif
171
172 public:
174 virtual bool status(const Space& _home) const {
175 if (done) return false;
176 const FlatZincSpace& home = static_cast<const FlatZincSpace&>(_home);
177 for (int i=0; i<home.iv_aux.size(); i++)
178 if (!home.iv_aux[i].assigned()) return true;
179 for (int i=0; i<home.bv_aux.size(); i++)
180 if (!home.bv_aux[i].assigned()) return true;
181#ifdef GECODE_HAS_SET_VARS
182 for (int i=0; i<home.sv_aux.size(); i++)
183 if (!home.sv_aux[i].assigned()) return true;
184#endif
185#ifdef GECODE_HAS_FLOAT_VARS
186 for (int i=0; i<home.fv_aux.size(); i++)
187 if (!home.fv_aux[i].assigned()) return true;
188#endif
189 // No non-assigned variables left
190 return false;
191 }
192
193 virtual Choice* choice(Space& home) {
194 done = true;
195 FlatZincSpace& fzs = static_cast<FlatZincSpace&>(*home.clone());
196 fzs.needAuxVars = false;
199#ifdef GECODE_HAS_SET_VARS
201#endif
202#ifdef GECODE_HAS_FLOAT_VARS
204#endif
205 Search::Options opt; opt.clone = false;
206 FlatZincSpace* sol = dfs(&fzs, opt);
207 if (sol) {
208 delete sol;
209 return new Choice(*this,false);
210 } else {
211 return new Choice(*this,true);
212 }
213 }
214
215 virtual Choice* choice(const Space&, Archive& e) {
216 bool fail; e >> fail;
217 return new Choice(*this, fail);
218 }
219
220 virtual ExecStatus commit(Space&, const Gecode::Choice& c, unsigned int) {
221 return static_cast<const Choice&>(c).fail ? ES_FAILED : ES_OK;
222 }
223
224 virtual void print(const Space&, const Gecode::Choice& c,
225 unsigned int,
226 std::ostream& o) const {
227 o << "FlatZinc("
228 << (static_cast<const Choice&>(c).fail ? "fail" : "ok")
229 << ")";
230 }
231
232 virtual Actor* copy(Space& home) {
233 return new (home) AuxVarBrancher(home, *this);
234 }
235
262
263 virtual size_t dispose(Space&) {
264 return sizeof(*this);
265 }
266 };
267
268 class BranchInformationO : public SharedHandle::Object {
269 private:
270 struct BI {
271 std::string r0;
272 std::string r1;
273 std::vector<std::string> n;
274 BI(void) : r0(""), r1(""), n(0) {}
275 BI(const std::string& r00, const std::string& r10,
276 const std::vector<std::string>& n0)
277 : r0(r00), r1(r10), n(n0) {}
278 };
279 std::vector<BI> v;
280 BranchInformationO(std::vector<BI> v0) : v(v0) {}
281 public:
283 virtual ~BranchInformationO(void) {}
284 virtual SharedHandle::Object* copy(void) const {
285 return new BranchInformationO(v);
286 }
287
289 const std::string& rel0,
290 const std::string& rel1,
291 const std::vector<std::string>& n) {
292 v.resize(std::max(static_cast<unsigned int>(v.size()),bg.id()+1));
293 v[bg.id()] = BI(rel0,rel1,n);
294 }
295
296 void print(const Brancher& b,
297 unsigned int a, int i, int n, std::ostream& o) const {
298 const BI& bi = v[b.group().id()];
299 o << bi.n[i] << " " << (a==0 ? bi.r0 : bi.r1) << " " << n;
300 }
301#ifdef GECODE_HAS_FLOAT_VARS
302 void print(const Brancher& b,
303 unsigned int a, int i, const FloatNumBranch& nl,
304 std::ostream& o) const {
305 const BI& bi = v[b.group().id()];
306 o << bi.n[i] << " "
307 << (((a == 0) == nl.l) ? "<=" : ">=") << nl.n;
308 }
309#endif
310 };
311
314
317
318 void
320 assert(object() == nullptr);
322 }
323
324 void
326 const std::string& rel0,
327 const std::string& rel1,
328 const std::vector<std::string>& n) {
329 static_cast<BranchInformationO*>(object())->add(bg,rel0,rel1,n);
330 }
331 void
332 BranchInformation::print(const Brancher& b, unsigned int a, int i,
333 int n, std::ostream& o) const {
334 static_cast<const BranchInformationO*>(object())->print(b,a,i,n,o);
335 }
336#ifdef GECODE_HAS_FLOAT_VARS
337 void
338 BranchInformation::print(const Brancher& b, unsigned int a, int i,
339 const FloatNumBranch& nl, std::ostream& o) const {
340 static_cast<const BranchInformationO*>(object())->print(b,a,i,nl,o);
341 }
342#endif
343 template<class Var>
344 void varValPrint(const Space &home, const Brancher& b,
345 unsigned int a,
346 Var, int i, const int& n,
347 std::ostream& o) {
348 static_cast<const FlatZincSpace&>(home).branchInfo.print(b,a,i,n,o);
349 }
350
351#ifdef GECODE_HAS_FLOAT_VARS
352 void varValPrintF(const Space &home, const Brancher& b,
353 unsigned int a,
354 FloatVar, int i, const FloatNumBranch& nl,
355 std::ostream& o) {
356 static_cast<const FlatZincSpace&>(home).branchInfo.print(b,a,i,nl,o);
357 }
358#endif
359
361 if (vs->assigned) {
362 return IntSet(vs->i,vs->i);
363 }
364 if (vs->domain()) {
365 AST::SetLit* sl = vs->domain.some();
366 if (sl->interval) {
367 return IntSet(sl->min, sl->max);
368 } else {
369 int* newdom = heap.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
370 for (int i=sl->s.size(); i--;)
371 newdom[i] = sl->s[i];
372 IntSet ret(newdom, sl->s.size());
373 heap.free(newdom, static_cast<unsigned long int>(sl->s.size()));
374 return ret;
375 }
376 }
378 }
379
381 if (bs->assigned) {
382 return bs->i;
383 }
384 if (bs->domain()) {
385 AST::SetLit* sl = bs->domain.some();
386 assert(sl->interval);
387 return std::min(1, std::max(0, sl->min));
388 }
389 return 0;
390 }
391
393 if (bs->assigned) {
394 return bs->i;
395 }
396 if (bs->domain()) {
397 AST::SetLit* sl = bs->domain.some();
398 assert(sl->interval);
399 return std::max(0, std::min(1, sl->max));
400 }
401 return 1;
402 }
403
405 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
406 if (s->id == "input_order")
408 if (s->id == "first_fail")
410 if (s->id == "anti_first_fail")
412 if (s->id == "smallest")
414 if (s->id == "largest")
416 if (s->id == "occurrence")
418 if (s->id == "max_regret")
420 if (s->id == "most_constrained")
423 if (s->id == "random") {
425 }
426 if (s->id == "dom_w_deg") {
428 }
429 if (s->id == "afc_min")
431 if (s->id == "afc_max")
433 if (s->id == "afc_size_min")
435 if (s->id == "afc_size_max") {
437 }
438 if (s->id == "action_min")
440 if (s->id == "action_max")
442 if (s->id == "action_size_min")
444 if (s->id == "action_size_max")
446 }
447 std::cerr << "Warning, ignored search annotation: ";
448 ann->print(std::cerr);
449 std::cerr << std::endl;
451 }
452
453 IntValBranch ann2ivalsel(AST::Node* ann, std::string& r0, std::string& r1,
454 Rnd rnd) {
455 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
456 if (s->id == "indomain_min") {
457 r0 = "="; r1 = "!=";
458 return INT_VAL_MIN();
459 }
460 if (s->id == "indomain_max") {
461 r0 = "="; r1 = "!=";
462 return INT_VAL_MAX();
463 }
464 if (s->id == "indomain_median") {
465 r0 = "="; r1 = "!=";
466 return INT_VAL_MED();
467 }
468 if (s->id == "indomain_split") {
469 r0 = "<="; r1 = ">";
470 return INT_VAL_SPLIT_MIN();
471 }
472 if (s->id == "indomain_reverse_split") {
473 r0 = ">"; r1 = "<=";
474 return INT_VAL_SPLIT_MAX();
475 }
476 if (s->id == "indomain_random") {
477 r0 = "="; r1 = "!=";
478 return INT_VAL_RND(rnd);
479 }
480 if (s->id == "indomain") {
481 r0 = "="; r1 = "=";
482 return INT_VALUES_MIN();
483 }
484 if (s->id == "indomain_middle") {
485 std::cerr << "Warning, replacing unsupported annotation "
486 << "indomain_middle with indomain_median" << std::endl;
487 r0 = "="; r1 = "!=";
488 return INT_VAL_MED();
489 }
490 if (s->id == "indomain_interval") {
491 std::cerr << "Warning, replacing unsupported annotation "
492 << "indomain_interval with indomain_split" << std::endl;
493 r0 = "<="; r1 = ">";
494 return INT_VAL_SPLIT_MIN();
495 }
496 }
497 std::cerr << "Warning, ignored search annotation: ";
498 ann->print(std::cerr);
499 std::cerr << std::endl;
500 r0 = "="; r1 = "!=";
501 return INT_VAL_MIN();
502 }
503
505 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
506 if (s->id == "indomain_min")
507 return INT_ASSIGN_MIN();
508 if (s->id == "indomain_max")
509 return INT_ASSIGN_MAX();
510 if (s->id == "indomain_median")
511 return INT_ASSIGN_MED();
512 if (s->id == "indomain_random") {
513 return INT_ASSIGN_RND(rnd);
514 }
515 }
516 std::cerr << "Warning, ignored search annotation: ";
517 ann->print(std::cerr);
518 std::cerr << std::endl;
519 return INT_ASSIGN_MIN();
520 }
521
523 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
524 if ((s->id == "input_order") ||
525 (s->id == "first_fail") ||
526 (s->id == "anti_first_fail") ||
527 (s->id == "smallest") ||
528 (s->id == "largest") ||
529 (s->id == "max_regret"))
531 if ((s->id == "occurrence") ||
532 (s->id == "most_constrained"))
534 if (s->id == "random")
536 if ((s->id == "afc_min") ||
537 (s->id == "afc_size_min"))
539 if ((s->id == "afc_max") ||
540 (s->id == "afc_size_max") ||
541 (s->id == "dom_w_deg"))
543 if ((s->id == "action_min") &&
544 (s->id == "action_size_min"))
546 if ((s->id == "action_max") ||
547 (s->id == "action_size_max"))
549 }
550 std::cerr << "Warning, ignored search annotation: ";
551 ann->print(std::cerr);
552 std::cerr << std::endl;
554 }
555
556 BoolValBranch ann2bvalsel(AST::Node* ann, std::string& r0, std::string& r1,
557 Rnd rnd) {
558 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
559 if (s->id == "indomain_min") {
560 r0 = "="; r1 = "!=";
561 return BOOL_VAL_MIN();
562 }
563 if (s->id == "indomain_max") {
564 r0 = "="; r1 = "!=";
565 return BOOL_VAL_MAX();
566 }
567 if (s->id == "indomain_median") {
568 r0 = "="; r1 = "!=";
569 return BOOL_VAL_MIN();
570 }
571 if (s->id == "indomain_split") {
572 r0 = "<="; r1 = ">";
573 return BOOL_VAL_MIN();
574 }
575 if (s->id == "indomain_reverse_split") {
576 r0 = ">"; r1 = "<=";
577 return BOOL_VAL_MAX();
578 }
579 if (s->id == "indomain_random") {
580 r0 = "="; r1 = "!=";
581 return BOOL_VAL_RND(rnd);
582 }
583 if (s->id == "indomain") {
584 r0 = "="; r1 = "=";
585 return BOOL_VAL_MIN();
586 }
587 if (s->id == "indomain_middle") {
588 std::cerr << "Warning, replacing unsupported annotation "
589 << "indomain_middle with indomain_median" << std::endl;
590 r0 = "="; r1 = "!=";
591 return BOOL_VAL_MIN();
592 }
593 if (s->id == "indomain_interval") {
594 std::cerr << "Warning, replacing unsupported annotation "
595 << "indomain_interval with indomain_split" << std::endl;
596 r0 = "<="; r1 = ">";
597 return BOOL_VAL_MIN();
598 }
599 }
600 std::cerr << "Warning, ignored search annotation: ";
601 ann->print(std::cerr);
602 std::cerr << std::endl;
603 r0 = "="; r1 = "!=";
604 return BOOL_VAL_MIN();
605 }
606
608 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
609 if ((s->id == "indomain_min") ||
610 (s->id == "indomain_median"))
611 return BOOL_ASSIGN_MIN();
612 if (s->id == "indomain_max")
613 return BOOL_ASSIGN_MAX();
614 if (s->id == "indomain_random") {
615 return BOOL_ASSIGN_RND(rnd);
616 }
617 }
618 std::cerr << "Warning, ignored search annotation: ";
619 ann->print(std::cerr);
620 std::cerr << std::endl;
621 return BOOL_ASSIGN_MIN();
622 }
623
624#ifdef GECODE_HAS_SET_VARS
625 SetVarBranch ann2svarsel(AST::Node* ann, Rnd rnd, double decay) {
626 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
627 if (s->id == "input_order")
628 return SET_VAR_NONE();
629 if (s->id == "first_fail")
630 return SET_VAR_SIZE_MIN();
631 if (s->id == "anti_first_fail")
632 return SET_VAR_SIZE_MAX();
633 if (s->id == "smallest")
634 return SET_VAR_MIN_MIN();
635 if (s->id == "largest")
636 return SET_VAR_MAX_MAX();
637 if (s->id == "afc_min")
638 return SET_VAR_AFC_MIN(decay);
639 if (s->id == "afc_max")
640 return SET_VAR_AFC_MAX(decay);
641 if (s->id == "afc_size_min")
642 return SET_VAR_AFC_SIZE_MIN(decay);
643 if (s->id == "afc_size_max")
644 return SET_VAR_AFC_SIZE_MAX(decay);
645 if (s->id == "action_min")
646 return SET_VAR_ACTION_MIN(decay);
647 if (s->id == "action_max")
648 return SET_VAR_ACTION_MAX(decay);
649 if (s->id == "action_size_min")
650 return SET_VAR_ACTION_SIZE_MIN(decay);
651 if (s->id == "action_size_max")
652 return SET_VAR_ACTION_SIZE_MAX(decay);
653 if (s->id == "random") {
654 return SET_VAR_RND(rnd);
655 }
656 }
657 std::cerr << "Warning, ignored search annotation: ";
658 ann->print(std::cerr);
659 std::cerr << std::endl;
660 return SET_VAR_NONE();
661 }
662
663 SetValBranch ann2svalsel(AST::Node* ann, std::string r0, std::string r1,
664 Rnd rnd) {
665 (void) rnd;
666 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
667 if (s->id == "indomain_min") {
668 r0 = "in"; r1 = "not in";
669 return SET_VAL_MIN_INC();
670 }
671 if (s->id == "indomain_max") {
672 r0 = "in"; r1 = "not in";
673 return SET_VAL_MAX_INC();
674 }
675 if (s->id == "outdomain_min") {
676 r1 = "in"; r0 = "not in";
677 return SET_VAL_MIN_EXC();
678 }
679 if (s->id == "outdomain_max") {
680 r1 = "in"; r0 = "not in";
681 return SET_VAL_MAX_EXC();
682 }
683 }
684 std::cerr << "Warning, ignored search annotation: ";
685 ann->print(std::cerr);
686 std::cerr << std::endl;
687 r0 = "in"; r1 = "not in";
688 return SET_VAL_MIN_INC();
689 }
690#endif
691
692#ifdef GECODE_HAS_FLOAT_VARS
694 double decay) {
695 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
696 if (s->id == "input_order")
698 if (s->id == "first_fail")
700 if (s->id == "anti_first_fail")
702 if (s->id == "smallest")
704 if (s->id == "largest")
706 if (s->id == "occurrence")
708 if (s->id == "most_constrained")
711 if (s->id == "random") {
713 }
714 if (s->id == "afc_min")
716 if (s->id == "afc_max")
718 if (s->id == "afc_size_min")
720 if (s->id == "afc_size_max")
722 if (s->id == "action_min")
724 if (s->id == "action_max")
726 if (s->id == "action_size_min")
728 if (s->id == "action_size_max")
730 }
731 std::cerr << "Warning, ignored search annotation: ";
732 ann->print(std::cerr);
733 std::cerr << std::endl;
735 }
736
737 FloatValBranch ann2fvalsel(AST::Node* ann, std::string r0, std::string r1) {
738 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
739 if (s->id == "indomain_split") {
740 r0 = "<="; r1 = ">";
741 return FLOAT_VAL_SPLIT_MIN();
742 }
743 if (s->id == "indomain_reverse_split") {
744 r1 = "<="; r0 = ">";
745 return FLOAT_VAL_SPLIT_MAX();
746 }
747 }
748 std::cerr << "Warning, ignored search annotation: ";
749 ann->print(std::cerr);
750 std::cerr << std::endl;
751 r0 = "<="; r1 = ">";
752 return FLOAT_VAL_SPLIT_MIN();
753 }
754
755#endif
756
758 public:
760 typedef std::unordered_set<TupleSet> TupleSetSet;
763
765 typedef std::unordered_set<SharedArray<int> > IntSharedArraySet;
768
770 typedef std::unordered_set<DFA> DFASet;
773
776
779 };
780
782 : Space(f),
783 _initData(nullptr), _random(f._random),
784 _solveAnnotations(nullptr),
786 iv_boolalias(nullptr),
788 step(f.step),
789#endif
791 _optVar = f._optVar;
792 _optVarIsInt = f._optVarIsInt;
793 _method = f._method;
794 _lns = f._lns;
795 _lnsInitialSolution = f._lnsInitialSolution;
796 branchInfo = f.branchInfo;
797 iv.update(*this, f.iv);
798 iv_lns.update(*this, f.iv_lns);
799 intVarCount = f.intVarCount;
800
801 on_restart_iv.update(*this, f.on_restart_iv);
802 on_restart_bv.update(*this, f.on_restart_bv);
804 on_restart_sv.update(*this, f.on_restart_sv);
805#endif
807 on_restart_fv.update(*this, f.on_restart_fv);
808#endif
809 if (needAuxVars) {
810 IntVarArgs iva;
811 for (int i=0; i<f.iv_aux.size(); i++) {
812 if (!f.iv_aux[i].assigned()) {
813 iva << IntVar();
814 iva[iva.size()-1].update(*this, f.iv_aux[i]);
815 }
816 }
817 iv_aux = IntVarArray(*this, iva);
818 }
819
820 bv.update(*this, f.bv);
821 boolVarCount = f.boolVarCount;
822 if (needAuxVars) {
823 BoolVarArgs bva;
824 for (int i=0; i<f.bv_aux.size(); i++) {
825 if (!f.bv_aux[i].assigned()) {
826 bva << BoolVar();
827 bva[bva.size()-1].update(*this, f.bv_aux[i]);
828 }
829 }
830 bv_aux = BoolVarArray(*this, bva);
831 }
832
833#ifdef GECODE_HAS_SET_VARS
834 sv.update(*this, f.sv);
835 setVarCount = f.setVarCount;
836 if (needAuxVars) {
837 SetVarArgs sva;
838 for (int i=0; i<f.sv_aux.size(); i++) {
839 if (!f.sv_aux[i].assigned()) {
840 sva << SetVar();
841 sva[sva.size()-1].update(*this, f.sv_aux[i]);
842 }
843 }
844 sv_aux = SetVarArray(*this, sva);
845 }
846#endif
847#ifdef GECODE_HAS_FLOAT_VARS
848 fv.update(*this, f.fv);
849 floatVarCount = f.floatVarCount;
850 if (needAuxVars) {
851 FloatVarArgs fva;
852 for (int i=0; i<f.fv_aux.size(); i++) {
853 if (!f.fv_aux[i].assigned()) {
854 fva << FloatVar();
855 fva[fva.size()-1].update(*this, f.fv_aux[i]);
856 }
857 }
858 fv_aux = FloatVarArray(*this, fva);
859 }
860#endif
861 }
862
866 _optVar(-1), _optVarIsInt(true), _lns(0), _lnsInitialSolution(0),
867 _random(random),
868 _solveAnnotations(nullptr), needAuxVars(true) {
869 branchInfo.init();
870 }
871
874 assert(s._initData != nullptr);
875 return s._initData->blackBoxContext;
876 }
877
878 void
879 FlatZincSpace::init(int intVars, int boolVars,
880 int setVars, int floatVars) {
881 (void) setVars;
882 (void) floatVars;
883
884 intVarCount = 0;
885 iv = IntVarArray(*this, intVars);
886 iv_introduced = std::vector<bool>(2*intVars);
887 iv_boolalias = alloc<int>(intVars+(intVars==0?1:0));
888 boolVarCount = 0;
889 bv = BoolVarArray(*this, boolVars);
890 bv_introduced = std::vector<bool>(2*boolVars);
891#ifdef GECODE_HAS_SET_VARS
892 setVarCount = 0;
893 sv = SetVarArray(*this, setVars);
894 sv_introduced = std::vector<bool>(2*setVars);
895#endif
896#ifdef GECODE_HAS_FLOAT_VARS
897 floatVarCount = 0;
898 fv = FloatVarArray(*this, floatVars);
899 fv_introduced = std::vector<bool>(2*floatVars);
900#endif
901 }
902
903 void
905 if (vs->alias) {
906 iv[intVarCount++] = iv[vs->i];
907 } else {
908 IntSet dom(vs2is(vs));
909 if (dom.size()==0) {
910 fail();
911 return;
912 } else {
913 iv[intVarCount++] = IntVar(*this, dom);
914 }
915 }
917 iv_introduced[2*(intVarCount-1)+1] = vs->funcDep;
919 }
920
921 void
925 int
929
930 void
932 if (vs->alias) {
933 bv[boolVarCount++] = bv[vs->i];
934 } else {
935 bv[boolVarCount++] = BoolVar(*this, vs2bsl(vs), vs2bsh(vs));
936 }
938 bv_introduced[2*(boolVarCount-1)+1] = vs->funcDep;
939 }
940
941#ifdef GECODE_HAS_SET_VARS
942 void
944 if (vs->alias) {
945 sv[setVarCount++] = sv[vs->i];
946 } else if (vs->assigned) {
947 assert(vs->upperBound());
948 AST::SetLit* vsv = vs->upperBound.some();
949 if (vsv->interval) {
950 IntSet d(vsv->min, vsv->max);
951 sv[setVarCount++] = SetVar(*this, d, d);
952 } else {
953 int* is = heap.alloc<int>(static_cast<unsigned long int>(vsv->s.size()));
954 for (int i=vsv->s.size(); i--; )
955 is[i] = vsv->s[i];
956 IntSet d(is, vsv->s.size());
957 heap.free(is,static_cast<unsigned long int>(vsv->s.size()));
958 sv[setVarCount++] = SetVar(*this, d, d);
959 }
960 } else if (vs->upperBound()) {
961 AST::SetLit* vsv = vs->upperBound.some();
962 if (vsv->interval) {
963 IntSet d(vsv->min, vsv->max);
964 sv[setVarCount++] = SetVar(*this, IntSet::empty, d);
965 } else {
966 int* is = heap.alloc<int>(static_cast<unsigned long int>(vsv->s.size()));
967 for (int i=vsv->s.size(); i--; )
968 is[i] = vsv->s[i];
969 IntSet d(is, vsv->s.size());
970 heap.free(is,static_cast<unsigned long int>(vsv->s.size()));
971 sv[setVarCount++] = SetVar(*this, IntSet::empty, d);
972 }
973 } else {
977 }
979 sv_introduced[2*(setVarCount-1)+1] = vs->funcDep;
980 }
981#else
982 void
984 throw FlatZinc::Error("Gecode", "set variables not supported");
985 }
986#endif
987
988#ifdef GECODE_HAS_FLOAT_VARS
989 void
991 if (vs->alias) {
992 fv[floatVarCount++] = fv[vs->i];
993 } else {
994 double dmin, dmax;
995 if (vs->domain()) {
996 dmin = vs->domain.some().first;
997 dmax = vs->domain.some().second;
998 if (dmin > dmax) {
999 fail();
1000 return;
1001 }
1002 } else {
1003 dmin = Float::Limits::min;
1004 dmax = Float::Limits::max;
1005 }
1006 fv[floatVarCount++] = FloatVar(*this, dmin, dmax);
1007 }
1009 fv_introduced[2*(floatVarCount-1)+1] = vs->funcDep;
1010 }
1011#else
1012 void
1014 throw FlatZinc::Error("Gecode", "float variables not supported");
1015 }
1016#endif
1017
1018 namespace {
1019 struct ConExprOrder {
1020 bool operator() (ConExpr* ce0, ConExpr* ce1) {
1021 return ce0->args->a.size() < ce1->args->a.size();
1022 }
1023 };
1024 }
1025
1026 void
1027 FlatZincSpace::postConstraints(std::vector<ConExpr*>& ces) {
1028 ConExprOrder ceo;
1029 std::sort(ces.begin(), ces.end(), ceo);
1030
1031 for (unsigned int i=0; i<ces.size(); i++) {
1032 const ConExpr& ce = *ces[i];
1033 try {
1034 registry().post(*this, ce);
1035 } catch (Gecode::Exception& e) {
1036 throw FlatZinc::Error("Gecode", e.what(), ce.ann);
1037 } catch (AST::TypeError& e) {
1038 throw FlatZinc::Error("Type error", e.what(), ce.ann);
1039 }
1040 delete ces[i];
1041 ces[i] = nullptr;
1042 }
1043 }
1044
1045 void flattenAnnotations(AST::Array* ann, std::vector<AST::Node*>& out) {
1046 for (unsigned int i=0; i<ann->a.size(); i++) {
1047 if (ann->a[i]->isCall("seq_search")) {
1048 AST::Call* c = ann->a[i]->getCall();
1049 if (c->args->isArray())
1050 flattenAnnotations(c->args->getArray(), out);
1051 else
1052 out.push_back(c->args);
1053 } else {
1054 out.push_back(ann->a[i]);
1055 }
1056 }
1057 }
1058
1059 void
1061 bool ignoreUnknown,
1062 std::ostream& err) {
1063 int seed = opt.seed();
1064 double decay = opt.decay();
1065 Rnd rnd(static_cast<unsigned int>(seed));
1066 TieBreak<IntVarBranch> def_int_varsel = INT_VAR_AFC_SIZE_MAX(0.99);
1067 IntBoolVarBranch def_intbool_varsel = INTBOOL_VAR_AFC_SIZE_MAX(0.99);
1068 IntValBranch def_int_valsel = INT_VAL_MIN();
1069 std::string def_int_rel_left = "=";
1070 std::string def_int_rel_right = "!=";
1071 TieBreak<BoolVarBranch> def_bool_varsel = BOOL_VAR_AFC_MAX(0.99);
1072 BoolValBranch def_bool_valsel = BOOL_VAL_MIN();
1073 std::string def_bool_rel_left = "=";
1074 std::string def_bool_rel_right = "!=";
1075#ifdef GECODE_HAS_SET_VARS
1076 SetVarBranch def_set_varsel = SET_VAR_AFC_SIZE_MAX(0.99);
1077 SetValBranch def_set_valsel = SET_VAL_MIN_INC();
1078 std::string def_set_rel_left = "in";
1079 std::string def_set_rel_right = "not in";
1080#endif
1081#ifdef GECODE_HAS_FLOAT_VARS
1082 TieBreak<FloatVarBranch> def_float_varsel = FLOAT_VAR_SIZE_MIN();
1083 FloatValBranch def_float_valsel = FLOAT_VAL_SPLIT_MIN();
1084 std::string def_float_rel_left = "<=";
1085 std::string def_float_rel_right = ">";
1086#endif
1087
1088 std::vector<bool> iv_searched(iv.size());
1089 for (unsigned int i=iv.size(); i--;)
1090 iv_searched[i] = false;
1091 std::vector<bool> bv_searched(bv.size());
1092 for (unsigned int i=bv.size(); i--;)
1093 bv_searched[i] = false;
1094#ifdef GECODE_HAS_SET_VARS
1095 std::vector<bool> sv_searched(sv.size());
1096 for (unsigned int i=sv.size(); i--;)
1097 sv_searched[i] = false;
1098#endif
1099#ifdef GECODE_HAS_FLOAT_VARS
1100 std::vector<bool> fv_searched(fv.size());
1101 for (unsigned int i=fv.size(); i--;)
1102 fv_searched[i] = false;
1103#endif
1104
1105 _lns = 0;
1106 if (ann) {
1107 std::vector<AST::Node*> flatAnn;
1108 if (ann->isArray()) {
1109 flattenAnnotations(ann->getArray() , flatAnn);
1110 } else {
1111 flatAnn.push_back(ann);
1112 }
1113
1114 for (unsigned int i=0; i<flatAnn.size(); i++) {
1115 if (flatAnn[i]->isCall("restart_geometric")) {
1116 AST::Call* call = flatAnn[i]->getCall("restart_geometric");
1117 opt.restart(RM_GEOMETRIC);
1118 AST::Array* args = call->getArgs(2);
1119 opt.restart_base(args->a[0]->getFloat());
1120 opt.restart_scale(args->a[1]->getInt());
1121 } else if (flatAnn[i]->isCall("restart_luby")) {
1122 AST::Call* call = flatAnn[i]->getCall("restart_luby");
1123 opt.restart(RM_LUBY);
1124 opt.restart_scale(call->args->getInt());
1125 } else if (flatAnn[i]->isCall("restart_linear")) {
1126 AST::Call* call = flatAnn[i]->getCall("restart_linear");
1127 opt.restart(RM_LINEAR);
1128 opt.restart_scale(call->args->getInt());
1129 } else if (flatAnn[i]->isCall("restart_constant")) {
1130 AST::Call* call = flatAnn[i]->getCall("restart_constant");
1131 opt.restart(RM_CONSTANT);
1132 opt.restart_scale(call->args->getInt());
1133 } else if (flatAnn[i]->isCall("restart_none")) {
1134 opt.restart(RM_NONE);
1135 } else if (flatAnn[i]->isCall("relax_and_reconstruct")) {
1136 if (_lns != 0)
1137 throw FlatZinc::Error("FlatZinc",
1138 "Only one relax_and_reconstruct annotation allowed");
1139 AST::Call *call = flatAnn[i]->getCall("relax_and_reconstruct");
1140 AST::Array* args;
1141 if (call->args->getArray()->a.size()==2) {
1142 args = call->getArgs(2);
1143 } else {
1144 args = call->getArgs(3);
1145 }
1146 _lns = args->a[1]->getInt();
1147 AST::Array *vars = args->a[0]->getArray();
1148 int k=vars->a.size();
1149 for (int i=vars->a.size(); i--;)
1150 if (vars->a[i]->isInt())
1151 k--;
1152 iv_lns = IntVarArray(*this, k);
1153 k = 0;
1154 for (unsigned int i=0; i<vars->a.size(); i++) {
1155 if (vars->a[i]->isInt())
1156 continue;
1157 iv_lns[k++] = iv[vars->a[i]->getIntVar()];
1158 }
1159 if (args->a.size()==3) {
1160 AST::Array *initial = args->a[2]->getArray();
1161 _lnsInitialSolution = IntSharedArray(initial->a.size());
1162 for (unsigned int i=initial->a.size(); i--;)
1163 _lnsInitialSolution[i] = initial->a[i]->getInt();
1164 }
1165 } else if (flatAnn[i]->isCall("gecode_search")) {
1166 AST::Call* c = flatAnn[i]->getCall();
1167 branchWithPlugin(c->args);
1168 } else if (flatAnn[i]->isCall("int_search")) {
1169 AST::Call *call = flatAnn[i]->getCall("int_search");
1170 AST::Array *args = call->getArgs(4);
1171 AST::Array *vars = args->a[0]->getArray();
1172 int k=vars->a.size();
1173 for (int i=vars->a.size(); i--;)
1174 if (vars->a[i]->isInt())
1175 k--;
1176 IntVarArgs va(k);
1177 std::vector<std::string> names;
1178 k=0;
1179 for (unsigned int i=0; i<vars->a.size(); i++) {
1180 if (vars->a[i]->isInt())
1181 continue;
1182 va[k++] = iv[vars->a[i]->getIntVar()];
1183 iv_searched[vars->a[i]->getIntVar()] = true;
1184 names.push_back(vars->a[i]->getVarName());
1185 }
1186 std::string r0, r1;
1187 {
1188 BrancherGroup bg;
1189 branch(bg(*this), va,
1190 ann2ivarsel(args->a[1],rnd,decay),
1191 ann2ivalsel(args->a[2],r0,r1,rnd),
1192 nullptr,
1194 branchInfo.add(bg,r0,r1,names);
1195 }
1196 } else if (flatAnn[i]->isCall("int_assign")) {
1197 AST::Call *call = flatAnn[i]->getCall("int_assign");
1198 AST::Array *args = call->getArgs(2);
1199 AST::Array *vars = args->a[0]->getArray();
1200 int k=vars->a.size();
1201 for (int i=vars->a.size(); i--;)
1202 if (vars->a[i]->isInt())
1203 k--;
1204 IntVarArgs va(k);
1205 k=0;
1206 for (unsigned int i=0; i<vars->a.size(); i++) {
1207 if (vars->a[i]->isInt())
1208 continue;
1209 va[k++] = iv[vars->a[i]->getIntVar()];
1210 iv_searched[vars->a[i]->getIntVar()] = true;
1211 }
1212 assign(*this, va, ann2asnivalsel(args->a[1],rnd), nullptr,
1214 } else if (flatAnn[i]->isCall("bool_search")) {
1215 AST::Call *call = flatAnn[i]->getCall("bool_search");
1216 AST::Array *args = call->getArgs(4);
1217 AST::Array *vars = args->a[0]->getArray();
1218 int k=vars->a.size();
1219 for (int i=vars->a.size(); i--;)
1220 if (vars->a[i]->isBool())
1221 k--;
1222 BoolVarArgs va(k);
1223 k=0;
1224 std::vector<std::string> names;
1225 for (unsigned int i=0; i<vars->a.size(); i++) {
1226 if (vars->a[i]->isBool())
1227 continue;
1228 va[k++] = bv[vars->a[i]->getBoolVar()];
1229 bv_searched[vars->a[i]->getBoolVar()] = true;
1230 names.push_back(vars->a[i]->getVarName());
1231 }
1232
1233 std::string r0, r1;
1234 {
1235 BrancherGroup bg;
1236 branch(bg(*this), va,
1237 ann2bvarsel(args->a[1],rnd,decay),
1238 ann2bvalsel(args->a[2],r0,r1,rnd),
1239 nullptr,
1241 branchInfo.add(bg,r0,r1,names);
1242 }
1243 } else if (flatAnn[i]->isCall("int_default_search")) {
1244 AST::Call *call = flatAnn[i]->getCall("int_default_search");
1245 AST::Array *args = call->getArgs(2);
1246 def_int_varsel = ann2ivarsel(args->a[0],rnd,decay);
1247 def_int_valsel = ann2ivalsel(args->a[1],
1248 def_int_rel_left,def_int_rel_right,rnd);
1249 } else if (flatAnn[i]->isCall("bool_default_search")) {
1250 AST::Call *call = flatAnn[i]->getCall("bool_default_search");
1251 AST::Array *args = call->getArgs(2);
1252 def_bool_varsel = ann2bvarsel(args->a[0],rnd,decay);
1253 def_bool_valsel = ann2bvalsel(args->a[1],
1254 def_bool_rel_left,def_bool_rel_right,
1255 rnd);
1256 } else if (flatAnn[i]->isCall("set_search")) {
1257#ifdef GECODE_HAS_SET_VARS
1258 AST::Call *call = flatAnn[i]->getCall("set_search");
1259 AST::Array *args = call->getArgs(4);
1260 AST::Array *vars = args->a[0]->getArray();
1261 int k=vars->a.size();
1262 for (int i=vars->a.size(); i--;)
1263 if (vars->a[i]->isSet())
1264 k--;
1265 SetVarArgs va(k);
1266 k=0;
1267 std::vector<std::string> names;
1268 for (unsigned int i=0; i<vars->a.size(); i++) {
1269 if (vars->a[i]->isSet())
1270 continue;
1271 va[k++] = sv[vars->a[i]->getSetVar()];
1272 sv_searched[vars->a[i]->getSetVar()] = true;
1273 names.push_back(vars->a[i]->getVarName());
1274 }
1275 std::string r0, r1;
1276 {
1277 BrancherGroup bg;
1278 branch(bg(*this), va,
1279 ann2svarsel(args->a[1],rnd,decay),
1280 ann2svalsel(args->a[2],r0,r1,rnd),
1281 nullptr,
1283 branchInfo.add(bg,r0,r1,names);
1284 }
1285#else
1286 if (!ignoreUnknown) {
1287 err << "Warning, ignored search annotation: ";
1288 flatAnn[i]->print(err);
1289 err << std::endl;
1290 }
1291#endif
1292 } else if (flatAnn[i]->isCall("set_default_search")) {
1293#ifdef GECODE_HAS_SET_VARS
1294 AST::Call *call = flatAnn[i]->getCall("set_default_search");
1295 AST::Array *args = call->getArgs(2);
1296 def_set_varsel = ann2svarsel(args->a[0],rnd,decay);
1297 def_set_valsel = ann2svalsel(args->a[1],
1298 def_set_rel_left,def_set_rel_right,rnd);
1299#else
1300 if (!ignoreUnknown) {
1301 err << "Warning, ignored search annotation: ";
1302 flatAnn[i]->print(err);
1303 err << std::endl;
1304 }
1305#endif
1306 } else if (flatAnn[i]->isCall("float_default_search")) {
1307#ifdef GECODE_HAS_FLOAT_VARS
1308 AST::Call *call = flatAnn[i]->getCall("float_default_search");
1309 AST::Array *args = call->getArgs(2);
1310 def_float_varsel = ann2fvarsel(args->a[0],rnd,decay);
1311 def_float_valsel = ann2fvalsel(args->a[1],
1312 def_float_rel_left,def_float_rel_right);
1313#else
1314 if (!ignoreUnknown) {
1315 err << "Warning, ignored search annotation: ";
1316 flatAnn[i]->print(err);
1317 err << std::endl;
1318 }
1319#endif
1320 } else if (flatAnn[i]->isCall("float_search")) {
1321#ifdef GECODE_HAS_FLOAT_VARS
1322 AST::Call *call = flatAnn[i]->getCall("float_search");
1323 AST::Array *args = call->getArgs(5);
1324 AST::Array *vars = args->a[0]->getArray();
1325 int k=vars->a.size();
1326 for (int i=vars->a.size(); i--;)
1327 if (vars->a[i]->isFloat())
1328 k--;
1329 FloatVarArgs va(k);
1330 k=0;
1331 std::vector<std::string> names;
1332 for (unsigned int i=0; i<vars->a.size(); i++) {
1333 if (vars->a[i]->isFloat())
1334 continue;
1335 va[k++] = fv[vars->a[i]->getFloatVar()];
1336 fv_searched[vars->a[i]->getFloatVar()] = true;
1337 names.push_back(vars->a[i]->getVarName());
1338 }
1339 std::string r0, r1;
1340 {
1341 BrancherGroup bg;
1342 branch(bg(*this), va,
1343 ann2fvarsel(args->a[2],rnd,decay),
1344 ann2fvalsel(args->a[3],r0,r1),
1345 nullptr,
1346 &varValPrintF);
1347 branchInfo.add(bg,r0,r1,names);
1348 }
1349#else
1350 if (!ignoreUnknown) {
1351 err << "Warning, ignored search annotation: ";
1352 flatAnn[i]->print(err);
1353 err << std::endl;
1354 }
1355#endif
1356 } else {
1357 if (!ignoreUnknown) {
1358 err << "Warning, ignored search annotation: ";
1359 flatAnn[i]->print(err);
1360 err << std::endl;
1361 }
1362 }
1363 }
1364 }
1365 int introduced = 0;
1366 int funcdep = 0;
1367 int searched = 0;
1368 for (int i=iv.size(); i--;) {
1369 if (iv_searched[i] || (_method != SAT && _optVarIsInt && _optVar==i)) {
1370 searched++;
1371 } else if (iv_introduced[2*i]) {
1372 if (iv_introduced[2*i+1]) {
1373 funcdep++;
1374 } else {
1375 introduced++;
1376 }
1377 }
1378 }
1379 std::vector<std::string> iv_sol_names(iv.size()-(introduced+funcdep+searched));
1380 IntVarArgs iv_sol(iv.size()-(introduced+funcdep+searched));
1381 std::vector<std::string> iv_tmp_names(introduced);
1382 IntVarArgs iv_tmp(introduced);
1383 for (int i=iv.size(), j=0, k=0; i--;) {
1384 if (iv_searched[i] || (_method != SAT && _optVarIsInt && _optVar==i))
1385 continue;
1386 if (iv_introduced[2*i]) {
1387 if (!iv_introduced[2*i+1]) {
1388 iv_tmp_names[j] = p.intVarName(i);
1389 iv_tmp[j++] = iv[i];
1390 }
1391 } else {
1392 iv_sol_names[k] = p.intVarName(i);
1393 iv_sol[k++] = iv[i];
1394 }
1395 }
1396
1397 introduced = 0;
1398 funcdep = 0;
1399 searched = 0;
1400 for (int i=bv.size(); i--;) {
1401 if (bv_searched[i]) {
1402 searched++;
1403 } else if (bv_introduced[2*i]) {
1404 if (bv_introduced[2*i+1]) {
1405 funcdep++;
1406 } else {
1407 introduced++;
1408 }
1409 }
1410 }
1411 std::vector<std::string> bv_sol_names(bv.size()-(introduced+funcdep+searched));
1412 BoolVarArgs bv_sol(bv.size()-(introduced+funcdep+searched));
1413 BoolVarArgs bv_tmp(introduced);
1414 std::vector<std::string> bv_tmp_names(introduced);
1415 for (int i=bv.size(), j=0, k=0; i--;) {
1416 if (bv_searched[i])
1417 continue;
1418 if (bv_introduced[2*i]) {
1419 if (!bv_introduced[2*i+1]) {
1420 bv_tmp_names[j] = p.boolVarName(i);
1421 bv_tmp[j++] = bv[i];
1422 }
1423 } else {
1424 bv_sol_names[k] = p.boolVarName(i);
1425 bv_sol[k++] = bv[i];
1426 }
1427 }
1428
1429 if (iv_sol.size() > 0 && bv_sol.size() > 0) {
1430 branch(*this, iv_sol, bv_sol, def_intbool_varsel, def_int_valsel);
1431 } else if (iv_sol.size() > 0) {
1432 BrancherGroup bg;
1433 branch(bg(*this), iv_sol, def_int_varsel, def_int_valsel, nullptr,
1435 branchInfo.add(bg,def_int_rel_left,def_int_rel_right,iv_sol_names);
1436 } else if (bv_sol.size() > 0) {
1437 BrancherGroup bg;
1438 branch(bg(*this), bv_sol, def_bool_varsel, def_bool_valsel, nullptr,
1440 branchInfo.add(bg,def_bool_rel_left,def_bool_rel_right,bv_sol_names);
1441 }
1442#ifdef GECODE_HAS_FLOAT_VARS
1443 introduced = 0;
1444 funcdep = 0;
1445 searched = 0;
1446 for (int i=fv.size(); i--;) {
1447 if (fv_searched[i] || (_method != SAT && !_optVarIsInt && _optVar==i)) {
1448 searched++;
1449 } else if (fv_introduced[2*i]) {
1450 if (fv_introduced[2*i+1]) {
1451 funcdep++;
1452 } else {
1453 introduced++;
1454 }
1455 }
1456 }
1457 std::vector<std::string> fv_sol_names(fv.size()-(introduced+funcdep+searched));
1458 FloatVarArgs fv_sol(fv.size()-(introduced+funcdep+searched));
1459 FloatVarArgs fv_tmp(introduced);
1460 std::vector<std::string> fv_tmp_names(introduced);
1461 for (int i=fv.size(), j=0, k=0; i--;) {
1462 if (fv_searched[i] || (_method != SAT && !_optVarIsInt && _optVar==i))
1463 continue;
1464 if (fv_introduced[2*i]) {
1465 if (!fv_introduced[2*i+1]) {
1466 fv_tmp_names[j] = p.floatVarName(i);
1467 fv_tmp[j++] = fv[i];
1468 }
1469 } else {
1470 fv_sol_names[k] = p.floatVarName(i);
1471 fv_sol[k++] = fv[i];
1472 }
1473 }
1474
1475 if (fv_sol.size() > 0) {
1476 BrancherGroup bg;
1477 branch(bg(*this), fv_sol, def_float_varsel, def_float_valsel, nullptr,
1478 &varValPrintF);
1479 branchInfo.add(bg,def_float_rel_left,def_float_rel_right,fv_sol_names);
1480 }
1481#endif
1482#ifdef GECODE_HAS_SET_VARS
1483 introduced = 0;
1484 funcdep = 0;
1485 searched = 0;
1486 for (int i=sv.size(); i--;) {
1487 if (sv_searched[i]) {
1488 searched++;
1489 } else if (sv_introduced[2*i]) {
1490 if (sv_introduced[2*i+1]) {
1491 funcdep++;
1492 } else {
1493 introduced++;
1494 }
1495 }
1496 }
1497 std::vector<std::string> sv_sol_names(sv.size()-(introduced+funcdep+searched));
1498 SetVarArgs sv_sol(sv.size()-(introduced+funcdep+searched));
1499 SetVarArgs sv_tmp(introduced);
1500 std::vector<std::string> sv_tmp_names(introduced);
1501 for (int i=sv.size(), j=0, k=0; i--;) {
1502 if (sv_searched[i])
1503 continue;
1504 if (sv_introduced[2*i]) {
1505 if (!sv_introduced[2*i+1]) {
1506 sv_tmp_names[j] = p.setVarName(i);
1507 sv_tmp[j++] = sv[i];
1508 }
1509 } else {
1510 sv_sol_names[k] = p.setVarName(i);
1511 sv_sol[k++] = sv[i];
1512 }
1513 }
1514
1515 if (sv_sol.size() > 0) {
1516 BrancherGroup bg;
1517 branch(bg(*this), sv_sol, def_set_varsel, def_set_valsel, nullptr,
1519 branchInfo.add(bg,def_set_rel_left,def_set_rel_right,sv_sol_names);
1520
1521 }
1522#endif
1523 iv_aux = IntVarArray(*this, iv_tmp);
1524 bv_aux = BoolVarArray(*this, bv_tmp);
1525 int n_aux = iv_aux.size() + bv_aux.size();
1526#ifdef GECODE_HAS_SET_VARS
1527 sv_aux = SetVarArray(*this, sv_tmp);
1528 n_aux += sv_aux.size();
1529#endif
1530#ifdef GECODE_HAS_FLOAT_VARS
1531 fv_aux = FloatVarArray(*this, fv_tmp);
1532 n_aux += fv_aux.size();
1533#endif
1534
1535 if (n_aux > 0) {
1536 if (_method == SAT) {
1537 AuxVarBrancher::post(*this, def_int_varsel, def_int_valsel,
1538 def_bool_varsel, def_bool_valsel
1540 , def_set_varsel, def_set_valsel
1541#endif
1543 , def_float_varsel, def_float_valsel
1544#endif
1545 );
1546 } else {
1547 {
1548 BrancherGroup bg;
1549 branch(bg(*this),iv_aux,def_int_varsel,def_int_valsel, nullptr,
1551 branchInfo.add(bg,def_int_rel_left,def_int_rel_right,iv_tmp_names);
1552 }
1553 {
1554 BrancherGroup bg;
1555 branch(bg(*this),bv_aux,def_bool_varsel,def_bool_valsel, nullptr,
1557 branchInfo.add(bg,def_bool_rel_left,def_bool_rel_right,bv_tmp_names);
1558 }
1559 #ifdef GECODE_HAS_SET_VARS
1560 {
1561 BrancherGroup bg;
1562 branch(bg(*this),sv_aux,def_set_varsel,def_set_valsel, nullptr,
1564 branchInfo.add(bg,def_set_rel_left,def_set_rel_right,sv_tmp_names);
1565 }
1566 #endif
1567 #ifdef GECODE_HAS_FLOAT_VARS
1568 {
1569 BrancherGroup bg;
1570 branch(bg(*this),fv_aux,def_float_varsel,def_float_valsel, nullptr,
1571 &varValPrintF);
1572 branchInfo.add(bg,def_float_rel_left,def_float_rel_right,fv_tmp_names);
1573 }
1574 #endif
1575
1576 }
1577 }
1578
1579 if (_method == MIN) {
1580 if (_optVarIsInt) {
1581 std::vector<std::string> names(1);
1582 names[0] = p.intVarName(_optVar);
1583 BrancherGroup bg;
1584 branch(bg(*this), iv[_optVar], INT_VAL_MIN(),
1586 branchInfo.add(bg,"=","!=",names);
1587 } else {
1588#ifdef GECODE_HAS_FLOAT_VARS
1589 std::vector<std::string> names(1);
1590 names[0] = p.floatVarName(_optVar);
1591 BrancherGroup bg;
1592 branch(bg(*this), fv[_optVar], FLOAT_VAL_SPLIT_MIN(),
1593 &varValPrintF);
1594 branchInfo.add(bg,"<=",">",names);
1595#endif
1596 }
1597 } else if (_method == MAX) {
1598 if (_optVarIsInt) {
1599 std::vector<std::string> names(1);
1600 names[0] = p.intVarName(_optVar);
1601 BrancherGroup bg;
1602 branch(bg(*this), iv[_optVar], INT_VAL_MAX(),
1604 branchInfo.add(bg,"=","!=",names);
1605 } else {
1606#ifdef GECODE_HAS_FLOAT_VARS
1607 std::vector<std::string> names(1);
1608 names[0] = p.floatVarName(_optVar);
1609 BrancherGroup bg;
1610 branch(bg(*this), fv[_optVar], FLOAT_VAL_SPLIT_MAX(),
1611 &varValPrintF);
1612 branchInfo.add(bg,"<=",">",names);
1613#endif
1614 }
1615 }
1616
1617 }
1618
1619 AST::Array*
1621 return _solveAnnotations;
1622 }
1623
1624 void
1629
1630 void
1631 FlatZincSpace::minimize(int var, bool isInt, AST::Array* ann) {
1632 _method = MIN;
1633 _optVar = var;
1634 _optVarIsInt = isInt;
1635 _solveAnnotations = ann;
1636 }
1637
1638 void
1639 FlatZincSpace::maximize(int var, bool isInt, AST::Array* ann) {
1640 _method = MAX;
1641 _optVar = var;
1642 _optVarIsInt = isInt;
1643 _solveAnnotations = ann;
1644 }
1645
1647 delete _initData;
1648 delete _solveAnnotations;
1649 }
1650
1651#ifdef GECODE_HAS_GIST
1652
1656 template<class Engine>
1658 };
1659
1661 template<typename S>
1662 class GistEngine<DFS<S> > {
1663 public:
1664 static void explore(S* root, const FlatZincOptions& opt,
1667 o.c_d = opt.c_d(); o.a_d = opt.a_d();
1668 o.inspect.click(i);
1669 o.inspect.compare(c);
1670 (void) Gecode::Gist::dfs(root, o);
1671 }
1672 };
1673
1675 template<typename S>
1676 class GistEngine<BAB<S> > {
1677 public:
1678 static void explore(S* root, const FlatZincOptions& opt,
1681 o.c_d = opt.c_d(); o.a_d = opt.a_d();
1682 o.inspect.click(i);
1683 o.inspect.compare(c);
1684 (void) Gecode::Gist::bab(root, o);
1685 }
1686 };
1687
1689 template<class S>
1692 private:
1693 const Printer& p;
1694 public:
1696 FZPrintingInspector(const Printer& p0);
1698 virtual void inspect(const Space& node);
1700 virtual void finalize(void);
1701 };
1702
1703 template<class S>
1705 : TextOutput("Gecode/FlatZinc"), p(p0) {}
1706
1707 template<class S>
1708 void
1710 init();
1711 dynamic_cast<const S&>(node).print(getStream(), p);
1712 getStream() << std::endl;
1713 }
1714
1715 template<class S>
1716 void
1720
1721 template<class S>
1723 : public Gecode::Gist::VarComparator<S> {
1724 private:
1725 const Printer& p;
1726 public:
1728 FZPrintingComparator(const Printer& p0);
1729
1731 virtual void compare(const Space& s0, const Space& s1);
1732 };
1733
1734 template<class S>
1736 : Gecode::Gist::VarComparator<S>("Gecode/FlatZinc"), p(p0) {}
1737
1738 template<class S>
1739 void
1741 this->init();
1742 try {
1743 dynamic_cast<const S&>(s0).compare(dynamic_cast<const S&>(s1),
1744 this->getStream(), p);
1745 } catch (Exception& e) {
1746 this->getStream() << "Exception: " << e.what();
1747 }
1748 this->getStream() << std::endl;
1749 }
1750
1751#endif
1752
1754 protected:
1755 std::unique_ptr<Search::Stop> stop_object;
1757 public:
1759 const BlackBoxContextHandle& black_box_context0)
1760 : stop_object(stop_object0), black_box_context(black_box_context0) {}
1761 bool stop(const Search::Statistics& s, const Search::Options& o) override {
1762 return black_box_context.failed() ||
1763 ((stop_object.get() != nullptr) && stop_object->stop(s,o));
1764 }
1765 };
1766
1768 protected:
1770 public:
1771 explicit InterruptHandlerGuard(bool install) : installed(install) {
1772 if (installed)
1774 }
1779 };
1780
1781 template<template<class> class Engine>
1782 void
1783 FlatZincSpace::runEngine(std::ostream& out, const Printer& p,
1784 const FlatZincOptions& opt, Support::Timer& t_total) {
1785 if (opt.restart()==RM_NONE) {
1786 runMeta<Engine,Driver::EngineToMeta>(out,p,opt,t_total);
1787 } else {
1788 runMeta<Engine,RBS>(out,p,opt,t_total);
1789 }
1790 }
1791
1792#ifdef GECODE_HAS_CPPROFILER
1793
1795 public:
1796 const Printer& p;
1797 FlatZincGetInfo(const Printer& printer) : p(printer) {}
1798 virtual std::string
1799 getInfo(const Space& space) const {
1800 std::stringstream ss;
1801 if (const FlatZincSpace* fz_space = dynamic_cast<const FlatZincSpace*>(&space)) {
1802 ss << "{\n\t\"domains\": \"";
1803 ss << fz_space->getDomains(p);
1804 ss << "\"\n}";
1805 }
1806 return ss.str();
1807 }
1809 };
1810
1811 void printIntVar(std::ostream& os, const std::string name, const Int::IntView& x) {
1812 os << "var ";
1813 if (x.assigned()) {
1814 os << "int: " << name << " = " << x.val() << ";";
1815 } else if (x.range()) {
1816 os << x.min() << ".." << x.max() << ": " << name << ";";
1817 } else {
1818 os << "array_union([";
1820 while (true) {
1821 os << r.min() << ".." << r.max();
1822 ++r;
1823 if (!r()) break;
1824 os << ',';
1825 }
1826 os << "]): " << name << ";";
1827 }
1828 os << "\n";
1829 }
1830 void printBoolVar(std::ostream& os, const std::string name, const BoolVar& b) {
1831 os << "var bool: " << name;
1832 if(b.assigned())
1833 os << " = " << (b.val() ? "true" : "false");
1834 os << ";\n";
1835 }
1836#ifdef GECODE_HAS_FLOAT_VARS
1837 void printFloatVar(std::ostream& os, const std::string name, const Float::FloatView& f) {
1838 os << "var ";
1839 if(f.assigned())
1840 os << "float: " << name << " = " << f.med() << ";";
1841 else
1842 os << f.min() << ".." << f.max() << ": " << name << ";";
1843 os << "\n";
1844 }
1845#endif
1846 std::string FlatZincSpace::getDomains(const Printer& p) const {
1847 std::ostringstream oss;
1848
1849 for (int i = 0; i < iv.size(); i++)
1850 printIntVar(oss, p.intVarName(i), iv[i]);
1851
1852 for (int i = 0; i < bv.size(); i++)
1853 printBoolVar(oss, p.boolVarName(i), bv[i]);
1854
1855#ifdef GECODE_HAS_FLOAT_VARS
1856 for (int i = 0; i < fv.size(); i++)
1857 printFloatVar(oss, p.floatVarName(i), fv[i]);
1858#endif
1859#ifdef GECODE_HAS_SET_VARS
1860 for (int i = 0; i < sv.size(); i++)
1861 oss << "var " << sv[i] << ": " << p.setVarName(i) << ";" << std::endl;
1862#endif
1863
1864 return oss.str();
1865 }
1866
1867#endif
1868
1869 template<template<class> class Engine,
1870 template<class,template<class> class> class Meta>
1871 void
1872 FlatZincSpace::runMeta(std::ostream& out, const Printer& p,
1873 const FlatZincOptions& opt, Support::Timer& t_total) {
1874#ifdef GECODE_HAS_GIST
1875 if (opt.mode() == SM_GIST) {
1876 BlackBoxContextHandle& black_box_context = BlackBoxAccess::context(*this);
1877 (void) status();
1878 black_box_context.rethrow();
1881 (void) GistEngine<Engine<FlatZincSpace> >::explore(this,opt,&pi,&pc);
1882 black_box_context.rethrow();
1883 return;
1884 }
1885#endif
1886 StatusStatistics sstat;
1887 unsigned int n_p = 0;
1888 Support::Timer t_solve;
1889 t_solve.start();
1890 if (status(sstat) != SS_FAILED) {
1891 n_p = PropagatorGroup::all.size(*this);
1892 }
1893 BlackBoxContextHandle& black_box_context = BlackBoxAccess::context(*this);
1894 black_box_context.rethrow();
1895 Search::Options o;
1896 std::unique_ptr<Search::Stop> stop(
1897 Driver::CombinedStop::create(opt.node(), opt.fail(), opt.time(),
1898 opt.restart_limit(), true));
1899 if (black_box_context) {
1900 stop.reset(new FlatZincStop(stop.release(), black_box_context));
1901 }
1902 o.stop = stop.get();
1903 std::unique_ptr<SearchTracer> tracer;
1904 o.c_d = opt.c_d();
1905 o.a_d = opt.a_d();
1906
1907#ifdef GECODE_HAS_CPPROFILER
1908 if (opt.profiler_port()) {
1909 FlatZincGetInfo* getInfo = nullptr;
1910 if (opt.profiler_info())
1911 getInfo = new FlatZincGetInfo(p);
1912 tracer.reset(new CPProfilerSearchTracer(opt.profiler_id(),
1913 opt.name(), opt.profiler_port(),
1914 getInfo));
1915 o.tracer = tracer.get();
1916 }
1917
1918#endif
1919
1920#ifdef GECODE_HAS_FLOAT_VARS
1921 step = opt.step();
1922#endif
1923 o.threads = opt.threads();
1924 o.nogoods_limit = opt.nogoods() ? opt.nogoods_limit() : 0;
1925 o.cutoff = new Search::CutoffAppend(new Search::CutoffConstant(0), 1, Driver::createCutoff(opt));
1926 int noOfSolutions = opt.solutions();
1927 if (noOfSolutions == -1) {
1928 noOfSolutions = (_method == SAT) ? 1 : 0;
1929 }
1930 bool printAll = _method == SAT || opt.allSolutions() || noOfSolutions != 0;
1931 int findSol = noOfSolutions;
1932 bool solution_limit_reached = false;
1933 bool engine_stopped = false;
1934 Gecode::Search::Statistics stat;
1935 std::unique_ptr<FlatZincSpace> sol;
1936 {
1937 InterruptHandlerGuard interrupt_handler(opt.interrupt());
1938 Meta<FlatZincSpace,Engine> se(this,o);
1939 while (FlatZincSpace* next = se.next()) {
1940 std::unique_ptr<FlatZincSpace> next_sol(next);
1941 if (black_box_context.failed()) {
1942 break;
1943 }
1944 sol = std::move(next_sol);
1945 if (printAll) {
1946 sol->print(out, p);
1947 out << "----------" << std::endl;
1948 }
1949 if (--findSol == 0) {
1950 solution_limit_reached = true;
1951 break;
1952 }
1953 }
1954 engine_stopped = se.stopped();
1955 if (opt.mode() == SM_STAT) {
1956 stat = se.statistics();
1957 }
1958 }
1959 if (black_box_context.failed()) {
1960 sol.reset();
1961 black_box_context.rethrow();
1962 }
1963 if (sol && !printAll) {
1964 sol->print(out, p);
1965 out << "----------" << std::endl;
1966 }
1967 if (!solution_limit_reached) {
1968 if (!engine_stopped) {
1969 if (sol) {
1970 out << "==========" << std::endl;
1971 } else {
1972 out << "=====UNSATISFIABLE=====" << std::endl;
1973 }
1974 } else if (!sol) {
1975 out << "=====UNKNOWN=====" << std::endl;
1976 }
1977 }
1978 if (opt.mode() == SM_STAT) {
1979 double totalTime = (t_total.stop() / 1000.0);
1980 double solveTime = (t_solve.stop() / 1000.0);
1981 double initTime = totalTime - solveTime;
1982 out << std::endl
1983 << "%%%mzn-stat: initTime=" << initTime
1984 << std::endl;
1985 out << "%%%mzn-stat: solveTime=" << solveTime
1986 << std::endl;
1987 out << "%%%mzn-stat: solutions="
1988 << std::abs(noOfSolutions - findSol) << std::endl
1989 << "%%%mzn-stat: variables="
1990 << (intVarCount + boolVarCount + setVarCount) << std::endl
1991 << "%%%mzn-stat: propagators=" << n_p << std::endl
1992 << "%%%mzn-stat: propagations=" << sstat.propagate+stat.propagate << std::endl
1993 << "%%%mzn-stat: nodes=" << stat.node << std::endl
1994 << "%%%mzn-stat: failures=" << stat.fail << std::endl
1995 << "%%%mzn-stat: restarts=" << stat.restart << std::endl
1996 << "%%%mzn-stat: peakDepth=" << stat.depth << std::endl
1997 << "%%%mzn-stat-end" << std::endl
1998 << std::endl;
1999 }
2000 }
2001
2002#ifdef GECODE_HAS_QT
2003 void
2004 FlatZincSpace::branchWithPlugin(AST::Node* ann) {
2005 if (AST::Call* c = dynamic_cast<AST::Call*>(ann)) {
2006 QString pluginName(c->id.c_str());
2007 if (QLibrary::isLibrary(pluginName+".dll")) {
2008 pluginName += ".dll";
2009 } else if (QLibrary::isLibrary(pluginName+".dylib")) {
2010 pluginName = "lib" + pluginName + ".dylib";
2011 } else if (QLibrary::isLibrary(pluginName+".so")) {
2012 // Must check .so after .dylib so that Mac OS uses .dylib
2013 pluginName = "lib" + pluginName + ".so";
2014 }
2015 QPluginLoader pl(pluginName);
2016 QObject* plugin_o = pl.instance();
2017 if (!plugin_o) {
2018 throw FlatZinc::Error("FlatZinc",
2019 "Error loading plugin "+pluginName.toStdString()+
2020 ": "+pl.errorString().toStdString());
2021 }
2022 BranchPlugin* pb = qobject_cast<BranchPlugin*>(plugin_o);
2023 if (!pb) {
2024 throw FlatZinc::Error("FlatZinc",
2025 "Error loading plugin "+pluginName.toStdString()+
2026 ": does not contain valid PluginBrancher");
2027 }
2028 pb->branch(*this, c);
2029 }
2030 }
2031#else
2032 void
2033 FlatZincSpace::branchWithPlugin(AST::Node*) {
2034 throw FlatZinc::Error("FlatZinc",
2035 "Branching with plugins not supported (requires Qt support)");
2036 }
2037#endif
2038
2039 void
2040 FlatZincSpace::run(std::ostream& out, const Printer& p,
2041 const FlatZincOptions& opt, Support::Timer& t_total) {
2042#ifndef GECODE_HAS_GIST
2043 if (opt.mode() == SM_GIST)
2044 throw FlatZinc::Error("FlatZinc",
2045 "Gist mode is unavailable in this build");
2046#endif
2047 switch (_method) {
2048 case MIN:
2049 case MAX:
2050 runEngine<BAB>(out,p,opt,t_total);
2051 break;
2052 case SAT:
2053 runEngine<DFS>(out,p,opt,t_total);
2054 break;
2055 }
2056 }
2057
2058 void
2060 if (_optVarIsInt) {
2061 if (_method == MIN)
2062 rel(*this, iv[_optVar], IRT_LE,
2063 static_cast<const FlatZincSpace*>(&s)->iv[_optVar].val());
2064 else if (_method == MAX)
2065 rel(*this, iv[_optVar], IRT_GR,
2066 static_cast<const FlatZincSpace*>(&s)->iv[_optVar].val());
2067 } else {
2068#ifdef GECODE_HAS_FLOAT_VARS
2069 if (_method == MIN)
2070 rel(*this, fv[_optVar], FRT_LE,
2071 static_cast<const FlatZincSpace*>(&s)->fv[_optVar].val()-step);
2072 else if (_method == MAX)
2073 rel(*this, fv[_optVar], FRT_GR,
2074 static_cast<const FlatZincSpace*>(&s)->fv[_optVar].val()+step);
2075#endif
2076 }
2077 }
2078
2079 bool
2081 if (mi.type() == MetaInfo::RESTART) {
2082 if (restart_data.initialized() && restart_data().mark_complete) {
2083 // Fail the space
2084 this->fail();
2085 // Return true to signal we are in the global search space
2086 return true;
2087 }
2088
2089 bool ret = false;
2090 if (on_restart_iv.size() > 0) {
2091 int base = 0;
2092
2093 // Assign the sol_int values (use lb if no solution is known)
2094 const FlatZincSpace* last = static_cast<const FlatZincSpace*>(mi.last());
2095 assert(last == nullptr || last->on_restart_iv.size() == restart_data().on_restart_iv_sol);
2096 for (int i = 0; i < restart_data().on_restart_iv_sol; ++i) {
2097 IntVar& outVar = on_restart_iv[base + restart_data().on_restart_iv_sol + i];
2098 int solVal = (last != nullptr) ? last->on_restart_iv[i].val() : on_restart_iv[base + i].min();
2099 rel(*this, outVar, IRT_EQ, solVal);
2100 }
2101 base += restart_data().on_restart_iv_sol * 2;
2102
2103 // Assign last_val_int values
2104 for (size_t i = 0; i < restart_data().last_val_int.size(); ++i) {
2105 rel(*this, on_restart_iv[base + i], IRT_EQ, restart_data().last_val_int[i]);
2106 }
2107 base += restart_data().last_val_int.size();
2108
2109 // Assign uniform_int random values
2110 for (size_t i = 0; i < restart_data().uniform_range_int.size(); ++i) {
2111 const auto& range = restart_data().uniform_range_int[i];
2112 const unsigned long long int width =
2113 static_cast<unsigned long long int>(
2114 static_cast<long long int>(range.second) -
2115 static_cast<long long int>(range.first)) + 1ULL;
2116 const int rndVal =
2117 static_cast<int>(static_cast<long long int>(range.first) +
2118 static_cast<long long int>(_random(width)));
2119 rel(*this, on_restart_iv[base + i], IRT_EQ, rndVal);
2120 }
2121 base += restart_data().uniform_range_int.size();
2122
2123 // Set the status value
2124 if (restart_data().on_restart_status) {
2125 assert(base == on_restart_iv.size() - 1);
2126 IntVar& restart_status = on_restart_iv[base];
2127 switch(mi.reason()) {
2128 case MetaInfo::RR_INIT:
2129 assert(!mi.last());
2130 rel(*this, restart_status, IRT_EQ, 1); // 1: START
2131 break;
2132 case MetaInfo::RR_SOL:
2133 assert(mi.solution() > 0);
2134 rel(*this, restart_status, IRT_EQ, 4); // 4: SAT
2135 break;
2136 case MetaInfo::RR_CMPL:
2137 rel(*this, restart_status, IRT_EQ, 3); // 3: UNSAT
2138 break;
2139 default:
2140 assert(mi.reason() == MetaInfo::RR_LIM);
2141 rel(*this, restart_status, IRT_EQ, 2); // 2: UNKNOWN
2142 break;
2143 }
2144 base += 1;
2145 }
2146 assert(base == on_restart_iv.size());
2147
2148 // Reduce on_restart_iv to only the variables required in a solution
2149 IntVarArray tmp(*this, restart_data().on_restart_iv_sol);
2150 for (int i = 0; i < restart_data().on_restart_iv_sol; ++i) {
2151 tmp[i] = on_restart_iv[i];
2152 }
2153 on_restart_iv = tmp;
2154
2155 ret = true;
2156 }
2157 if (on_restart_bv.size() > 0) {
2158 int base = 0;
2159
2160 // Assign the sol_bool values (use lb if no solution is known)
2161 const FlatZincSpace* last = static_cast<const FlatZincSpace*>(mi.last());
2162 assert(last == nullptr || last->on_restart_bv.size() == restart_data().on_restart_bv_sol);
2163 for (int i = 0; i < restart_data().on_restart_bv_sol; ++i) {
2164 BoolVar& outVar = on_restart_bv[base + restart_data().on_restart_bv_sol + i];
2165 int solVal = (last != nullptr) ? last->on_restart_bv[i].val() : on_restart_bv[base + i].min();
2166 rel(*this, outVar, IRT_EQ, solVal);
2167 }
2168 base += restart_data().on_restart_bv_sol * 2;
2169
2170 // Assign last_val_bool values
2171 for (size_t i = 0; i < restart_data().last_val_bool.size(); ++i) {
2172 rel(*this, on_restart_bv[base + i], IRT_EQ, restart_data().last_val_bool[i]);
2173 }
2174 base += restart_data().last_val_bool.size();
2175 assert(base == on_restart_bv.size());
2176
2177 // Reduce on_restart_bv to only the variables required in a solution
2178 BoolVarArray tmp(*this, restart_data().on_restart_bv_sol);
2179 for (int i = 0; i < restart_data().on_restart_bv_sol; ++i) {
2180 tmp[i] = on_restart_bv[i];
2181 }
2182 on_restart_bv = tmp;
2183
2184 ret = true;
2185 }
2186#ifdef GECODE_HAS_SET_VARS
2187 if (on_restart_sv.size() > 0) {
2188 int base = 0;
2189
2190 // Assign the sol_set values (use lb if no solution is known)
2191 const FlatZincSpace* last = static_cast<const FlatZincSpace*>(mi.last());
2192 assert(last == nullptr || last->on_restart_sv.size() == restart_data().on_restart_sv_sol);
2193 for (int i = 0; i < restart_data().on_restart_sv_sol; ++i) {
2194 SetVar& outVar = on_restart_sv[base + restart_data().on_restart_sv_sol + i];
2195 Set::GlbRanges<Set::SetView> lb(last != nullptr ? last->on_restart_sv[i] : on_restart_sv[base + i]);
2196 IntSet val(lb);
2197 dom(*this, outVar, SRT_EQ, val);
2198 }
2199 base += restart_data().on_restart_sv_sol * 2;
2200
2201 // Assign last_val_set values
2202 for (size_t i = 0; i < restart_data().last_val_set.size(); ++i) {
2203 dom(*this, on_restart_sv[base + i], SRT_EQ, restart_data().last_val_set[i]);
2204 }
2205 base += restart_data().last_val_set.size();
2206 assert(base == on_restart_sv.size());
2207
2208 // Reduce on_restart_sv to only the variables required in a solution
2209 SetVarArray tmp(*this, restart_data().on_restart_sv_sol);
2210 for (int i = 0; i < restart_data().on_restart_sv_sol; ++i) {
2211 tmp[i] = on_restart_sv[i];
2212 }
2213 on_restart_sv = tmp;
2214
2215 ret = true;
2216 }
2217#endif
2218#ifdef GECODE_HAS_FLOAT_VARS
2219 if (on_restart_fv.size() > 0) {
2220 int base = 0;
2221
2222 // Assign the sol_float values (use lb if no solution is known)
2223 const FlatZincSpace* last = static_cast<const FlatZincSpace*>(mi.last());
2224 assert(last == nullptr || last->on_restart_fv.size() == restart_data().on_restart_fv_sol);
2225 for (int i = 0; i < restart_data().on_restart_fv_sol; ++i) {
2226 FloatVar& outVar = on_restart_fv[base + restart_data().on_restart_fv_sol + i];
2227 FloatVal solVal = (last != nullptr) ? last->on_restart_fv[i].val() : on_restart_fv[base + i].min();
2228 rel(*this, outVar, FRT_EQ, solVal);
2229 }
2230 base += restart_data().on_restart_fv_sol * 2;
2231
2232 // Assign last_val_float values
2233 for (size_t i = 0; i < restart_data().last_val_float.size(); ++i) {
2234 rel(*this, on_restart_fv[base + i], FRT_EQ, restart_data().last_val_float[i]);
2235 }
2236 base += restart_data().last_val_float.size();
2237
2238 // Assign uniform_float random values
2239 for (size_t i = 0; i < restart_data().uniform_range_float.size(); ++i) {
2240 const auto& range = restart_data().uniform_range_float[i];
2241 /* rndVal will be an element of [range.first, range.second] */
2242 const FloatVal rndVal =
2243 (static_cast<FloatVal>(_random(INT_MAX)) /
2244 static_cast<FloatVal>(INT_MAX - 1)) *
2245 (range.second - range.first) + range.first;
2246 rel(*this, on_restart_fv[base + i], FRT_EQ, rndVal);
2247 }
2248 base += restart_data().uniform_range_float.size();
2249 assert(base == on_restart_fv.size());
2250
2251 // Reduce on_restart_fv to only the variables required in a solution
2252 FloatVarArray tmp(*this, restart_data().on_restart_fv_sol);
2253 for (int i = 0; i < restart_data().on_restart_fv_sol; ++i) {
2254 tmp[i] = on_restart_fv[i];
2255 }
2256 on_restart_fv = tmp;
2257
2258 ret = true;
2259 }
2260#endif
2261 if (ret) {
2262 return false;
2263 }
2264 }
2265
2266 if ((mi.type() == MetaInfo::RESTART) && (mi.restart() != 0) &&
2267 (_lns > 0) && (mi.last()==nullptr) && (_lnsInitialSolution.size()>0)) {
2268 for (unsigned int i=iv_lns.size(); i--;) {
2269 if (_random(99U) <= _lns) {
2270 rel(*this, iv_lns[i], IRT_EQ, _lnsInitialSolution[i]);
2271 }
2272 }
2273 return false;
2274 } else if ((mi.type() == MetaInfo::RESTART) && (mi.restart() != 0) &&
2275 (_lns > 0) && mi.last()) {
2276 const FlatZincSpace& last =
2277 static_cast<const FlatZincSpace&>(*mi.last());
2278 for (unsigned int i=iv_lns.size(); i--;) {
2279 if (_random(99U) <= _lns) {
2280 rel(*this, iv_lns[i], IRT_EQ, last.iv_lns[i]);
2281 }
2282 }
2283 return false;
2284 }
2285 return true;
2286 }
2287
2288 Space*
2290 return new FlatZincSpace(*this);
2291 }
2292
2295 return _method;
2296 }
2297
2298 int
2300 return _optVar;
2301 }
2302
2303 bool
2305 return _optVarIsInt;
2306 }
2307
2308 void
2309 FlatZincSpace::print(std::ostream& out, const Printer& p) const {
2310 p.print(out, iv, bv
2312 , sv
2313#endif
2315 , fv
2316#endif
2317 );
2318 }
2319
2320 void
2321 FlatZincSpace::compare(const Space& s, std::ostream& out) const {
2322 (void) s; (void) out;
2323#ifdef GECODE_HAS_GIST
2324 const FlatZincSpace& fs = dynamic_cast<const FlatZincSpace&>(s);
2325 for (int i = 0; i < iv.size(); ++i) {
2326 std::stringstream ss;
2327 ss << "iv[" << i << "]";
2328 std::string result(Gecode::Gist::Comparator::compare(ss.str(), iv[i],
2329 fs.iv[i]));
2330 if (result.length() > 0) out << result << std::endl;
2331 }
2332 for (int i = 0; i < bv.size(); ++i) {
2333 std::stringstream ss;
2334 ss << "bv[" << i << "]";
2335 std::string result(Gecode::Gist::Comparator::compare(ss.str(), bv[i],
2336 fs.bv[i]));
2337 if (result.length() > 0) out << result << std::endl;
2338 }
2339#ifdef GECODE_HAS_SET_VARS
2340 for (int i = 0; i < sv.size(); ++i) {
2341 std::stringstream ss;
2342 ss << "sv[" << i << "]";
2343 std::string result(Gecode::Gist::Comparator::compare(ss.str(), sv[i],
2344 fs.sv[i]));
2345 if (result.length() > 0) out << result << std::endl;
2346 }
2347#endif
2348#ifdef GECODE_HAS_FLOAT_VARS
2349 for (int i = 0; i < fv.size(); ++i) {
2350 std::stringstream ss;
2351 ss << "fv[" << i << "]";
2352 std::string result(Gecode::Gist::Comparator::compare(ss.str(), fv[i],
2353 fs.fv[i]));
2354 if (result.length() > 0) out << result << std::endl;
2355 }
2356#endif
2357#endif
2358 }
2359
2360 void
2361 FlatZincSpace::compare(const FlatZincSpace& s, std::ostream& out,
2362 const Printer& p) const {
2363 p.printDiff(out, iv, s.iv, bv, s.bv
2365 , sv, s.sv
2366#endif
2368 , fv, s.fv
2369#endif
2370 );
2371 }
2372
2373 void
2375 p.shrinkArrays(*this, _optVar, _optVarIsInt, iv, bv
2377 , sv
2378#endif
2380 , fv
2381#endif
2382 );
2383 }
2384
2385 IntArgs
2387 AST::Array* a = arg->getArray();
2388 IntArgs ia(a->a.size()+offset);
2389 for (int i=offset; i--;)
2390 ia[i] = 0;
2391 for (int i=a->a.size(); i--;)
2392 ia[i+offset] = a->a[i]->getInt();
2393 return ia;
2394 }
2395 TupleSet
2396 FlatZincSpace::arg2tupleset(const IntArgs& a, int noOfVars) {
2397 int noOfTuples = a.size() == 0 ? 0 : (a.size()/noOfVars);
2398
2399 // Build TupleSet
2400 TupleSet ts(noOfVars);
2401 for (int i=0; i<noOfTuples; i++) {
2402 IntArgs t(noOfVars);
2403 for (int j=0; j<noOfVars; j++) {
2404 t[j] = a[i*noOfVars+j];
2405 }
2406 ts.add(t);
2407 }
2408 ts.finalize(EPK_AUTO);
2409
2410 if (_initData) {
2411 FlatZincSpaceInitData::TupleSetSet::iterator it = _initData->tupleSetSet.find(ts);
2412 if (it != _initData->tupleSetSet.end()) {
2413 return *it;
2414 }
2415 _initData->tupleSetSet.insert(ts);
2416 }
2417
2418
2419 return ts;
2420 }
2423 IntArgs ia(arg2intargs(arg,offset));
2424 SharedArray<int> sia(ia);
2425 if (_initData) {
2426 FlatZincSpaceInitData::IntSharedArraySet::iterator it = _initData->intSharedArraySet.find(sia);
2427 if (it != _initData->intSharedArraySet.end()) {
2428 return *it;
2429 }
2430 _initData->intSharedArraySet.insert(sia);
2431 }
2432
2433 return sia;
2434 }
2435 IntArgs
2437 AST::Array* a = arg->getArray();
2438 IntArgs ia(a->a.size()+offset);
2439 for (int i=offset; i--;)
2440 ia[i] = 0;
2441 for (int i=a->a.size(); i--;)
2442 ia[i+offset] = a->a[i]->getBool();
2443 return ia;
2444 }
2447 IntArgs ia(arg2boolargs(arg,offset));
2448 SharedArray<int> sia(ia);
2449 if (_initData) {
2450 FlatZincSpaceInitData::IntSharedArraySet::iterator it = _initData->intSharedArraySet.find(sia);
2451 if (it != _initData->intSharedArraySet.end()) {
2452 return *it;
2453 }
2454 _initData->intSharedArraySet.insert(sia);
2455 }
2456
2457 return sia;
2458 }
2459 IntSet
2461 AST::SetLit* sl = n->getSet();
2462 IntSet d;
2463 if (sl->interval) {
2464 d = IntSet(sl->min, sl->max);
2465 } else {
2466 Region re;
2467 int* is = re.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
2468 for (int i=sl->s.size(); i--; )
2469 is[i] = sl->s[i];
2470 d = IntSet(is, sl->s.size());
2471 }
2472 return d;
2473 }
2476 AST::Array* a = arg->getArray();
2477 if (a->a.size() == 0) {
2478 IntSetArgs emptyIa(0);
2479 return emptyIa;
2480 }
2481 IntSetArgs ia(a->a.size()+offset);
2482 for (int i=offset; i--;)
2483 ia[i] = IntSet::empty;
2484 for (int i=a->a.size(); i--;) {
2485 ia[i+offset] = arg2intset(a->a[i]);
2486 }
2487 return ia;
2488 }
2491 AST::Array* a = arg->getArray();
2492 if (a->a.size() == 0) {
2493 IntVarArgs emptyIa(0);
2494 return emptyIa;
2495 }
2496 IntVarArgs ia(a->a.size()+offset);
2497 for (int i=offset; i--;)
2498 ia[i] = IntVar(*this, 0, 0);
2499 for (int i=a->a.size(); i--;) {
2500 if (a->a[i]->isIntVar()) {
2501 ia[i+offset] = iv[a->a[i]->getIntVar()];
2502 } else {
2503 int value = a->a[i]->getInt();
2504 IntVar iv(*this, value, value);
2505 ia[i+offset] = iv;
2506 }
2507 }
2508 return ia;
2509 }
2511 FlatZincSpace::arg2boolvarargs(AST::Node* arg, int offset, int siv) {
2512 AST::Array* a = arg->getArray();
2513 if (a->a.size() == 0) {
2514 BoolVarArgs emptyIa(0);
2515 return emptyIa;
2516 }
2517 BoolVarArgs ia(a->a.size()+offset-(siv==-1?0:1));
2518 for (int i=offset; i--;)
2519 ia[i] = BoolVar(*this, 0, 0);
2520 for (int i=0; i<static_cast<int>(a->a.size()); i++) {
2521 if (i==siv)
2522 continue;
2523 if (a->a[i]->isBool()) {
2524 bool value = a->a[i]->getBool();
2525 BoolVar iv(*this, value, value);
2526 ia[offset++] = iv;
2527 } else if (a->a[i]->isIntVar() &&
2528 aliasBool2Int(a->a[i]->getIntVar()) != -1) {
2529 ia[offset++] = bv[aliasBool2Int(a->a[i]->getIntVar())];
2530 } else {
2531 ia[offset++] = bv[a->a[i]->getBoolVar()];
2532 }
2533 }
2534 return ia;
2535 }
2536 BoolVar
2538 BoolVar x0;
2539 if (n->isBool()) {
2540 x0 = BoolVar(*this, n->getBool(), n->getBool());
2541 }
2542 else {
2543 x0 = bv[n->getBoolVar()];
2544 }
2545 return x0;
2546 }
2547 IntVar
2549 IntVar x0;
2550 if (n->isIntVar()) {
2551 x0 = iv[n->getIntVar()];
2552 } else {
2553 x0 = IntVar(*this, n->getInt(), n->getInt());
2554 }
2555 return x0;
2556 }
2557 bool
2559 AST::Array* a = b->getArray();
2560 singleInt = -1;
2561 if (a->a.size() == 0)
2562 return true;
2563 for (int i=a->a.size(); i--;) {
2564 if (a->a[i]->isBoolVar() || a->a[i]->isBool()) {
2565 } else if (a->a[i]->isIntVar()) {
2566 if (aliasBool2Int(a->a[i]->getIntVar()) == -1) {
2567 if (singleInt != -1) {
2568 return false;
2569 }
2570 singleInt = i;
2571 }
2572 } else {
2573 return false;
2574 }
2575 }
2576 return singleInt==-1 || a->a.size() > 1;
2577 }
2578#ifdef GECODE_HAS_SET_VARS
2579 SetVar
2581 SetVar x0;
2582 if (!n->isSetVar()) {
2583 IntSet d = arg2intset(n);
2584 x0 = SetVar(*this, d, d);
2585 } else {
2586 x0 = sv[n->getSetVar()];
2587 }
2588 return x0;
2589 }
2591 FlatZincSpace::arg2setvarargs(AST::Node* arg, int offset, int doffset,
2592 const IntSet& od) {
2593 AST::Array* a = arg->getArray();
2594 SetVarArgs ia(a->a.size()+offset);
2595 for (int i=offset; i--;) {
2596 IntSet d = i<doffset ? od : IntSet::empty;
2597 ia[i] = SetVar(*this, d, d);
2598 }
2599 for (int i=a->a.size(); i--;) {
2600 ia[i+offset] = arg2SetVar(a->a[i]);
2601 }
2602 return ia;
2603 }
2604#endif
2605#ifdef GECODE_HAS_FLOAT_VARS
2608 AST::Array* a = arg->getArray();
2609 FloatValArgs fa(a->a.size()+offset);
2610 for (int i=offset; i--;)
2611 fa[i] = 0.0;
2612 for (int i=a->a.size(); i--;)
2613 fa[i+offset] = a->a[i]->getFloat();
2614 return fa;
2615 }
2618 AST::Array* a = arg->getArray();
2619 if (a->a.size() == 0) {
2620 FloatVarArgs emptyFa(0);
2621 return emptyFa;
2622 }
2623 FloatVarArgs fa(a->a.size()+offset);
2624 for (int i=offset; i--;)
2625 fa[i] = FloatVar(*this, 0.0, 0.0);
2626 for (int i=a->a.size(); i--;) {
2627 if (a->a[i]->isFloatVar()) {
2628 fa[i+offset] = fv[a->a[i]->getFloatVar()];
2629 } else {
2630 double value = a->a[i]->getFloat();
2631 FloatVar fv(*this, value, value);
2632 fa[i+offset] = fv;
2633 }
2634 }
2635 return fa;
2636 }
2637 FloatVar
2639 FloatVar x0;
2640 if (n->isFloatVar()) {
2641 x0 = fv[n->getFloatVar()];
2642 } else {
2643 x0 = FloatVar(*this, n->getFloat(), n->getFloat());
2644 }
2645 return x0;
2646 }
2647#endif
2650 if (ann) {
2651 if (ann->hasAtom("val") || ann->hasAtom("value_propagation"))
2652 return IPL_VAL;
2653 if (ann->hasAtom("domain") || ann->hasAtom("domain_propagation"))
2654 return IPL_DOM;
2655 if (ann->hasAtom("bounds") ||
2656 ann->hasAtom("bounds_propagation") ||
2657 ann->hasAtom("boundsR") ||
2658 ann->hasAtom("boundsD") ||
2659 ann->hasAtom("boundsZ"))
2660 return IPL_BND;
2661 }
2662 return IPL_DEF;
2663 }
2664
2665 DFA
2667 if (_initData) {
2668 FlatZincSpaceInitData::DFASet::iterator it = _initData->dfaSet.find(a);
2669 if (it != _initData->dfaSet.end()) {
2670 return *it;
2671 }
2672 _initData->dfaSet.insert(a);
2673 }
2674 return a;
2675 }
2676
2677 void
2679 _output = output;
2680 }
2681
2682 void
2683 Printer::printElem(std::ostream& out,
2684 AST::Node* ai,
2685 const Gecode::IntVarArray& iv,
2686 const Gecode::BoolVarArray& bv
2688 , const Gecode::SetVarArray& sv
2689#endif
2691 ,
2692 const Gecode::FloatVarArray& fv
2693#endif
2694 ) const {
2695 int k;
2696 if (ai->isInt(k)) {
2697 out << k;
2698 } else if (ai->isIntVar()) {
2699 out << iv[ai->getIntVar()];
2700 } else if (ai->isBoolVar()) {
2701 if (bv[ai->getBoolVar()].min() == 1) {
2702 out << "true";
2703 } else if (bv[ai->getBoolVar()].max() == 0) {
2704 out << "false";
2705 } else {
2706 out << "false..true";
2707 }
2708#ifdef GECODE_HAS_SET_VARS
2709 } else if (ai->isSetVar()) {
2710 if (!sv[ai->getSetVar()].assigned()) {
2711 out << sv[ai->getSetVar()];
2712 return;
2713 }
2714 SetVarGlbRanges svr(sv[ai->getSetVar()]);
2715 if (!svr()) {
2716 out << "{}";
2717 return;
2718 }
2719 int min = svr.min();
2720 int max = svr.max();
2721 ++svr;
2722 if (svr()) {
2723 SetVarGlbValues svv(sv[ai->getSetVar()]);
2724 int i = svv.val();
2725 out << "{" << i;
2726 ++svv;
2727 for (; svv(); ++svv)
2728 out << ", " << svv.val();
2729 out << "}";
2730 } else {
2731 out << min << ".." << max;
2732 }
2733#endif
2734#ifdef GECODE_HAS_FLOAT_VARS
2735 } else if (ai->isFloatVar()) {
2736 if (fv[ai->getFloatVar()].assigned()) {
2737 FloatVal vv = fv[ai->getFloatVar()].val();
2738 FloatNum v;
2739 if (vv.singleton())
2740 v = vv.min();
2741 else if (vv < 0.0)
2742 v = vv.max();
2743 else
2744 v = vv.min();
2745 std::ostringstream oss;
2746 // oss << std::scientific;
2747 oss << std::setprecision(std::numeric_limits<double>::digits10);
2748 oss << v;
2749 if (oss.str().find(".") == std::string::npos)
2750 oss << ".0";
2751 out << oss.str();
2752 } else {
2753 out << fv[ai->getFloatVar()];
2754 }
2755#endif
2756 } else if (ai->isBool()) {
2757 out << (ai->getBool() ? "true" : "false");
2758 } else if (ai->isSet()) {
2759 AST::SetLit* s = ai->getSet();
2760 if (s->interval) {
2761 out << s->min << ".." << s->max;
2762 } else {
2763 out << "{";
2764 for (unsigned int i=0; i<s->s.size(); i++) {
2765 out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
2766 }
2767 }
2768 } else if (ai->isString()) {
2769 std::string s = ai->getString();
2770 for (unsigned int i=0; i<s.size(); i++) {
2771 if (s[i] == '\\' && i<s.size()-1) {
2772 switch (s[i+1]) {
2773 case 'n': out << "\n"; break;
2774 case '\\': out << "\\"; break;
2775 case 't': out << "\t"; break;
2776 default: out << "\\" << s[i+1];
2777 }
2778 i++;
2779 } else {
2780 out << s[i];
2781 }
2782 }
2783 }
2784 }
2785
2786 void
2787 Printer::printElemDiff(std::ostream& out,
2788 AST::Node* ai,
2789 const Gecode::IntVarArray& iv1,
2790 const Gecode::IntVarArray& iv2,
2791 const Gecode::BoolVarArray& bv1,
2792 const Gecode::BoolVarArray& bv2
2794 , const Gecode::SetVarArray& sv1,
2795 const Gecode::SetVarArray& sv2
2796#endif
2798 , const Gecode::FloatVarArray& fv1,
2799 const Gecode::FloatVarArray& fv2
2800#endif
2801 ) const {
2802#ifdef GECODE_HAS_GIST
2803 using namespace Gecode::Gist;
2804 int k;
2805 if (ai->isInt(k)) {
2806 out << k;
2807 } else if (ai->isIntVar()) {
2808 std::string res(Comparator::compare("",iv1[ai->getIntVar()],
2809 iv2[ai->getIntVar()]));
2810 if (res.length() > 0) {
2811 res.erase(0, 1); // Remove '='
2812 out << res;
2813 } else {
2814 out << iv1[ai->getIntVar()];
2815 }
2816 } else if (ai->isBoolVar()) {
2817 std::string res(Comparator::compare("",bv1[ai->getBoolVar()],
2818 bv2[ai->getBoolVar()]));
2819 if (res.length() > 0) {
2820 res.erase(0, 1); // Remove '='
2821 out << res;
2822 } else {
2823 out << bv1[ai->getBoolVar()];
2824 }
2825#ifdef GECODE_HAS_SET_VARS
2826 } else if (ai->isSetVar()) {
2827 std::string res(Comparator::compare("",sv1[ai->getSetVar()],
2828 sv2[ai->getSetVar()]));
2829 if (res.length() > 0) {
2830 res.erase(0, 1); // Remove '='
2831 out << res;
2832 } else {
2833 out << sv1[ai->getSetVar()];
2834 }
2835#endif
2836#ifdef GECODE_HAS_FLOAT_VARS
2837 } else if (ai->isFloatVar()) {
2838 std::string res(Comparator::compare("",fv1[ai->getFloatVar()],
2839 fv2[ai->getFloatVar()]));
2840 if (res.length() > 0) {
2841 res.erase(0, 1); // Remove '='
2842 out << res;
2843 } else {
2844 out << fv1[ai->getFloatVar()];
2845 }
2846#endif
2847 } else if (ai->isBool()) {
2848 out << (ai->getBool() ? "true" : "false");
2849 } else if (ai->isSet()) {
2850 AST::SetLit* s = ai->getSet();
2851 if (s->interval) {
2852 out << s->min << ".." << s->max;
2853 } else {
2854 out << "{";
2855 for (unsigned int i=0; i<s->s.size(); i++) {
2856 out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
2857 }
2858 }
2859 } else if (ai->isString()) {
2860 std::string s = ai->getString();
2861 for (unsigned int i=0; i<s.size(); i++) {
2862 if (s[i] == '\\' && i<s.size()-1) {
2863 switch (s[i+1]) {
2864 case 'n': out << "\n"; break;
2865 case '\\': out << "\\"; break;
2866 case 't': out << "\t"; break;
2867 default: out << "\\" << s[i+1];
2868 }
2869 i++;
2870 } else {
2871 out << s[i];
2872 }
2873 }
2874 }
2875#else
2876 (void) out;
2877 (void) ai;
2878 (void) iv1;
2879 (void) iv2;
2880 (void) bv1;
2881 (void) bv2;
2882#ifdef GECODE_HAS_SET_VARS
2883 (void) sv1;
2884 (void) sv2;
2885#endif
2886#ifdef GECODE_HAS_FLOAT_VARS
2887 (void) fv1;
2888 (void) fv2;
2889#endif
2890
2891#endif
2892 }
2893
2894 void
2895 Printer::print(std::ostream& out,
2896 const Gecode::IntVarArray& iv,
2897 const Gecode::BoolVarArray& bv
2899 ,
2900 const Gecode::SetVarArray& sv
2901#endif
2903 ,
2904 const Gecode::FloatVarArray& fv
2905#endif
2906 ) const {
2907 if (_output == nullptr)
2908 return;
2909 for (unsigned int i=0; i< _output->a.size(); i++) {
2910 AST::Node* ai = _output->a[i];
2911 if (ai->isArray()) {
2912 AST::Array* aia = ai->getArray();
2913 int size = aia->a.size();
2914 out << "[";
2915 for (int j=0; j<size; j++) {
2916 printElem(out,aia->a[j],iv,bv
2918 ,sv
2919#endif
2921 ,fv
2922#endif
2923 );
2924 if (j<size-1)
2925 out << ", ";
2926 }
2927 out << "]";
2928 } else {
2929 printElem(out,ai,iv,bv
2931 ,sv
2932#endif
2934 ,fv
2935#endif
2936 );
2937 }
2938 }
2939 }
2940
2941 void
2942 Printer::printDiff(std::ostream& out,
2943 const Gecode::IntVarArray& iv1,
2944 const Gecode::IntVarArray& iv2,
2945 const Gecode::BoolVarArray& bv1,
2946 const Gecode::BoolVarArray& bv2
2948 ,
2949 const Gecode::SetVarArray& sv1,
2950 const Gecode::SetVarArray& sv2
2951#endif
2953 ,
2954 const Gecode::FloatVarArray& fv1,
2955 const Gecode::FloatVarArray& fv2
2956#endif
2957 ) const {
2958 if (_output == nullptr)
2959 return;
2960 for (unsigned int i=0; i< _output->a.size(); i++) {
2961 AST::Node* ai = _output->a[i];
2962 if (ai->isArray()) {
2963 AST::Array* aia = ai->getArray();
2964 int size = aia->a.size();
2965 out << "[";
2966 for (int j=0; j<size; j++) {
2967 printElemDiff(out,aia->a[j],iv1,iv2,bv1,bv2
2969 ,sv1,sv2
2970#endif
2972 ,fv1,fv2
2973#endif
2974 );
2975 if (j<size-1)
2976 out << ", ";
2977 }
2978 out << "]";
2979 } else {
2980 printElemDiff(out,ai,iv1,iv2,bv1,bv2
2982 ,sv1,sv2
2983#endif
2985 ,fv1,fv2
2986#endif
2987 );
2988 }
2989 }
2990 }
2991
2992 void
2993 Printer::addIntVarName(const std::string& n) {
2994 iv_names.push_back(n);
2995 }
2996 void
2997 Printer::addBoolVarName(const std::string& n) {
2998 bv_names.push_back(n);
2999 }
3000#ifdef GECODE_HAS_FLOAT_VARS
3001 void
3002 Printer::addFloatVarName(const std::string& n) {
3003 fv_names.push_back(n);
3004 }
3005#endif
3006#ifdef GECODE_HAS_SET_VARS
3007 void
3008 Printer::addSetVarName(const std::string& n) {
3009 sv_names.push_back(n);
3010 }
3011#endif
3012
3013 void
3015 std::map<int,int>& iv, std::map<int,int>& bv,
3016 std::map<int,int>& sv, std::map<int,int>& fv) {
3017 if (node->isIntVar()) {
3018 AST::IntVar* x = static_cast<AST::IntVar*>(node);
3019 if (iv.find(x->i) == iv.end()) {
3020 int newi = iv.size();
3021 iv[x->i] = newi;
3022 }
3023 x->i = iv[x->i];
3024 } else if (node->isBoolVar()) {
3025 AST::BoolVar* x = static_cast<AST::BoolVar*>(node);
3026 if (bv.find(x->i) == bv.end()) {
3027 int newi = bv.size();
3028 bv[x->i] = newi;
3029 }
3030 x->i = bv[x->i];
3031 } else if (node->isSetVar()) {
3032 AST::SetVar* x = static_cast<AST::SetVar*>(node);
3033 if (sv.find(x->i) == sv.end()) {
3034 int newi = sv.size();
3035 sv[x->i] = newi;
3036 }
3037 x->i = sv[x->i];
3038 } else if (node->isFloatVar()) {
3039 AST::FloatVar* x = static_cast<AST::FloatVar*>(node);
3040 if (fv.find(x->i) == fv.end()) {
3041 int newi = fv.size();
3042 fv[x->i] = newi;
3043 }
3044 x->i = fv[x->i];
3045 }
3046 }
3047
3048 void
3050 int& optVar, bool optVarIsInt,
3054 ,
3056#endif
3058 ,
3060#endif
3061 ) {
3062 if (_output == nullptr) {
3063 if (optVarIsInt && optVar != -1) {
3064 IntVar ov = iv[optVar];
3065 iv = IntVarArray(home, 1);
3066 iv[0] = ov;
3067 optVar = 0;
3068 } else {
3069 iv = IntVarArray(home, 0);
3070 }
3071 bv = BoolVarArray(home, 0);
3072#ifdef GECODE_HAS_SET_VARS
3073 sv = SetVarArray(home, 0);
3074#endif
3075#ifdef GECODE_HAS_FLOAT_VARS
3076 if (!optVarIsInt && optVar != -1) {
3077 FloatVar ov = fv[optVar];
3078 fv = FloatVarArray(home, 1);
3079 fv[0] = ov;
3080 optVar = 0;
3081 } else {
3082 fv = FloatVarArray(home,0);
3083 }
3084#endif
3085 return;
3086 }
3087 std::map<int,int> iv_new;
3088 std::map<int,int> bv_new;
3089 std::map<int,int> sv_new;
3090 std::map<int,int> fv_new;
3091
3092 if (optVar != -1) {
3093 if (optVarIsInt)
3094 iv_new[optVar] = 0;
3095 else
3096 fv_new[optVar] = 0;
3097 optVar = 0;
3098 }
3099
3100 for (unsigned int i=0; i< _output->a.size(); i++) {
3101 AST::Node* ai = _output->a[i];
3102 if (ai->isArray()) {
3103 AST::Array* aia = ai->getArray();
3104 for (unsigned int j=0; j<aia->a.size(); j++) {
3105 shrinkElement(aia->a[j],iv_new,bv_new,sv_new,fv_new);
3106 }
3107 } else {
3108 shrinkElement(ai,iv_new,bv_new,sv_new,fv_new);
3109 }
3110 }
3111
3112 IntVarArgs iva(iv_new.size());
3113 std::vector<std::string> iv_names_new(iv_new.size());
3114 for (std::map<int,int>::iterator i=iv_new.begin(); i != iv_new.end(); ++i) {
3115 iva[(*i).second] = iv[(*i).first];
3116 iv_names_new[(*i).second] = iv_names[(*i).first];
3117 }
3118 iv = IntVarArray(home, iva);
3119 iv_names = iv_names_new;
3120
3121 BoolVarArgs bva(bv_new.size());
3122 std::vector<std::string> bv_names_new(bv_new.size());
3123 for (std::map<int,int>::iterator i=bv_new.begin(); i != bv_new.end(); ++i) {
3124 bva[(*i).second] = bv[(*i).first];
3125 bv_names_new[(*i).second] = bv_names[(*i).first];
3126 }
3127 bv = BoolVarArray(home, bva);
3128 bv_names = bv_names_new;
3129
3130#ifdef GECODE_HAS_SET_VARS
3131 SetVarArgs sva(sv_new.size());
3132 std::vector<std::string> sv_names_new(sv_new.size());
3133 for (std::map<int,int>::iterator i=sv_new.begin(); i != sv_new.end(); ++i) {
3134 sva[(*i).second] = sv[(*i).first];
3135 sv_names_new[(*i).second] = sv_names[(*i).first];
3136 }
3137 sv = SetVarArray(home, sva);
3138 sv_names = sv_names_new;
3139#endif
3140
3141#ifdef GECODE_HAS_FLOAT_VARS
3142 FloatVarArgs fva(fv_new.size());
3143 std::vector<std::string> fv_names_new(fv_new.size());
3144 for (std::map<int,int>::iterator i=fv_new.begin(); i != fv_new.end(); ++i) {
3145 fva[(*i).second] = fv[(*i).first];
3146 fv_names_new[(*i).second] = fv_names[(*i).first];
3147 }
3148 fv = FloatVarArray(home, fva);
3149 fv_names = fv_names_new;
3150#endif
3151 }
3152
3154 delete _output;
3155 }
3156
3157}}
3158
3159// STATISTICS: flatzinc-any
Archive representation
Definition archive.hpp:42
void put(unsigned int i)
Add i to the contents.
Definition archive.hpp:174
T * a
Element array.
Definition array.hpp:548
int size(void) const
Return size of array (number of elements).
Definition array.hpp:1597
Depth-first branch-and-bound search engine.
Definition search.hh:1114
Which values to select for assignment.
Definition int.hh:5346
Which values to select for branching first.
Definition int.hh:5235
Passing Boolean variables.
Definition int.hh:738
Boolean variable array.
Definition int.hh:839
Boolean integer variables.
Definition int.hh:533
Group of branchers.
Definition core.hpp:806
Base-class for branchers.
Definition core.hpp:1453
friend class Space
Definition core.hpp:1455
Brancher(Home home)
Constructor for creation.
Definition core.hpp:3714
friend class Choice
Definition core.hpp:1456
Class to send solution information to CPProfiler.
Definition search.hh:427
Choice for performing commit
Definition core.hpp:1423
virtual void archive(Archive &e) const
Archive into e.
Definition core.cpp:946
Deterministic finite automaton (DFA).
Definition int.hh:2203
Depth-first search engine.
Definition search.hh:1080
static void installCtrlHandler(bool install, bool force=false)
Install handler for catching Ctrl-C.
Definition script.hpp:127
Exception: Base-class for exceptions
Definition exception.hpp:42
virtual const char * what(void) const noexcept
Return information.
Definition exception.cpp:55
std::vector< Node * > a
Definition ast.hh:233
Node representing an atom
Definition ast.hh:290
Boolean variable node.
Definition ast.hh:197
Node representing a function call
Definition ast.hh:255
Array * getArgs(unsigned int n)
Definition ast.hh:265
Float variable node.
Definition ast.hh:214
Integer variable node.
Definition ast.hh:206
A node in a FlatZinc abstract syntax tree.
Definition ast.hh:67
bool isSetVar(void)
Test if node is a set variable node.
Definition ast.hh:478
Array * getArray(void)
Cast this node to an array node.
Definition ast.hh:396
bool isBool(void)
Test if node is a Boolean node.
Definition ast.hh:490
bool isFloatVar(void)
Test if node is a float variable node.
Definition ast.hh:482
bool isSet(void)
Test if node is a set literal node.
Definition ast.hh:498
double getFloat(void)
Cast this node to a Float node.
Definition ast.hh:452
int getFloatVar(void)
Cast this node to a Float variable node.
Definition ast.hh:428
bool isArray(void)
Test if node is an array node.
Definition ast.hh:506
SetLit * getSet(void)
Cast this node to a set literal node.
Definition ast.hh:458
bool isString(void)
Test if node is a string node.
Definition ast.hh:502
bool hasAtom(const std::string &id)
Test if node has atom with id.
Definition ast.hh:321
bool isInt(int &i)
Test if node is int, if yes set i to the value.
Definition ast.hh:364
int getInt(void)
Cast this node to an integer node.
Definition ast.hh:440
bool isIntVar(void)
Test if node is an integer variable node.
Definition ast.hh:470
int getIntVar(void)
Cast this node to an integer variable node.
Definition ast.hh:416
bool isBoolVar(void)
Test if node is a Boolean variable node.
Definition ast.hh:474
Call * getCall(void)
Return function call.
Definition ast.hh:343
int getBoolVar(void)
Cast this node to a Boolean variable node.
Definition ast.hh:422
virtual void print(std::ostream &)=0
Output string representation.
int getSetVar(void)
Cast this node to a set variable node.
Definition ast.hh:434
bool getBool(void)
Cast this node to a Boolean node.
Definition ast.hh:446
std::string getString(void)
Cast this node to a string node.
Definition ast.hh:464
Set literal node
Definition ast.hh:171
std::vector< int > s
Definition ast.hh:175
Set variable node
Definition ast.hh:222
Exception signaling type error
Definition ast.hh:55
Choice that only signals failure or success
Definition flatzinc.cpp:141
bool fail
Whether brancher should fail.
Definition flatzinc.cpp:144
virtual size_t size(void) const
Report size occupied.
Definition flatzinc.cpp:149
Choice(const Brancher &b, bool fail0)
Initialize choice for brancher b.
Definition flatzinc.cpp:146
virtual void archive(Archive &e) const
Archive into e.
Definition flatzinc.cpp:153
virtual Choice * choice(const Space &, Archive &e)
Return choice.
Definition flatzinc.cpp:215
TieBreak< BoolVarBranch > bool_varsel
Definition flatzinc.cpp:161
virtual void print(const Space &, const Gecode::Choice &c, unsigned int, std::ostream &o) const
Print explanation.
Definition flatzinc.cpp:224
TieBreak< IntVarBranch > int_varsel
Definition flatzinc.cpp:159
virtual bool status(const Space &_home) const
Check status of brancher, return true if alternatives left.
Definition flatzinc.cpp:174
bool done
Flag whether brancher is done.
Definition flatzinc.cpp:109
virtual Actor * copy(Space &home)
Copy brancher.
Definition flatzinc.cpp:232
static void post(Home home, TieBreak< IntVarBranch > int_varsel, IntValBranch int_valsel, TieBreak< BoolVarBranch > bool_varsel, BoolValBranch bool_valsel, SetVarBranch set_varsel, SetValBranch set_valsel, TieBreak< FloatVarBranch > float_varsel, FloatValBranch float_valsel)
Post brancher.
Definition flatzinc.cpp:236
TieBreak< FloatVarBranch > float_varsel
Definition flatzinc.cpp:168
virtual Choice * choice(Space &home)
Return choice.
Definition flatzinc.cpp:193
virtual ExecStatus commit(Space &, const Gecode::Choice &c, unsigned int)
Perform commit for choice c.
Definition flatzinc.cpp:220
virtual size_t dispose(Space &)
Delete brancher and return its size.
Definition flatzinc.cpp:263
AuxVarBrancher(Home home, TieBreak< IntVarBranch > int_varsel0, IntValBranch int_valsel0, TieBreak< BoolVarBranch > bool_varsel0, BoolValBranch bool_valsel0, SetVarBranch set_varsel0, SetValBranch set_valsel0, TieBreak< FloatVarBranch > float_varsel0, FloatValBranch float_valsel0)
Construct brancher.
Definition flatzinc.cpp:111
AuxVarBrancher(Space &home, AuxVarBrancher &b)
Copy constructor.
Definition flatzinc.cpp:137
static BlackBoxContextHandle & context(FlatZincSpace &s)
Definition flatzinc.cpp:873
Model-local context shared by blackbox propagators and search support.
Definition blackbox.hh:56
void rethrow(void) const
Rethrow the first recorded propagation exception.
Specification for Boolean variables.
Definition varspec.hh:97
Option< AST::SetLit * > domain
Definition varspec.hh:99
void print(const Brancher &b, unsigned int a, int i, int n, std::ostream &o) const
Output branch information.
Definition flatzinc.cpp:296
void add(BrancherGroup bg, const std::string &rel0, const std::string &rel1, const std::vector< std::string > &n)
Add new brancher information.
Definition flatzinc.cpp:288
void print(const Brancher &b, unsigned int a, int i, const FloatNumBranch &nl, std::ostream &o) const
Definition flatzinc.cpp:302
virtual SharedHandle::Object * copy(void) const
Definition flatzinc.cpp:284
void init(void)
Initialise for use.
Definition flatzinc.cpp:319
void print(const Brancher &b, unsigned int a, int i, int n, std::ostream &o) const
Output branch information.
Definition flatzinc.cpp:332
void add(BrancherGroup bg, const std::string &rel0, const std::string &rel1, const std::vector< std::string > &n)
Add new brancher information.
Definition flatzinc.cpp:325
Abstract representation of a constraint.
Definition conexpr.hh:43
AST::Array * ann
Constraint annotations.
Definition conexpr.hh:50
Exception class for FlatZinc errors
Definition flatzinc.hh:727
virtual void compare(const Space &s0, const Space &s1)
Use the compare method of the template class S to compare two spaces.
FZPrintingComparator(const Printer &p0)
Constructor.
An inspector for printing simple text output.
virtual void finalize(void)
Finalize when Gist exits.
FZPrintingInspector(const Printer &p0)
Constructor.
virtual void inspect(const Space &node)
Use the print method of the template class S to print a space.
FlatZincGetInfo(const Printer &printer)
virtual std::string getInfo(const Space &space) const
Return info for a space.
Options for running FlatZinc models
Definition flatzinc.hh:226
std::unordered_set< TupleSet > TupleSetSet
Hash table of tuple sets.
Definition flatzinc.cpp:760
BlackBoxContextHandle blackBoxContext
Opaque state shared by blackbox propagators in this model.
Definition flatzinc.cpp:775
DFASet dfaSet
Hash table of DFAs.
Definition flatzinc.cpp:772
std::unordered_set< DFA > DFASet
Hash table of DFAs.
Definition flatzinc.cpp:770
IntSharedArraySet intSharedArraySet
Hash table of shared integer arrays.
Definition flatzinc.cpp:767
TupleSetSet tupleSetSet
Hash table of tuple sets.
Definition flatzinc.cpp:762
std::unordered_set< SharedArray< int > > IntSharedArraySet
Hash table of shared integer arrays.
Definition flatzinc.cpp:765
A space that can be initialized with a FlatZinc model.
Definition flatzinc.hh:424
void createBranchers(Printer &p, AST::Node *ann, FlatZincOptions &opt, bool ignoreUnknown, std::ostream &err=std::cerr)
Create branchers corresponding to the solve item annotations.
Gecode::IntVarArray iv_lns
The integer variables used in LNS.
Definition flatzinc.hh:487
void shrinkArrays(Printer &p)
Remove all variables not needed for output.
unsigned int _lns
Percentage of variables to keep in LNS (or 0 for no LNS).
Definition flatzinc.hh:452
void maximize(int var, bool isInt, AST::Array *annotation)
Post that integer variable var should be maximized.
IntVarArgs arg2intvarargs(AST::Node *arg, int offset=0)
Convert arg to IntVarArgs.
Gecode::FloatVarArray fv
The float variables.
Definition flatzinc.hh:574
Rnd _random
Random number generator.
Definition flatzinc.hh:458
Gecode::FloatVarArray on_restart_fv
On Restart Tracked Floating Point Variables.
Definition flatzinc.hh:550
void newBoolVar(BoolVarSpec *vs)
Create new Boolean variable from specification.
Definition flatzinc.cpp:931
FloatVar arg2FloatVar(AST::Node *n)
Convert n to FloatVar.
void print(std::ostream &out, const Printer &p) const
Produce output on out using p.
std::vector< bool > fv_introduced
Indicates whether a float variable is introduced by mzn2fzn.
Definition flatzinc.hh:578
AST::Array * _solveAnnotations
Annotations on the solve item.
Definition flatzinc.hh:461
int _optVar
Index of the variable to optimize.
Definition flatzinc.hh:444
BranchInformation branchInfo
Information for printing branches.
Definition flatzinc.hh:669
void run(std::ostream &out, const Printer &p, const FlatZincOptions &opt, Gecode::Support::Timer &t_total)
Run the search.
DFA getSharedDFA(DFA &a)
Share DFA a if possible.
void newFloatVar(FloatVarSpec *vs)
Create new float variable from specification.
Definition flatzinc.cpp:990
SetVar arg2SetVar(AST::Node *n)
Convert n to SetVar.
int * iv_boolalias
Indicates whether an integer variable aliases a Boolean variable.
Definition flatzinc.hh:557
virtual bool slave(const MetaInfo &mi)
Slave function for restarts.
void postConstraints(std::vector< ConExpr * > &ces)
Post a constraint specified by ce.
SetVarArgs arg2setvarargs(AST::Node *arg, int offset=0, int doffset=0, const IntSet &od=IntSet::empty)
Convert n to SetVarArgs.
bool _optVarIsInt
Whether variable to optimize is integer (or float).
Definition flatzinc.hh:446
FlatZincSpace(FlatZincSpace &)
Copy constructor.
Definition flatzinc.cpp:781
Gecode::BoolVarArray bv
The Boolean variables.
Definition flatzinc.hh:559
void newSetVar(SetVarSpec *vs)
Create new set variable from specification.
Definition flatzinc.cpp:943
bool optVarIsInt(void) const
Return whether variable used for optimization is integer (or float).
Gecode::SetVarArray on_restart_sv
On Restart Tracked Set Variables.
Definition flatzinc.hh:546
std::vector< bool > iv_introduced
Indicates whether an integer variable is introduced by mzn2fzn.
Definition flatzinc.hh:555
IntVar arg2IntVar(AST::Node *n)
Convert n to IntVar.
std::string getDomains(const Printer &p) const
Get string representing the domains of variables (for cpprofiler).
FlatZincSpaceInitData * _initData
Initialisation data (only used for posting constraints).
Definition flatzinc.hh:433
Meth method(void) const
Return whether to solve a satisfaction or optimization problem.
std::vector< bool > sv_introduced
Indicates whether a set variable is introduced by mzn2fzn.
Definition flatzinc.hh:570
IntSet arg2intset(AST::Node *n)
Convert n to IntSet.
std::vector< bool > bv_introduced
Indicates whether a Boolean variable is introduced by mzn2fzn.
Definition flatzinc.hh:563
Gecode::FloatVarArray fv_aux
The introduced float variables.
Definition flatzinc.hh:576
void minimize(int var, bool isInt, AST::Array *annotation)
Post that integer variable var should be minimized.
virtual void constrain(const Space &s)
Implement optimization.
IntArgs arg2boolargs(AST::Node *arg, int offset=0)
Convert arg (array of Booleans) to IntArgs.
Gecode::SetVarArray sv_aux
The introduced set variables.
Definition flatzinc.hh:568
int floatVarCount
Number of float variables.
Definition flatzinc.hh:439
int boolVarCount
Number of Boolean variables.
Definition flatzinc.hh:437
Gecode::SetVarArray sv
The set variables.
Definition flatzinc.hh:566
int setVarCount
Number of set variables.
Definition flatzinc.hh:441
Gecode::IntVarArray on_restart_iv
On Restart Tracked Integer Variables.
Definition flatzinc.hh:541
int optVar(void) const
Return index of variable used for optimization.
FloatVarArgs arg2floatvarargs(AST::Node *arg, int offset=0)
Convert n to FloatVarArgs.
IntSharedArray arg2boolsharedarray(AST::Node *arg, int offset=0)
Convert arg (array of integers) to IntSharedArray.
void solve(AST::Array *annotation)
Post the solve item.
Gecode::FloatNum step
Step by which a next solution has to have lower cost.
Definition flatzinc.hh:580
IntSharedArray _lnsInitialSolution
Initial solution to start the LNS (or nullptr for no LNS).
Definition flatzinc.hh:455
Gecode::BoolVarArray bv_aux
The introduced Boolean variables.
Definition flatzinc.hh:561
IntSharedArray arg2intsharedarray(AST::Node *arg, int offset=0)
Convert arg (array of integers) to IntSharedArray.
BoolVarArgs arg2boolvarargs(AST::Node *arg, int offset=0, int siv=-1)
Convert arg to BoolVarArgs.
void aliasBool2Int(int iv, int bv)
Link integer variable iv to Boolean variable bv.
Definition flatzinc.cpp:922
AST::Array * solveAnnotations(void) const
Return the solve item annotations.
Gecode::IntVarArray iv_aux
The introduced integer variables.
Definition flatzinc.hh:484
Gecode::IntVarArray iv
The integer variables.
Definition flatzinc.hh:482
virtual Gecode::Space * copy(void)
Copy function.
void init(int intVars, int boolVars, int setVars, int floatVars)
Initialize space with given number of variables.
Definition flatzinc.cpp:879
Gecode::BoolVarArray on_restart_bv
On Restart Tracked Boolean Variables.
Definition flatzinc.hh:543
bool isBoolArray(AST::Node *b, int &singleInt)
Check if b is array of Booleans (or has a single integer).
IntPropLevel ann2ipl(AST::Node *ann)
Convert ann to integer propagation level.
void newIntVar(IntVarSpec *vs)
Create new integer variable from specification.
Definition flatzinc.cpp:904
Meth _method
Whether to solve as satisfaction or optimization problem.
Definition flatzinc.hh:449
void compare(const Space &s, std::ostream &out) const
Compare this space with space s and print the differences on out.
int intVarCount
Number of integer variables.
Definition flatzinc.hh:435
BoolVar arg2BoolVar(AST::Node *n)
Convert n to BoolVar.
TupleSet arg2tupleset(const IntArgs &a, int noOfVars)
Convert a to TupleSet.
IntSetArgs arg2intsetargs(AST::Node *arg, int offset=0)
Convert arg to IntSetArgs.
FloatValArgs arg2floatargs(AST::Node *arg, int offset=0)
Convert n to FloatValArgs.
bool needAuxVars
Whether the introduced variables still need to be copied.
Definition flatzinc.hh:583
IntArgs arg2intargs(AST::Node *arg, int offset=0)
Convert arg (array of integers) to IntArgs.
std::unique_ptr< Search::Stop > stop_object
FlatZincStop(Search::Stop *stop_object0, const BlackBoxContextHandle &black_box_context0)
BlackBoxContextHandle black_box_context
bool stop(const Search::Statistics &s, const Search::Options &o) override
Stop search, if returns true.
Specification for floating point variables.
Definition varspec.hh:119
Option< std::pair< double, double > > domain
Definition varspec.hh:121
static void explore(S *root, const FlatZincOptions &opt, Gist::Inspector *i, Gist::Comparator *c)
static void explore(S *root, const FlatZincOptions &opt, Gist::Inspector *i, Gist::Comparator *c)
Traits class for search engines.
Which integer or Boolean variable to select for branching.
Definition branch.hh:44
Specification for integer variables.
Definition varspec.hh:72
Option< AST::SetLit * > domain
Definition varspec.hh:74
Output support class for FlatZinc interpreter.
Definition flatzinc.hh:107
void addFloatVarName(const std::string &n)
void printDiff(std::ostream &out, const Gecode::IntVarArray &iv1, const Gecode::IntVarArray &iv2, const Gecode::BoolVarArray &bv1, const Gecode::BoolVarArray &bv2, const Gecode::SetVarArray &sv1, const Gecode::SetVarArray &sv2, const Gecode::FloatVarArray &fv1, const Gecode::FloatVarArray &fv2) const
void addSetVarName(const std::string &n)
void init(AST::Array *output)
void print(std::ostream &out, const Gecode::IntVarArray &iv, const Gecode::BoolVarArray &bv, const Gecode::SetVarArray &sv, const Gecode::FloatVarArray &fv) const
void shrinkArrays(Space &home, int &optVar, bool optVarIsInt, Gecode::IntVarArray &iv, Gecode::BoolVarArray &bv, Gecode::SetVarArray &sv, Gecode::FloatVarArray &fv)
void addIntVarName(const std::string &n)
void addBoolVarName(const std::string &n)
void shrinkElement(AST::Node *node, std::map< int, int > &iv, std::map< int, int > &bv, std::map< int, int > &sv, std::map< int, int > &fv)
void post(FlatZincSpace &s, const ConExpr &ce)
Post constraint specified by ce.
Definition registry.cpp:60
Specification for set variables.
Definition varspec.hh:139
Option< AST::SetLit * > upperBound
Definition varspec.hh:141
int i
Variable index.
Definition varspec.hh:57
bool introduced
Whether the variable was introduced in the mzn2fzn translation.
Definition varspec.hh:63
bool assigned
Whether the variable is assigned.
Definition varspec.hh:61
bool alias
Whether the variable aliases another variable.
Definition varspec.hh:59
bool funcDep
Whether the variable functionally depends on another variable.
Definition varspec.hh:65
Value description class for branching.
Definition float.hh:1469
bool l
Whether to try the lower or upper half first.
Definition float.hh:1474
FloatNum n
The middle value for branching.
Definition float.hh:1472
Passing float arguments.
Definition float.hh:953
Which values to select for branching first.
Definition float.hh:1833
Float value type.
Definition float.hh:334
FloatNum size(void) const
Return size of float value (distance between maximum and minimum).
Definition val.hpp:78
Passing float variables.
Definition float.hh:982
Float variable array.
Definition float.hh:1035
Float variables.
Definition float.hh:870
Float view for float variables.
Definition view.hpp:52
Abstract base class for comparators.
Definition gist.hh:119
virtual void compare(const Space &s0, const Space &s1)=0
Call-back function.
Abstract base class for inspectors.
Definition gist.hh:99
void compare(Comparator *c)
Add comparator.
Definition gist.hpp:182
void click(Inspector *i)
Add inspector that reacts on node double clicks.
Definition gist.hpp:170
Options for Gist
Definition gist.hh:234
class Gecode::Gist::Options::I_ inspect
An window for simple text output.
Definition gist.hh:160
void finalize(void)
Clean up when Gist exits.
Definition gist.cpp:64
TextOutput(const std::string &name)
Constructor.
Definition gist.cpp:60
std::ostream & getStream(void)
Get the stream that is used to output text.
Definition gist.cpp:85
void init(void)
Initialize the implementation object.
Definition gist.cpp:77
A simple comparator.
Definition gist.hh:211
VarComparator(std::string name)
Constructor.
Definition gist.hpp:37
unsigned int id(void) const
Return a unique id for the group.
Definition core.hpp:5150
Home class for posting propagators
Definition core.hpp:863
Passing integer arguments.
Definition int.hh:652
Which values to select for assignment.
Definition int.hh:5317
Integer sets.
Definition int.hh:178
static const IntSet empty
Empty set.
Definition int.hh:301
Which values to select for branching first.
Definition int.hh:5200
Passing integer variables.
Definition int.hh:680
Integer variable array.
Definition int.hh:791
Integer variables.
Definition int.hh:389
Integer view for integer variables.
Definition view.hpp:129
int min(void) const
Return minimum of domain.
Definition int.hpp:58
bool range(void) const
Test whether domain is a range.
Definition int.hpp:103
int val(void) const
Return assigned value (only if assigned).
Definition int.hpp:70
int max(void) const
Return maximum of domain.
Definition int.hpp:62
Range iterator for integer views.
Definition view.hpp:54
Information passed by meta search engines.
Definition core.hpp:1628
@ RESTART
Information is provided by a restart-based engine.
Definition core.hpp:1633
unsigned long long int solution(void) const
Return number of solutions since last restart.
Definition core.hpp:3173
unsigned long int restart(void) const
Return number of restarts.
Definition core.hpp:3164
const Space * last(void) const
Return last solution found (possibly nullptr).
Definition core.hpp:3183
RestartReason reason(void) const
Return reason for restarting.
Definition core.hpp:3169
@ RR_INIT
Restarting after initialisation.
Definition core.hpp:1642
@ RR_SOL
Restarting after a solution is found.
Definition core.hpp:1644
@ RR_CMPL
Restarting after exhausting search space.
Definition core.hpp:1646
@ RR_LIM
Restarting after reaching restart limit.
Definition core.hpp:1648
Type type(void) const
Return type of information.
Definition core.hpp:3160
static PropagatorGroup all
Group of all propagators.
Definition core.hpp:796
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition region.hpp:386
Random number generator.
Definition rnd.hpp:42
Search engine options
Definition search.hh:751
unsigned int c_d
Create a clone after every c_d commits (commit distance).
Definition search.hh:758
unsigned int a_d
Create a clone during recomputation if distance is greater than a_d (adaptive distance).
Definition search.hh:760
Search engine statistics
Definition search.hh:151
unsigned long int restart
Number of restarts.
Definition search.hh:160
unsigned long int depth
Maximum depth of search stack.
Definition search.hh:158
unsigned long long int fail
Number of failed nodes in search tree.
Definition search.hh:154
unsigned long long int node
Number of nodes expanded.
Definition search.hh:156
Base-class for Stop-object.
Definition search.hh:804
Which values to select for branching first.
Definition set.hh:1460
Passing set variables.
Definition set.hh:491
Set variable array
Definition set.hh:575
Which variable to select for branching.
Definition set.hh:1309
Set variables
Definition set.hh:127
Range iterator for the greatest lower bound.
Definition var-imp.hpp:359
Shared array with arbitrary number of elements.
int size(void) const
Return number of elements.
SharedHandle(void)
Create shared handle with no object pointing to.
SharedHandle::Object * object(void) const
Access to the shared object.
Computation spaces.
Definition core.hpp:1775
struct Gecode::Space::@055132133326276162005044145100211202071356247106::@275070317317120154232063063134255170030071110047 p
Data only available during propagation or branching.
struct Gecode::Space::@055132133326276162005044145100211202071356247106::@155123175027073262103111264343315000271204104107 c
Data available only during copying.
friend class Region
Definition core.hpp:1788
T * alloc(long unsigned int n)
Allocate block of n objects of type T from space heap.
Definition core.hpp:2901
friend class BrancherGroup
Definition core.hpp:1781
Statistics for execution of status
Definition core.hpp:1724
unsigned long long int propagate
Number of propagator executions.
Definition core.hpp:1727
double stop(void)
Get time since start of timer.
Definition timer.hpp:63
void start(void)
Start timer.
Definition timer.hpp:58
Combine variable selection criteria for tie-breaking.
Definition tiebreak.hpp:38
Class representing a set of tuples.
Definition int.hh:2382
TupleSet & add(const IntArgs &t)
Add tuple t to tuple set.
std::size_t hash(void) const
Return hash key.
void finalize(void)
Finalize tuple set with dense support data.
bool assigned(void) const
Test if all variables are assigned.
Definition array.hpp:1036
int size(void) const
Return size of array (number of elements).
Definition array.hpp:936
bool assigned(void) const
Test whether view is assigned.
Definition view.hpp:516
Base class for variables.
Definition var.hpp:40
unsigned int seed
The random seed to be used.
Definition test.hh:88
unsigned int threads
Number of threads to use.
Definition test.hh:86
const int * pi[]
Definition photo.cpp:14262
Heap heap
The single global heap.
Definition heap.cpp:44
void fail(void)
Fail space.
Definition core.hpp:4167
@ SM_GIST
Run script in Gist.
Definition driver.hh:98
@ RM_CONSTANT
Restart with constant sequence.
Definition driver.hh:107
@ RM_LINEAR
Restart with linear sequence.
Definition driver.hh:108
@ RM_LUBY
Restart with Luby sequence.
Definition driver.hh:109
@ RM_NONE
No restarts.
Definition driver.hh:106
@ RM_GEOMETRIC
Restart with geometric sequence.
Definition driver.hh:110
int bab(Space *root, const Gist::Options &opt=Gist::Options::def)
Create a new stand-alone Gist for branch-and-bound search of root.
Definition gist.hpp:208
int dfs(Space *root, const Gist::Options &opt=Gist::Options::def)
Create a new stand-alone Gist for root.
Definition gist.hpp:203
void assign(Home home, const FloatVarArgs &x, FloatVarBranch vars, FloatAssign vals, FloatBranchFilter bf=nullptr, FloatVarValPrint vvp=nullptr)
Assign all x with variable selection vars and value selection vals.
Definition branch.cpp:111
void rel(Home home, FloatVar x0, FloatRelType frt, FloatVar x1)
Post propagator for .
Definition rel.cpp:68
double FloatNum
Floating point number base type.
Definition float.hh:106
@ FRT_EQ
Equality ( ).
Definition float.hh:1076
@ FRT_GR
Greater ( ).
Definition float.hh:1081
@ FRT_LE
Less ( ).
Definition float.hh:1079
IntPropLevel
Propagation levels for integer propagators.
Definition int.hh:1008
@ IRT_EQ
Equality ( ).
Definition int.hh:960
@ IRT_LE
Less ( ).
Definition int.hh:963
@ IRT_GR
Greater ( ).
Definition int.hh:965
@ IPL_DOM
Domain propagation Options: basic versus advanced propagation.
Definition int.hh:1013
@ IPL_VAL
Value propagation.
Definition int.hh:1011
@ IPL_DEF
Simple propagation levels.
Definition int.hh:1010
@ IPL_BND
Bounds propagation.
Definition int.hh:1012
Space(void)
Default constructor.
Definition core.cpp:121
@ SRT_EQ
Equality ( ).
Definition set.hh:651
Space * clone(void) const
Clone space.
Definition core.hpp:3312
@ SS_FAILED
Space is failed
Definition core.hpp:1715
void stop(Support::Timer &timer, std::ostream &os)
Get time since start of timer and print user friendly time information.
Definition script.cpp:42
Interpreter for the FlatZinc language.
void printIntVar(std::ostream &os, const std::string name, const Int::IntView &x)
Registry & registry(void)
Return global registry object.
Definition registry.cpp:54
void varValPrintF(const Space &home, const Brancher &b, unsigned int a, FloatVar, int i, const FloatNumBranch &nl, std::ostream &o)
Definition flatzinc.cpp:352
TieBreak< IntVarBranch > ann2ivarsel(AST::Node *ann, Rnd rnd, double decay)
Definition flatzinc.cpp:404
void varValPrint(const Space &home, const Brancher &b, unsigned int a, Var, int i, const int &n, std::ostream &o)
Definition flatzinc.cpp:344
BoolAssign ann2asnbvalsel(AST::Node *ann, Rnd rnd)
Definition flatzinc.cpp:607
TieBreak< BoolVarBranch > ann2bvarsel(AST::Node *ann, Rnd rnd, double decay)
Definition flatzinc.cpp:522
void printFloatVar(std::ostream &os, const std::string name, const Float::FloatView &f)
void printBoolVar(std::ostream &os, const std::string name, const BoolVar &b)
TieBreak< FloatVarBranch > ann2fvarsel(AST::Node *ann, Rnd rnd, double decay)
Definition flatzinc.cpp:693
BoolValBranch ann2bvalsel(AST::Node *ann, std::string &r0, std::string &r1, Rnd rnd)
Definition flatzinc.cpp:556
IntSet vs2is(IntVarSpec *vs)
Definition flatzinc.cpp:360
FloatValBranch ann2fvalsel(AST::Node *ann, std::string r0, std::string r1)
Definition flatzinc.cpp:737
int vs2bsl(BoolVarSpec *bs)
Definition flatzinc.cpp:380
IntValBranch ann2ivalsel(AST::Node *ann, std::string &r0, std::string &r1, Rnd rnd)
Definition flatzinc.cpp:453
IntBoolVarBranch INTBOOL_VAR_AFC_SIZE_MAX(double d=1.0)
Select variable with largest accumulated failure count divided by domain size.
Definition branch.hpp:138
GECODE_FLATZINC_EXPORT Rnd defrnd
Uninitialized default random number generator.
void branch(Home home, const IntVarArgs &x, const BoolVarArgs &y, IntBoolVarBranch vars, IntValBranch vals)
Branch function for integer and Boolean variables.
Definition branch.cpp:120
SetVarBranch ann2svarsel(AST::Node *ann, Rnd rnd, double decay)
Definition flatzinc.cpp:625
SetValBranch ann2svalsel(AST::Node *ann, std::string r0, std::string r1, Rnd rnd)
Definition flatzinc.cpp:663
int vs2bsh(BoolVarSpec *bs)
Definition flatzinc.cpp:392
IntAssign ann2asnivalsel(AST::Node *ann, Rnd rnd)
Definition flatzinc.cpp:504
void flattenAnnotations(AST::Array *ann, std::vector< AST::Node * > &out)
const FloatNum max
Largest allowed float value.
Definition float.hh:844
const FloatNum min
Smallest allowed float value.
Definition float.hh:846
The Gecode Interactive Search Tool.
const int min
Smallest allowed integer value.
Definition int.hh:122
const int max
Largest allowed integer value.
Definition int.hh:120
const int min
Smallest allowed integer in integer set.
Definition set.hh:99
const int max
Largest allowed integer in integer set.
Definition set.hh:97
void print(std::basic_ostream< Char, Traits > &s, bool assigned, IL &lb, IU &ub, unsigned int cardMin, unsigned int cardMax)
Print set view.
Definition print.hpp:63
Gecode toplevel namespace
FloatVarBranch FLOAT_VAR_RND(Rnd r)
Select random variable (uniform distribution, for tie breaking).
Definition var.hpp:112
FloatValBranch FLOAT_VAL_SPLIT_MAX(void)
Select values greater than mean of smallest and largest value.
Definition val.hpp:60
ArgArray< IntSet > IntSetArgs
Passing set arguments.
Definition int.hh:643
SetVarBranch SET_VAR_ACTION_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest action divided by domain size with decay factor d.
Definition var.hpp:246
IntAssign INT_ASSIGN_RND(Rnd r)
Select random value.
Definition assign.hpp:70
SetVarBranch SET_VAR_ACTION_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest action divided by domain size with decay factor d.
Definition var.hpp:256
IntValBranch INT_VAL_SPLIT_MIN(void)
Select values not greater than mean of smallest and largest value.
Definition val.hpp:75
FloatVarBranch FLOAT_VAR_AFC_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest accumulated failure count with decay factor d.
Definition var.hpp:127
BoolAssign BOOL_ASSIGN_MAX(void)
Select largest value.
Definition assign.hpp:105
FloatVarBranch FLOAT_VAR_SIZE_MAX(BranchTbl tbl=nullptr)
Select variable with largest domain size.
Definition var.hpp:212
IntVarBranch INT_VAR_AFC_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest accumulated failure count divided by domain size with decay factor d.
Definition var.hpp:236
FloatVarBranch FLOAT_VAR_MAX_MAX(BranchTbl tbl=nullptr)
Select variable with largest max.
Definition var.hpp:202
SetVarBranch SET_VAR_NONE(void)
Select first unassigned variable.
Definition var.hpp:96
IntVarBranch INT_VAR_DEGREE_MAX(BranchTbl tbl=nullptr)
Select variable with largest degree.
Definition var.hpp:121
IntVarBranch INT_VAR_ACTION_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with highest action with decay factor d.
Definition var.hpp:156
FloatVarBranch FLOAT_VAR_AFC_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smalllest accumulated failure count divided by domain size with decay factor d.
Definition var.hpp:227
SharedArray< int > IntSharedArray
Arrays of integers that can be shared among several element constraints.
Definition int.hh:1512
IntValBranch INT_VAL_MED(void)
Select greatest value not greater than the median.
Definition val.hpp:60
IntVarBranch INT_VAR_REGRET_MIN_MAX(BranchTbl tbl=nullptr)
Select variable with largest min-regret.
Definition var.hpp:291
IntVarBranch INT_VAR_ACTION_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest action divided by domain size with decay factor d.
Definition var.hpp:256
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
BoolValBranch BOOL_VAL_MIN(void)
Select smallest value.
Definition val.hpp:130
IntVarBranch INT_VAR_NONE(void)
Select first unassigned variable.
Definition var.hpp:96
void dom(Home home, FloatVar x, FloatVal n)
Propagates .
Definition dom.cpp:40
BoolVarBranch BOOL_VAR_NONE(void)
Select first unassigned variable.
Definition var.hpp:364
IntVarBranch INT_VAR_AFC_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest accumulated failure count with decay factor d.
Definition var.hpp:136
IntVarBranch INT_VAR_AFC_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest accumulated failure count with decay factor d.
Definition var.hpp:126
IntValBranch INT_VALUES_MIN(void)
Try all values starting from smallest.
Definition val.hpp:100
SetVarBranch SET_VAR_SIZE_MIN(BranchTbl tbl=nullptr)
Select variable with smallest unknown set.
Definition var.hpp:206
SetVarBranch SET_VAR_RND(Rnd r)
Select random variable (uniform distribution, for tie breaking).
Definition var.hpp:101
void range(Home home, const IntVarArgs &x, SetVar y, SetVar z)
Post constraint .
Definition aliases.hpp:158
void cmb_hash(std::size_t &seed, const T h)
Combine hash value h into seed.
Definition hash.hpp:44
SetVarBranch SET_VAR_MAX_MAX(BranchTbl tbl=nullptr)
Select variable with largest maximum unknown element.
Definition var.hpp:201
IntValBranch INT_VAL_MAX(void)
Select largest value.
Definition val.hpp:65
FloatVarBranch FLOAT_VAR_ACTION_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with highest action with decay factor d.
Definition var.hpp:157
BoolValBranch BOOL_VAL_MAX(void)
Select largest value.
Definition val.hpp:135
BoolVarBranch BOOL_VAR_RND(Rnd r)
Select random variable (uniform distribution, for tie breaking).
Definition var.hpp:369
BoolVarBranch BOOL_VAR_ACTION_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with lowest action with decay factor d.
Definition var.hpp:414
SetVarBranch SET_VAR_AFC_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest accumulated failure count with decay factor d.
Definition var.hpp:136
FloatVarBranch FLOAT_VAR_MIN_MIN(BranchTbl tbl=nullptr)
Select variable with smallest min.
Definition var.hpp:187
SetVarBranch SET_VAR_MIN_MIN(BranchTbl tbl=nullptr)
Select variable with smallest minimum unknown element.
Definition var.hpp:186
FloatVarBranch FLOAT_VAR_ACTION_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with lowest action with decay factor d.
Definition var.hpp:147
SetValBranch SET_VAL_MAX_INC(void)
Include largest element.
Definition val.hpp:75
BoolAssign BOOL_ASSIGN_RND(Rnd r)
Select random value.
Definition assign.hpp:110
IntValBranch INT_VAL_SPLIT_MAX(void)
Select values greater than mean of smallest and largest value.
Definition val.hpp:80
IntValBranch INT_VAL_MIN(void)
Select smallest value.
Definition val.hpp:55
IntAssign INT_ASSIGN_MED(void)
Select greatest value not greater than the median.
Definition assign.hpp:60
SetVarBranch SET_VAR_AFC_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest accumulated failure count with decay factor d.
Definition var.hpp:126
BoolVarBranch BOOL_VAR_AFC_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest accumulated failure count with decay factor d.
Definition var.hpp:394
T * dfs(T *s, const Search::Options &o=Search::Options::def)
Invoke depth-first search engine for subclass T of space s with options o.
Definition dfs.hpp:73
BoolVarBranch BOOL_VAR_AFC_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest accumulated failure count with decay factor d.
Definition var.hpp:404
FloatVarBranch FLOAT_VAR_NONE(void)
Select first unassigned variable.
Definition var.hpp:97
IntVarBranch INT_VAR_MAX_MAX(BranchTbl tbl=nullptr)
Select variable with largest max.
Definition var.hpp:201
IntAssign INT_ASSIGN_MIN(void)
Select smallest value.
Definition assign.hpp:55
IntVarBranch INT_VAR_ACTION_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with lowest action with decay factor d.
Definition var.hpp:146
IntVarBranch INT_VAR_RND(Rnd r)
Select random variable (uniform distribution, for tie breaking).
Definition var.hpp:101
IntVarBranch INT_VAR_AFC_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest accumulated failure count divided by domain size with decay factor d.
Definition var.hpp:226
SetValBranch SET_VAL_MIN_INC(void)
Include smallest element.
Definition val.hpp:55
ExecStatus
Definition core.hpp:479
@ ES_OK
Execution is okay.
Definition core.hpp:483
@ ES_FAILED
Execution has resulted in failure.
Definition core.hpp:481
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
FloatVarBranch FLOAT_VAR_DEGREE_MAX(BranchTbl tbl=nullptr)
Select variable with largest degree.
Definition var.hpp:122
SetVarBranch SET_VAR_AFC_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest accumulated failure count divided by domain size with decay factor d.
Definition var.hpp:226
SetValBranch SET_VAL_MAX_EXC(void)
Exclude largest element.
Definition val.hpp:80
FloatVarBranch FLOAT_VAR_ACTION_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest action divided by domain size with decay factor d.
Definition var.hpp:257
BoolValBranch BOOL_VAL_RND(Rnd r)
Select random value.
Definition val.hpp:140
SetVarBranch SET_VAR_AFC_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest accumulated failure count divided by domain size with decay factor d.
Definition var.hpp:236
SetVarBranch SET_VAR_ACTION_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with lowest action with decay factor d.
Definition var.hpp:146
IntVarBranch INT_VAR_SIZE_MIN(BranchTbl tbl=nullptr)
Select variable with smallest domain size.
Definition var.hpp:206
BoolVarBranch BOOL_VAR_DEGREE_MAX(BranchTbl tbl=nullptr)
Select variable with largest degree.
Definition var.hpp:389
FloatVarBranch FLOAT_VAR_AFC_SIZE_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest accumulated failure count divided by domain size with decay factor d.
Definition var.hpp:237
IntVarBranch INT_VAR_ACTION_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest action divided by domain size with decay factor d.
Definition var.hpp:246
BoolVarBranch BOOL_VAR_ACTION_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with highest action with decay factor d.
Definition var.hpp:424
BoolAssign BOOL_ASSIGN_MIN(void)
Select smallest value.
Definition assign.hpp:100
FloatValBranch FLOAT_VAL_SPLIT_MIN(void)
Select values not greater than mean of smallest and largest value.
Definition val.hpp:55
IntAssign INT_ASSIGN_MAX(void)
Select largest value.
Definition assign.hpp:65
FloatVarBranch FLOAT_VAR_SIZE_MIN(BranchTbl tbl=nullptr)
Select variable with smallest domain size.
Definition var.hpp:207
IntVarBranch INT_VAR_MIN_MIN(BranchTbl tbl=nullptr)
Select variable with smallest min.
Definition var.hpp:186
FloatVarBranch FLOAT_VAR_AFC_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with largest accumulated failure count with decay factor d.
Definition var.hpp:137
SetValBranch SET_VAL_MIN_EXC(void)
Exclude smallest element.
Definition val.hpp:60
IntVarBranch INT_VAR_SIZE_MAX(BranchTbl tbl=nullptr)
Select variable with largest domain size.
Definition var.hpp:211
SetVarBranch SET_VAR_SIZE_MAX(BranchTbl tbl=nullptr)
Select variable with largest unknown set.
Definition var.hpp:211
IntValBranch INT_VAL_RND(Rnd r)
Select random value.
Definition val.hpp:70
SetVarBranch SET_VAR_ACTION_MAX(double d=1.0, BranchTbl tbl=nullptr)
Select variable with highest action with decay factor d.
Definition var.hpp:156
FloatVarBranch FLOAT_VAR_ACTION_SIZE_MIN(double d=1.0, BranchTbl tbl=nullptr)
Select variable with smallest action divided by domain size with decay factor d.
Definition var.hpp:247
const Gecode::FloatNum step
Gecode::IntArgs i({1, 2, 3, 4})
Options opt
The options.
Definition test.cpp:95
const Val & some(void) const
Definition option.hh:47
size_t operator()(const Gecode::DFA &d) const
Return hash key for d.
Definition flatzinc.cpp:82
size_t operator()(const Gecode::SharedArray< int > &x) const
Return hash key for x.
Definition flatzinc.cpp:71
size_t operator()(const Gecode::TupleSet &x) const
Return hash key for x.
Definition flatzinc.cpp:62
#define GECODE_HAS_FLOAT_VARS
Definition config.hpp:72
#define GECODE_HAS_SET_VARS
Definition config.hpp:102
#define forceinline
Definition config.hpp:141