Generated on for Gecode by doxygen 1.17.0
core.hpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.dev>
5 * Guido Tack <tack@gecode.dev>
6 * Mikael Zayenz Lagerkvist <lagerkvist@gecode.dev>
7 *
8 * Contributing authors:
9 * Filip Konvicka <filip.konvicka@logis.cz>
10 * Kris Coester <kris.coester@sap.com>
11 * Alexander Shepil <alexander.shepil@sap.com>
12 * Samuel Gagnon <samuel.gagnon92@gmail.com>
13 *
14 * Copyright:
15 * Christian Schulte, 2002
16 * Guido Tack, 2003
17 * Mikael Zayenz Lagerkvist, 2006, 2026
18 * Kris Coester, 2024
19 * Alexander Shepil, 2024
20 * LOGIS, s.r.o., 2009
21 * Samuel Gagnon, 2018
22 *
23 * Bugfixes provided by:
24 * Alexander Samoilov <alexander_samoilov@yahoo.com>
25 *
26 * This file is part of Gecode, the generic constraint
27 * development environment:
28 * http://www.gecode.dev
29 *
30 * Permission is hereby granted, free of charge, to any person obtaining
31 * a copy of this software and associated documentation files (the
32 * "Software"), to deal in the Software without restriction, including
33 * without limitation the rights to use, copy, modify, merge, publish,
34 * distribute, sublicense, and/or sell copies of the Software, and to
35 * permit persons to whom the Software is furnished to do so, subject to
36 * the following conditions:
37 *
38 * The above copyright notice and this permission notice shall be
39 * included in all copies or substantial portions of the Software.
40 *
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
42 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
44 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
45 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
46 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
47 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 *
49 */
50
51#include <atomic>
52#include <iostream>
53
54namespace Gecode {
55
56 class Space;
57
66
67 typedef int ModEvent;
68
75
77 typedef int PropCond;
83
94 typedef int ModEventDelta;
95
96}
97
99
100namespace Gecode {
101
104 public:
106 static const int idx_c = -1;
108 static const int idx_d = -1;
112 static const int free_bits = 0;
114 static const int med_fst = 0;
116 static const int med_lst = 0;
118 static const int med_mask = 0;
122 static bool med_update(ModEventDelta& med, ModEvent me);
123 };
124
125 forceinline ModEvent
129 forceinline bool
133
134
135 /*
136 * These are the classes of interest
137 *
138 */
139 class ActorLink;
140 class Actor;
141 class Propagator;
143 class LocalObject;
144 class Advisor;
145 class AFC;
146 class Choice;
147 class Brancher;
148 class Group;
149 class PropagatorGroup;
150 class BrancherGroup;
151 class PostInfo;
152 class ViewTraceInfo;
153 class PropagateTraceInfo;
154 class CommitTraceInfo;
155 class PostTraceInfo;
156 class TraceRecorder;
157 class TraceFilter;
158 class Tracer;
159
160 template<class A> class Council;
161 template<class A> class Advisors;
162 template<class VIC> class VarImp;
163
164
165 /*
166 * Variable implementations
167 *
168 */
169
177 class VarImpBase {};
178
192
199 template<class VarImp>
201 public:
203 VarImpDisposer(void);
205 virtual void dispose(Space& home, VarImpBase* x);
206 };
207
209 class Delta {
210 template<class VIC> friend class VarImp;
211 private:
213 ModEvent me;
214 };
215
223 template<class VIC>
224 class VarImp : public VarImpBase {
225 friend class Space;
226 friend class Propagator;
227 template<class VarImp> friend class VarImpDisposer;
229 private:
230 union {
248 } b;
249
251 static const int idx_c = VIC::idx_c;
253 static const int idx_d = VIC::idx_d;
255 static const int free_bits = VIC::free_bits;
257 unsigned int entries;
259 unsigned int free_and_bits;
261 static const Gecode::PropCond pc_max = VIC::pc_max;
262#ifdef GECODE_HAS_CBS
264 const unsigned var_id;
265#endif
266
267 union {
278 unsigned int idx[pc_max+1];
281 } u;
282
284 ActorLink** actor(PropCond pc);
286 ActorLink** actorNonZero(PropCond pc);
288 unsigned int& idx(PropCond pc);
290 unsigned int idx(PropCond pc) const;
291
298 void update(VarImp* x, ActorLink**& sub);
305 static void update(Space& home, ActorLink**& sub);
307 static void recover(Space& home, ActorLink**& sub);
308
310 void enter(Space& home, Propagator* p, PropCond pc);
312 void enter(Space& home, ActorLink* a);
314 void resize(Space& home);
316 void remove(Space& home, Propagator* p, PropCond pc);
318 void remove(Space& home, ActorLink* a);
319
320
321 protected:
323 void cancel(Space& home);
329 bool advise(Space& home, ModEvent me, Delta& d);
330 private:
332 void _fail(Space& home);
333 protected:
336#ifdef GECODE_HAS_VAR_DISPOSE
338 static VarImp<VIC>* vars_d(Space& home);
340 static void vars_d(Space& home, VarImp<VIC>* x);
341#endif
342
343 public:
345 VarImp(Space& home);
347 VarImp(void);
348
349#ifdef GECODE_HAS_CBS
351 unsigned int id(void) const;
352#endif
353
355
356
368 void subscribe(Space& home, Propagator& p, PropCond pc,
369 bool assigned, ModEvent me, bool schedule);
371 void cancel(Space& home, Propagator& p, PropCond pc);
380 void subscribe(Space& home, Advisor& a, bool assigned, bool fail);
382 void cancel(Space& home, Advisor& a, bool fail);
383
390 unsigned int degree(void) const;
397 double afc(void) const;
399
401
402
403 VarImp(Space& home, VarImp& x);
405 bool copied(void) const;
407 VarImp* forward(void) const;
409 VarImp* next(void) const;
411
413
414
421 static void schedule(Space& home, Propagator& p, ModEvent me,
422 bool force = false);
430 static void reschedule(Space& home, Propagator& p, PropCond pc,
431 bool assigned, ModEvent me);
433 static ModEvent me(const ModEventDelta& med);
439
441
442
443 static ModEvent modevent(const Delta& d);
445
447
448
449 unsigned int bits(void) const;
451 unsigned int& bits(void);
453
454 protected:
456 void schedule(Space& home, PropCond pc1, PropCond pc2, ModEvent me);
457
458 public:
460
461
462 static void* operator new(size_t,Space&);
464 static void operator delete(void*,Space&);
466 static void operator delete(void*);
468 };
469
470
488
493 class PropCost {
494 friend class Space;
495 public:
515
517 public:
519 enum Mod {
522 };
523 private:
525 static PropCost cost(Mod m, ActualCost lo, ActualCost hi, unsigned int n);
528 public:
530 static PropCost record(void);
532 static PropCost crazy(PropCost::Mod m, unsigned int n);
534 static PropCost crazy(PropCost::Mod m, int n);
536 static PropCost cubic(PropCost::Mod m, unsigned int n);
538 static PropCost cubic(PropCost::Mod m, int n);
540 static PropCost quadratic(PropCost::Mod m, unsigned int n);
542 static PropCost quadratic(PropCost::Mod m, int n);
544 static PropCost linear(PropCost::Mod m, unsigned int n);
546 static PropCost linear(PropCost::Mod m, int n);
550 static PropCost binary(PropCost::Mod m);
552 static PropCost unary(PropCost::Mod m);
553 };
554
555
569 AP_DISPOSE = (1 << 0),
575 AP_WEAKLY = (1 << 1),
580 AP_VIEW_TRACE = (1 << 2),
585 AP_TRACE = (1 << 3)
586 };
587
588
596 class ActorLink {
597 friend class Actor;
598 friend class Propagator;
599 friend class Advisor;
600 friend class Brancher;
601 friend class LocalObject;
602 friend class Space;
603 template<class VIC> friend class VarImp;
604 private:
605 ActorLink* _next; ActorLink* _prev;
606 public:
608
609 ActorLink* prev(void) const; void prev(ActorLink*);
610 ActorLink* next(void) const; void next(ActorLink*);
611 ActorLink** next_ref(void);
613
615 void init(void);
617 void unlink(void);
619 void head(ActorLink* al);
621 void tail(ActorLink* al);
623 bool empty(void) const;
625 template<class T> static ActorLink* cast(T* a);
627 template<class T> static const ActorLink* cast(const T* a);
628 };
629
630
636 friend class ActorLink;
637 friend class Space;
638 friend class Propagator;
639 friend class Advisor;
640 friend class Brancher;
641 friend class LocalObject;
642 template<class VIC> friend class VarImp;
643 template<class A> friend class Council;
644 private:
646 static Actor* cast(ActorLink* al);
648 static const Actor* cast(const ActorLink* al);
650 GECODE_KERNEL_EXPORT static Actor* sentinel;
651 public:
653 virtual Actor* copy(Space& home) = 0;
654
656
657
659 virtual size_t dispose(Space& home);
661 static void* operator new(size_t s, Space& home);
663 static void operator delete(void* p, Space& home);
665 public:
669 static void* operator new(size_t s);
671 static void operator delete(void* p);
672 };
673
674 class Home;
675
680 class Group {
681 friend class Home;
682 friend class Propagator;
683 friend class Brancher;
684 friend class ViewTraceInfo;
685 friend class PropagateTraceInfo;
686 friend class CommitTraceInfo;
687 friend class PostTraceInfo;
688 protected:
690 static const unsigned int GROUPID_ALL = 0U;
692 static const unsigned int GROUPID_DEF = 1U;
694 static const unsigned int GROUPID_MAX = UINT_MAX >> 2;
696 unsigned int gid;
699 static unsigned int next;
704 Group(unsigned int gid0);
705 public:
707
708
710 Group(void);
712 Group(const Group& g);
714 Group& operator =(const Group& g);
716 unsigned int id(void) const;
718 bool in(Group a) const;
720 bool in(void) const;
722
724 static Group all;
727 static Group def;
728 };
729
734 class PropagatorGroup : public Group {
735 friend class Propagator;
736 friend class ViewTraceInfo;
737 friend class PropagateTraceInfo;
738 friend class PostTraceInfo;
739 protected:
741 PropagatorGroup(unsigned int gid);
742 public:
744
745
746 PropagatorGroup(void);
752 Home operator ()(Space& home);
754
756
768 PropagatorGroup& move(Space& home, unsigned int id);
770
772
773 bool operator ==(PropagatorGroup g) const;
775 bool operator !=(PropagatorGroup g) const;
778 unsigned int size(Space& home) const;
781 void kill(Space& home);
784 void disable(Space& home);
792 void enable(Space& home, bool s=true);
794
800 };
801
806 class BrancherGroup : public Group {
807 friend class Brancher;
808 protected:
810 BrancherGroup(unsigned int gid);
811 public:
813
814
815 BrancherGroup(void);
821 Home operator ()(Space& home);
823
825
829 BrancherGroup& move(Space& home, Brancher& b);
837 BrancherGroup& move(Space& home, unsigned int id);
839
841
842 bool operator ==(BrancherGroup g) const;
844 bool operator !=(BrancherGroup g) const;
847 unsigned int size(Space& home) const;
850 void kill(Space& home);
852
858 };
859
863 class Home {
864 friend class PostInfo;
865 protected:
874 public:
876
877
878 Home(Space& s, Propagator* p=nullptr,
882 Home(const Home& h);
884 Home& operator =(const Home& h);
886 operator Space&(void);
888
890
897 Propagator* propagator(void) const;
901 BrancherGroup branchergroup(void) const;
903
905
906 bool failed(void) const;
908 void fail(void);
910 void notice(Actor& a, ActorProperty p, bool duplicate=false);
912 };
913
918 friend class Space;
919 friend class PostInfo;
920 public:
922 enum What {
928 POST = 2,
931 };
932 protected:
934 ptrdiff_t who;
936 void propagator(Propagator& p);
938 void brancher(Brancher& b);
940 void post(PropagatorGroup g);
942 void other(void);
943 public:
945 What what(void) const;
947 const Propagator& propagator(void) const;
949 const Brancher& brancher(void) const;
951 PropagatorGroup post(void) const;
952 };
953
957 class PostInfo {
958 friend class Space;
959 protected:
965 unsigned int pid;
967 bool nested;
968 public:
970 PostInfo(Home home);
972 ~PostInfo(void);
973 };
974
979 friend class Space;
980 public:
988 protected:
990 unsigned int i;
994 const Propagator* p;
999 const Propagator* p, Status s);
1000 public:
1002 unsigned int id(void) const;
1004 PropagatorGroup group(void) const;
1006 const Propagator* propagator(void) const;
1008 Status status(void) const;
1009 };
1010
1015 friend class Space;
1016 protected:
1018 const Brancher& b;
1020 const Choice& c;
1022 unsigned int a;
1024 CommitTraceInfo(const Brancher& b, const Choice& c, unsigned int a);
1025 public:
1027 unsigned int id(void) const;
1029 BrancherGroup group(void) const;
1031 const Brancher& brancher(void) const;
1033 const Choice& choice(void) const;
1035 unsigned int alternative(void) const;
1036 };
1037
1042 friend class Space;
1043 friend class PostInfo;
1044 public:
1051 protected:
1057 unsigned int n;
1059 PostTraceInfo(PropagatorGroup g, Status s, unsigned int n);
1060 public:
1062 Status status(void) const;
1064 PropagatorGroup group(void) const;
1066 unsigned int propagators(void) const;
1067 };
1068
1074 friend class ActorLink;
1075 friend class Space;
1076 template<class VIC> friend class VarImp;
1077 friend class Advisor;
1078 template<class A> friend class Council;
1080 friend class PropagatorGroup;
1081 private:
1082 union {
1086 size_t size;
1089 } u;
1091 void* gpi_disabled;
1093 static Propagator* cast(ActorLink* al);
1095 static const Propagator* cast(const ActorLink* al);
1097 void disable(Space& home);
1099 void enable(Space& home);
1100 protected:
1102 Propagator(Home home);
1104 Propagator(Space& home, Propagator& p);
1106 Propagator* fwd(void) const;
1108 Kernel::GPI::Info& gpi(void);
1109
1110 public:
1112
1113
1121 virtual void reschedule(Space& home) = 0;
1145 virtual ExecStatus propagate(Space& home, const ModEventDelta& med) = 0;
1147 virtual PropCost cost(const Space& home, const ModEventDelta& med) const = 0;
1155 ModEventDelta modeventdelta(void) const;
1192 virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
1195 virtual void advise(Space& home, Advisor& a);
1197
1199
1200 double afc(void) const;
1202#ifdef GECODE_HAS_CBS
1204
1205
1212 typedef std::function<void(unsigned int prop_id, unsigned int var_id,
1213 int val, double dens)> SendMarginal;
1214 virtual void solndistrib(Space& home, SendMarginal send) const;
1223 typedef std::function<bool(unsigned int var_id)> InDecision;
1224 virtual void domainsizesum(InDecision in, unsigned int& size,
1225 unsigned int& size_b) const;
1227#endif
1229
1230
1231 unsigned int id(void) const;
1233 PropagatorGroup group(void) const;
1235 void group(PropagatorGroup g);
1237 bool disabled(void) const;
1239 };
1240
1241
1249 template<class A>
1250 class Council {
1251 friend class Advisor;
1252 friend class Advisors<A>;
1253 private:
1255 mutable ActorLink* advisors;
1256 public:
1258 Council(void);
1260 Council(Space& home);
1262 bool empty(void) const;
1264 void update(Space& home, Council<A>& c);
1266 void dispose(Space& home);
1267 };
1268
1269
1274 template<class A>
1275 class Advisors {
1276 private:
1278 ActorLink* a;
1279 public:
1281 Advisors(const Council<A>& c);
1283 bool operator ()(void) const;
1285 void operator ++(void);
1287 A& advisor(void) const;
1288 };
1289
1290
1301 class Advisor : private ActorLink {
1302 template<class VIC> friend class VarImp;
1303 template<class A> friend class Council;
1304 template<class A> friend class Advisors;
1306 private:
1308 bool disposed(void) const;
1310 static Advisor* cast(ActorLink* al);
1312 static const Advisor* cast(const ActorLink* al);
1314 static ActorLink* link(Advisor& a);
1315 protected:
1317 Propagator& propagator(void) const;
1318 public:
1320 template<class A>
1321 Advisor(Space& home, Propagator& p, Council<A>& c);
1323 Advisor(Space& home, Advisor& a);
1325 const ViewTraceInfo& operator ()(const Space& home) const;
1326
1328
1329
1330 template<class A>
1331 void dispose(Space& home, Council<A>& c);
1333 static void* operator new(size_t s, Space& home);
1335 static void operator delete(void* p, Space& home);
1337 private:
1338#ifndef __GNUC__
1340 static void operator delete(void* p);
1341#endif
1343 static void* operator new(size_t s);
1344 };
1345
1346
1352 private:
1354 void* nl;
1355 public:
1362
1363 NGL(void);
1365 NGL(Space& home);
1367 NGL(Space& home, NGL& ngl);
1369 virtual void subscribe(Space& home, Propagator& p) = 0;
1371 virtual void cancel(Space& home, Propagator& p) = 0;
1373 virtual void reschedule(Space& home, Propagator& p) = 0;
1375 virtual NGL::Status status(const Space& home) const = 0;
1377 virtual ExecStatus prune(Space& home) = 0;
1379 virtual NGL* copy(Space& home) = 0;
1382 virtual bool notice(void) const;
1384 virtual size_t dispose(Space& home);
1386
1387
1388 bool leaf(void) const;
1390 NGL* next(void) const;
1392 void leaf(bool l);
1394 void next(NGL* n);
1396 NGL* add(NGL* n, bool l);
1398
1400
1401 static void* operator new(size_t s, Space& home);
1403 static void operator delete(void* s, Space& home);
1405 static void operator delete(void* p);
1407 public:
1411 static void* operator new(size_t s);
1412 };
1413
1424 friend class Space;
1425 private:
1426 unsigned int bid;
1427 unsigned int alt;
1428
1430 unsigned int id(void) const;
1431 protected:
1433 Choice(const Brancher& b, const unsigned int a);
1434 public:
1436 unsigned int alternatives(void) const;
1438 GECODE_KERNEL_EXPORT virtual ~Choice(void);
1441 virtual void archive(Archive& e) const;
1442 };
1443
1454 friend class ActorLink;
1455 friend class Space;
1456 friend class Choice;
1457 private:
1459 unsigned int bid;
1461 unsigned int gid;
1463 static Brancher* cast(ActorLink* al);
1465 static const Brancher* cast(const ActorLink* al);
1466 protected:
1468 Brancher(Home home);
1470 Brancher(Space& home, Brancher& b);
1471 public:
1473
1474
1482 virtual bool status(const Space& home) const = 0;
1490 virtual const Choice* choice(Space& home) = 0;
1492 virtual const Choice* choice(const Space& home, Archive& e) = 0;
1499 virtual ExecStatus commit(Space& home, const Choice& c,
1500 unsigned int a) = 0;
1515 virtual NGL* ngl(Space& home, const Choice& c, unsigned int a) const;
1524 virtual void print(const Space& home, const Choice& c, unsigned int a,
1525 std::ostream& o) const;
1527
1529
1530 unsigned int id(void) const;
1532 BrancherGroup group(void) const;
1534 void group(BrancherGroup g);
1536 };
1537
1544 class LocalObject : public Actor {
1545 friend class ActorLink;
1546 friend class Space;
1547 friend class LocalHandle;
1548 protected:
1550 LocalObject(Home home);
1552 LocalObject(Space& home, LocalObject& l);
1554 static LocalObject* cast(ActorLink* al);
1556 static const LocalObject* cast(const ActorLink* al);
1557 private:
1559 GECODE_KERNEL_EXPORT void fwdcopy(Space& home);
1560 public:
1562 LocalObject* fwd(Space& home);
1563 };
1564
1570 private:
1572 LocalObject* o;
1573 protected:
1575 LocalHandle(void);
1579 LocalHandle(const LocalHandle& lh);
1580 public:
1584 void update(Space& home, LocalHandle& lh);
1586 ~LocalHandle(void);
1587 protected:
1589 LocalObject* object(void) const;
1591 void object(LocalObject* n);
1592 };
1593
1594
1600 protected:
1602 std::atomic<unsigned long int> n;
1603 public:
1605 NoGoods(void);
1607 NoGoods(const NoGoods& ng);
1609 NoGoods& operator =(const NoGoods& ng);
1612 virtual void post(Space& home) const;
1614 unsigned long int ng(void) const;
1616 void ng(unsigned long int n);
1618 virtual ~NoGoods(void);
1621 static NoGoods eng;
1622 };
1623
1629 public:
1637
1650 protected:
1652 const Type t;
1654
1655
1656 const unsigned long int r;
1660 const unsigned long long int s;
1662 const unsigned long long int f;
1664 const Space* l;
1666 const NoGoods& ng;
1668
1670
1671 const unsigned int a;
1673 public:
1675
1676
1677 MetaInfo(unsigned long int r,
1679 unsigned long long int s,
1680 unsigned long long int f,
1681 const Space* l,
1682 NoGoods& ng);
1684 MetaInfo(unsigned int a);
1686
1687 Type type(void) const;
1689
1690
1691 unsigned long int restart(void) const;
1693 RestartReason reason(void) const;
1695 unsigned long long int solution(void) const;
1697 unsigned long long int fail(void) const;
1699 const Space* last(void) const;
1701 const NoGoods& nogoods(void) const;
1703
1705
1706 unsigned int asset(void) const;
1708 };
1709
1719
1725 public:
1727 unsigned long long int propagate;
1729 StatusStatistics(void);
1731 void reset(void);
1736 };
1737
1743 public:
1745 CloneStatistics(void);
1747 void reset(void);
1752 };
1753
1759 public:
1761 CommitStatistics(void);
1763 void reset(void);
1768 };
1769
1770
1771
1776 friend class Actor;
1777 friend class Propagator;
1778 friend class PropagatorGroup;
1779 friend class Propagators;
1780 friend class Brancher;
1781 friend class BrancherGroup;
1782 friend class Branchers;
1783 friend class Advisor;
1784 template <class A> friend class Council;
1785 template<class VIC> friend class VarImp;
1786 template<class VarImp> friend class VarImpDisposer;
1787 friend class LocalObject;
1788 friend class Region;
1789 friend class AFC;
1790 friend class PostInfo;
1792 void trace(Home home, TraceFilter tf, int te, Tracer& t);
1793 private:
1798#ifdef GECODE_HAS_CBS
1800 unsigned int var_id_counter;
1801#endif
1803 ActorLink pl;
1805 ActorLink bl;
1811 Brancher* b_status;
1823 Brancher* b_commit;
1825 Brancher* brancher(unsigned int id);
1826
1828 void kill(Brancher& b);
1830 void kill(Propagator& p);
1831
1834 void kill_brancher(unsigned int id);
1835
1837 static const unsigned reserved_bid = 0U;
1838
1840 static const unsigned int sc_bits = 2;
1842 static const unsigned int sc_fast = 0;
1844 static const unsigned int sc_disabled = 1;
1846 static const unsigned int sc_trace = 2;
1847
1848 union {
1850 struct {
1872 unsigned int bid_sc;
1874 unsigned int n_sub;
1877 } p;
1879 struct {
1888 } c;
1889 } pc;
1891 void enqueue(Propagator* p);
1896#ifdef GECODE_HAS_VAR_DISPOSE
1898 GECODE_KERNEL_EXPORT static VarImpDisposerBase* vd[AllVarConf::idx_d];
1900 VarImpBase* _vars_d[AllVarConf::idx_d];
1902 template<class VIC> VarImpBase* vars_d(void) const;
1904 template<class VIC> void vars_d(VarImpBase* x);
1905#endif
1907 void update(ActorLink** sub);
1909
1911 void recover_noidx(void);
1912
1914 void recover(Space& source);
1915
1917 bool is_partial_clone(void) const;
1918
1920 Actor** d_fst;
1922 Actor** d_cur;
1924 Actor** d_lst;
1925
1927 GECODE_KERNEL_EXPORT static StatusStatistics unused_status;
1929 GECODE_KERNEL_EXPORT static CloneStatistics unused_clone;
1931 GECODE_KERNEL_EXPORT static CommitStatistics unused_commit;
1932
1946 GECODE_KERNEL_EXPORT Space* _clone(void);
1947
1981 void _commit(const Choice& c, unsigned int a);
1982
2014 void _trycommit(const Choice& c, unsigned int a);
2015
2018 TraceRecorder* findtracerecorder(void);
2021 void post(const PostInfo& pi);
2022
2030 void ap_notice_dispose(Actor* a, bool d);
2038 void ap_ignore_dispose(Actor* a, bool d);
2039 public:
2045 Space(void);
2060 Space& operator =(const Space& s) = default;
2066 virtual ~Space(void);
2077 virtual Space* copy(void) = 0;
2088 GECODE_KERNEL_EXPORT virtual void constrain(const Space& best);
2113 virtual bool master(const MetaInfo& mi);
2140 virtual bool slave(const MetaInfo& mi);
2141
2142 /*
2143 * Member functions for search engines
2144 *
2145 */
2146
2161 SpaceStatus status(void);
2162
2195 const Choice* choice(void);
2196
2207 const Choice* choice(Archive& e) const;
2208
2225 Space* clone(void) const;
2227 Space* clone(CloneStatistics& stat) const;
2228
2264 void commit(const Choice& c, unsigned int a);
2266 void commit(const Choice& c, unsigned int a,
2267 CommitStatistics& stat);
2301 void trycommit(const Choice& c, unsigned int a);
2303 void trycommit(const Choice& c, unsigned int a,
2304 CommitStatistics& stat);
2324 NGL* ngl(const Choice& c, unsigned int a);
2325
2341 void print(const Choice& c, unsigned int a, std::ostream& o) const;
2342
2352 void notice(Actor& a, ActorProperty p, bool duplicate=false);
2361 void ignore(Actor& a, ActorProperty p, bool duplicate=false);
2362
2363
2412
2423 template<class A>
2435 template<class A>
2448 template<class A>
2450
2458 void fail(void);
2467 bool failed(void) const;
2472 bool stable(void) const;
2473
2475
2476
2477 Home operator ()(Propagator& p);
2479 Home operator ()(PropagatorGroup pg);
2481 Home operator ()(BrancherGroup bg);
2483
2489
2495 template<class T>
2496 T* alloc(long unsigned int n);
2503 template<class T>
2504 T* alloc(long int n);
2511 template<class T>
2512 T* alloc(unsigned int n);
2519 template<class T>
2520 T* alloc(int n);
2530 template<class T>
2531 void free(T* b, long unsigned int n);
2541 template<class T>
2542 void free(T* b, long int n);
2552 template<class T>
2553 void free(T* b, unsigned int n);
2563 template<class T>
2564 void free(T* b, int n);
2576 template<class T>
2577 T* realloc(T* b, long unsigned int n, long unsigned int m);
2589 template<class T>
2590 T* realloc(T* b, long int n, long int m);
2602 template<class T>
2603 T* realloc(T* b, unsigned int n, unsigned int m);
2615 template<class T>
2616 T* realloc(T* b, int n, int m);
2624 template<class T>
2625 T** realloc(T** b, long unsigned int n, long unsigned int m);
2633 template<class T>
2634 T** realloc(T** b, long int n, long int m);
2642 template<class T>
2643 T** realloc(T** b, unsigned int n, unsigned int m);
2651 template<class T>
2652 T** realloc(T** b, int n, int m);
2654 void* ralloc(size_t s);
2656 void rfree(void* p, size_t s);
2658 void* rrealloc(void* b, size_t n, size_t m);
2660 template<size_t> void* fl_alloc(void);
2666 template<size_t> void fl_dispose(FreeList* f, FreeList* l);
2668
2670
2673 template<class T>
2674 T& construct(void);
2680 template<class T, typename A1>
2681 T& construct(A1 const& a1);
2687 template<class T, typename A1, typename A2>
2688 T& construct(A1 const& a1, A2 const& a2);
2694 template<class T, typename A1, typename A2, typename A3>
2695 T& construct(A1 const& a1, A2 const& a2, A3 const& a3);
2701 template<class T, typename A1, typename A2, typename A3, typename A4>
2702 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4);
2708 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
2709 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5);
2711
2713
2714
2715 void afc_decay(double d);
2717 double afc_decay(void) const;
2721
2722 protected:
2729 private:
2731 Space& home;
2733 ActorLink* q;
2735 ActorLink* c;
2737 ActorLink* e;
2738 public:
2740 Propagators(Space& home);
2742 bool operator ()(void) const;
2744 void operator ++(void);
2746 Propagator& propagator(void) const;
2747 };
2748
2754 private:
2756 Space& home;
2758 ActorLink* q;
2760 ActorLink* c;
2762 ActorLink* e;
2763 public:
2767 bool operator ()(void) const;
2769 void operator ++(void);
2771 Propagator& propagator(void) const;
2772 };
2773
2779 private:
2781 ActorLink* c;
2783 ActorLink* e;
2784 public:
2786 IdlePropagators(Space& home);
2788 bool operator ()(void) const;
2790 void operator ++(void);
2792 Propagator& propagator(void) const;
2793 };
2794
2800 private:
2802 ActorLink* c;
2804 ActorLink* e;
2805 public:
2807 Branchers(Space& home);
2809 bool operator ()(void) const;
2811 void operator ++(void);
2813 Brancher& brancher(void) const;
2814 };
2815 };
2816
2819 private:
2824 public:
2826 Propagators(const Space& home, PropagatorGroup g);
2828 bool operator ()(void) const;
2830 void operator ++(void);
2832 const Propagator& propagator(void) const;
2833 };
2834
2837 private:
2841 BrancherGroup g;
2842 public:
2844 Branchers(const Space& home, BrancherGroup g);
2846 bool operator ()(void) const;
2848 void operator ++(void);
2850 const Brancher& brancher(void) const;
2851 };
2852
2853
2854
2855
2856 /*
2857 * Memory management
2858 *
2859 */
2860
2861 // Space allocation: general space heaps and free lists
2862 forceinline void*
2863 Space::ralloc(size_t s) {
2864 return mm.alloc(ssd.data().sm,s);
2865 }
2866 forceinline void
2867 Space::rfree(void* p, size_t s) {
2868 return mm.reuse(p,s);
2869 }
2870 forceinline void*
2871 Space::rrealloc(void* _b, size_t n, size_t m) {
2872 char* b = static_cast<char*>(_b);
2873 if (n < m) {
2874 char* p = static_cast<char*>(ralloc(m));
2875 memcpy(p,b,n);
2876 rfree(b,n);
2877 return p;
2878 } else {
2879 rfree(b+m,m-n);
2880 return b;
2881 }
2882 }
2883
2884 template<size_t s>
2885 forceinline void*
2887 return mm.template fl_alloc<s>(ssd.data().sm);
2888 }
2889 template<size_t s>
2890 forceinline void
2892 mm.template fl_dispose<s>(f,l);
2893 }
2894
2895 /*
2896 * Typed allocation routines
2897 *
2898 */
2899 template<class T>
2900 forceinline T*
2901 Space::alloc(long unsigned int n) {
2902 T* p = static_cast<T*>(ralloc(sizeof(T)*n));
2903 for (long unsigned int i=0; i<n; i++)
2904 (void) new (p+i) T();
2905 return p;
2906 }
2907 template<class T>
2908 forceinline T*
2909 Space::alloc(long int n) {
2910 assert(n >= 0);
2911 return alloc<T>(static_cast<long unsigned int>(n));
2912 }
2913 template<class T>
2914 forceinline T*
2915 Space::alloc(unsigned int n) {
2916 return alloc<T>(static_cast<long unsigned int>(n));
2917 }
2918 template<class T>
2919 forceinline T*
2921 assert(n >= 0);
2922 return alloc<T>(static_cast<long unsigned int>(n));
2923 }
2924
2925 template<class T>
2926 forceinline void
2927 Space::free(T* b, long unsigned int n) {
2928 for (long unsigned int i=0; i<n; i++)
2929 b[i].~T();
2930 rfree(b,n*sizeof(T));
2931 }
2932 template<class T>
2933 forceinline void
2934 Space::free(T* b, long int n) {
2935 assert(n >= 0);
2936 free<T>(b,static_cast<long unsigned int>(n));
2937 }
2938 template<class T>
2939 forceinline void
2940 Space::free(T* b, unsigned int n) {
2941 free<T>(b,static_cast<long unsigned int>(n));
2942 }
2943 template<class T>
2944 forceinline void
2945 Space::free(T* b, int n) {
2946 assert(n >= 0);
2947 free<T>(b,static_cast<long unsigned int>(n));
2948 }
2949
2950 template<class T>
2951 forceinline T*
2952 Space::realloc(T* b, long unsigned int n, long unsigned int m) {
2953 if (n < m) {
2954 T* p = static_cast<T*>(ralloc(sizeof(T)*m));
2955 for (long unsigned int i=0; i<n; i++)
2956 (void) new (p+i) T(b[i]);
2957 for (long unsigned int i=n; i<m; i++)
2958 (void) new (p+i) T();
2959 free<T>(b,n);
2960 return p;
2961 } else {
2962 free<T>(b+m,m-n);
2963 return b;
2964 }
2965 }
2966 template<class T>
2967 forceinline T*
2968 Space::realloc(T* b, long int n, long int m) {
2969 assert((n >= 0) && (m >= 0));
2970 return realloc<T>(b,static_cast<long unsigned int>(n),
2971 static_cast<long unsigned int>(m));
2972 }
2973 template<class T>
2974 forceinline T*
2975 Space::realloc(T* b, unsigned int n, unsigned int m) {
2976 return realloc<T>(b,static_cast<long unsigned int>(n),
2977 static_cast<long unsigned int>(m));
2978 }
2979 template<class T>
2980 forceinline T*
2981 Space::realloc(T* b, int n, int m) {
2982 assert((n >= 0) && (m >= 0));
2983 return realloc<T>(b,static_cast<long unsigned int>(n),
2984 static_cast<long unsigned int>(m));
2985 }
2986
2987#define GECODE_KERNEL_REALLOC(T) \
2988 template<> \
2989 forceinline T* \
2990 Space::realloc<T>(T* b, long unsigned int n, long unsigned int m) { \
2991 return static_cast<T*>(rrealloc(b,n*sizeof(T),m*sizeof(T))); \
2992 } \
2993 template<> \
2994 forceinline T* \
2995 Space::realloc<T>(T* b, long int n, long int m) { \
2996 assert((n >= 0) && (m >= 0)); \
2997 return realloc<T>(b,static_cast<long unsigned int>(n), \
2998 static_cast<long unsigned int>(m)); \
2999 } \
3000 template<> \
3001 forceinline T* \
3002 Space::realloc<T>(T* b, unsigned int n, unsigned int m) { \
3003 return realloc<T>(b,static_cast<long unsigned int>(n), \
3004 static_cast<long unsigned int>(m)); \
3005 } \
3006 template<> \
3007 forceinline T* \
3008 Space::realloc<T>(T* b, int n, int m) { \
3009 assert((n >= 0) && (m >= 0)); \
3010 return realloc<T>(b,static_cast<long unsigned int>(n), \
3011 static_cast<long unsigned int>(m)); \
3012 }
3013
3015 GECODE_KERNEL_REALLOC(signed char)
3016 GECODE_KERNEL_REALLOC(unsigned char)
3017 GECODE_KERNEL_REALLOC(signed short int)
3018 GECODE_KERNEL_REALLOC(unsigned short int)
3019 GECODE_KERNEL_REALLOC(signed int)
3020 GECODE_KERNEL_REALLOC(unsigned int)
3021 GECODE_KERNEL_REALLOC(signed long int)
3022 GECODE_KERNEL_REALLOC(unsigned long int)
3024 GECODE_KERNEL_REALLOC(double)
3025
3026#undef GECODE_KERNEL_REALLOC
3027
3028 template<class T>
3029 forceinline T**
3030 Space::realloc(T** b, long unsigned int n, long unsigned int m) {
3031 return static_cast<T**>(rrealloc(b,n*sizeof(T),m*sizeof(T*)));
3032 }
3033 template<class T>
3034 forceinline T**
3035 Space::realloc(T** b, long int n, long int m) {
3036 assert((n >= 0) && (m >= 0));
3037 return realloc<T*>(b,static_cast<long unsigned int>(n),
3038 static_cast<long unsigned int>(m));
3039 }
3040 template<class T>
3041 forceinline T**
3042 Space::realloc(T** b, unsigned int n, unsigned int m) {
3043 return realloc<T*>(b,static_cast<long unsigned int>(n),
3044 static_cast<long unsigned int>(m));
3045 }
3046 template<class T>
3047 forceinline T**
3048 Space::realloc(T** b, int n, int m) {
3049 assert((n >= 0) && (m >= 0));
3050 return realloc<T*>(b,static_cast<long unsigned int>(n),
3051 static_cast<long unsigned int>(m));
3052 }
3053
3054
3055#ifdef GECODE_HAS_VAR_DISPOSE
3056 template<class VIC>
3057 forceinline VarImpBase*
3058 Space::vars_d(void) const {
3059 return _vars_d[VIC::idx_d];
3060 }
3061 template<class VIC>
3062 forceinline void
3063 Space::vars_d(VarImpBase* x) {
3064 _vars_d[VIC::idx_d] = x;
3065 }
3066#endif
3067
3068 forceinline bool
3069 Space::is_partial_clone(void) const {
3070 return d_fst == &Actor::sentinel;
3071 }
3072
3073 // Space allocated entities: Actors, variable implementations, and advisors
3074 forceinline void
3075 Actor::operator delete(void*) {}
3076 forceinline void
3077 Actor::operator delete(void*, Space&) {}
3078 forceinline void*
3079 Actor::operator new(size_t s, Space& home) {
3080 return home.ralloc(s);
3081 }
3082
3083 template<class VIC>
3084 forceinline void
3085 VarImp<VIC>::operator delete(void*) {}
3086 template<class VIC>
3087 forceinline void
3088 VarImp<VIC>::operator delete(void*, Space&) {}
3089 template<class VIC>
3090 forceinline void*
3091 VarImp<VIC>::operator new(size_t s, Space& home) {
3092 return home.ralloc(s);
3093 }
3094
3095#ifndef __GNUC__
3096 forceinline void
3097 Advisor::operator delete(void*) {}
3098#endif
3099 forceinline void
3100 Advisor::operator delete(void*, Space&) {}
3101 forceinline void*
3102 Advisor::operator new(size_t s, Space& home) {
3103 return home.ralloc(s);
3104 }
3105
3106 forceinline void
3107 NGL::operator delete(void*) {}
3108 forceinline void
3109 NGL::operator delete(void*, Space&) {}
3110 forceinline void*
3111 NGL::operator new(size_t s, Space& home) {
3112 return home.ralloc(s);
3113 }
3114
3115
3116 /*
3117 * No-goods
3118 *
3119 */
3120 forceinline
3122 : n(0) {}
3123 forceinline
3125 : n(ng0.ng()) {}
3126 forceinline NoGoods&
3128 ng(ng0.ng());
3129 return *this;
3130 }
3131 forceinline unsigned long int
3132 NoGoods::ng(void) const {
3133 return n.load(std::memory_order_acquire);
3134 }
3135 forceinline void
3136 NoGoods::ng(unsigned long int n0) {
3137 n.store(n0, std::memory_order_release);
3138 }
3139 forceinline
3141
3142
3143 /*
3144 * Information from meta search engines
3145 */
3146 forceinline
3147 MetaInfo::MetaInfo(unsigned long int r0,
3148 RestartReason rr0,
3149 unsigned long long int s0,
3150 unsigned long long int f0,
3151 const Space* l0,
3152 NoGoods& ng0)
3153 : t(RESTART), r(r0), rr(rr0), s(s0), f(f0), l(l0), ng(ng0), a(0) {}
3154
3155 forceinline
3156 MetaInfo::MetaInfo(unsigned int a0)
3157 : t(PORTFOLIO), r(0), rr(RR_NO), s(0), f(0), l(nullptr), ng(NoGoods::eng), a(a0) {}
3158
3159 forceinline MetaInfo::Type
3160 MetaInfo::type(void) const {
3161 return t;
3162 }
3163 forceinline unsigned long int
3164 MetaInfo::restart(void) const {
3165 assert(type() == RESTART);
3166 return r;
3167 }
3168 forceinline MetaInfo::RestartReason
3169 MetaInfo::reason(void) const {
3170 return rr;
3171 }
3172 forceinline unsigned long long int
3174 assert(type() == RESTART);
3175 return s;
3176 }
3177 forceinline unsigned long long int
3178 MetaInfo::fail(void) const {
3179 assert(type() == RESTART);
3180 return f;
3181 }
3182 forceinline const Space*
3183 MetaInfo::last(void) const {
3184 assert(type() == RESTART);
3185 return l;
3186 }
3187 forceinline const NoGoods&
3188 MetaInfo::nogoods(void) const {
3189 assert(type() == RESTART);
3190 return ng;
3191 }
3192 forceinline unsigned int
3193 MetaInfo::asset(void) const {
3194 assert(type() == PORTFOLIO);
3195 return a;
3196 }
3197
3198
3199
3200 /*
3201 * ActorLink
3202 *
3203 */
3204 forceinline ActorLink*
3205 ActorLink::prev(void) const {
3206 return _prev;
3207 }
3208
3209 forceinline ActorLink*
3210 ActorLink::next(void) const {
3211 return _next;
3212 }
3213
3214 forceinline ActorLink**
3216 return &_next;
3217 }
3218
3219 forceinline void
3221 _prev = al;
3222 }
3223
3224 forceinline void
3226 _next = al;
3227 }
3228
3229 forceinline void
3231 ActorLink* p = _prev; ActorLink* n = _next;
3232 p->_next = n; n->_prev = p;
3233 }
3234
3235 forceinline void
3237 _next = this; _prev =this;
3238 }
3239
3240 forceinline void
3242 // Inserts al at head of link-chain (that is, after this)
3243 ActorLink* n = _next;
3244 this->_next = a; a->_prev = this;
3245 a->_next = n; n->_prev = a;
3246 }
3247
3248 forceinline void
3250 // Inserts al at tail of link-chain (that is, before this)
3251 ActorLink* p = _prev;
3252 a->_next = this; this->_prev = a;
3253 p->_next = a; a->_prev = p;
3254 }
3255
3256 forceinline bool
3257 ActorLink::empty(void) const {
3258 return _next == this;
3259 }
3260
3261 template<class T>
3262 forceinline ActorLink*
3264 // Turning al into a reference is for gcc, assume is for MSVC
3265 GECODE_NOT_NULL(a);
3266 ActorLink& t = *a;
3267 return static_cast<ActorLink*>(&t);
3268 }
3269
3270 template<class T>
3271 forceinline const ActorLink*
3272 ActorLink::cast(const T* a) {
3273 // Turning al into a reference is for gcc, assume is for MSVC
3274 GECODE_NOT_NULL(a);
3275 const ActorLink& t = *a;
3276 return static_cast<const ActorLink*>(&t);
3277 }
3278
3279
3280 /*
3281 * Actor
3282 *
3283 */
3284 forceinline Actor*
3285 Actor::cast(ActorLink* al) {
3286 // Turning al into a reference is for gcc, assume is for MSVC
3287 GECODE_NOT_NULL(al);
3288 ActorLink& t = *al;
3289 return static_cast<Actor*>(&t);
3290 }
3291
3292 forceinline const Actor*
3293 Actor::cast(const ActorLink* al) {
3294 // Turning al into a reference is for gcc, assume is for MSVC
3295 GECODE_NOT_NULL(al);
3296 const ActorLink& t = *al;
3297 return static_cast<const Actor*>(&t);
3298 }
3299
3300 forceinline void
3301 Home::notice(Actor& a, ActorProperty p, bool duplicate) {
3302 s.notice(a,p,duplicate);
3303 }
3304
3305 forceinline SpaceStatus
3307 StatusStatistics stat;
3308 return status(stat);
3309 }
3310
3311 forceinline Space*
3312 Space::clone(void) const {
3313 CloneStatistics stat;
3314 return clone(stat);
3315 }
3316
3317 forceinline Space*
3319 // Clone is only const for search engines. During cloning, several data
3320 // structures are updated (e.g. forwarding pointers), so we have to
3321 // cast away the constness.
3322 return const_cast<Space*>(this)->_clone();
3323 }
3324
3325 forceinline void
3326 Space::commit(const Choice& c, unsigned int a) {
3327 CommitStatistics stat;
3328 commit(c,a,stat);
3329 }
3330
3331 forceinline void
3332 Space::commit(const Choice& c, unsigned int a, CommitStatistics&) {
3333 _commit(c,a);
3334 }
3335
3336 forceinline void
3337 Space::trycommit(const Choice& c, unsigned int a) {
3338 CommitStatistics stat;
3339 trycommit(c,a,stat);
3340 }
3341
3342 forceinline void
3343 Space::trycommit(const Choice& c, unsigned int a, CommitStatistics&) {
3344 _trycommit(c,a);
3345 }
3346
3347 forceinline double
3348 Space::afc_decay(void) const {
3349 return ssd.data().gpi.decay();
3350 }
3351
3352 forceinline void
3354 ssd.data().gpi.decay(d);
3355 }
3356
3357 forceinline size_t
3359 return sizeof(*this);
3360 }
3361
3362
3363 /*
3364 * Home for posting actors
3365 *
3366 */
3367 forceinline
3370 : s(s0), p(p0), pg(pg0), bg(bg0) {}
3371 forceinline
3373 : s(h.s), p(h.p), pg(h.pg), bg(h.bg) {}
3374 forceinline Home&
3376 s=h.s; p=h.p; pg=h.pg; bg=h.bg;
3377 return *this;
3378 }
3379 forceinline
3380 Home::operator Space&(void) {
3381 return s;
3382 }
3383 forceinline Home
3385 return Home(s,&p);
3386 }
3387 forceinline Home
3391 forceinline Home
3395 forceinline Home
3397 return Home(*this,&p);
3398 }
3399 forceinline Home
3401 return Home(*this,nullptr,pg,BrancherGroup::def);
3402 }
3403 forceinline Home
3405 return Home(*this,nullptr,PropagatorGroup::def,bg);
3406 }
3407 forceinline Propagator*
3408 Home::propagator(void) const {
3409 return p;
3410 }
3411 forceinline PropagatorGroup
3413 return pg;
3414 }
3415 forceinline BrancherGroup
3417 return bg;
3418 }
3419
3420 /*
3421 * View trace information
3422 *
3423 */
3424 forceinline void
3426 who = reinterpret_cast<ptrdiff_t>(&p) | PROPAGATOR;
3427 }
3428 forceinline void
3430 who = reinterpret_cast<ptrdiff_t>(&b) | BRANCHER;
3431 }
3432 forceinline void
3434 who = (g.id() << 2) | POST;
3435 }
3436 forceinline void
3438 who = OTHER;
3439 }
3440 forceinline ViewTraceInfo::What
3442 return static_cast<What>(who & 3);
3443 }
3444 forceinline const Propagator&
3446 assert(what() == PROPAGATOR);
3447 // Because PROPAGATOR == 0
3448 return *reinterpret_cast<Propagator*>(who);
3449 }
3450 forceinline const Brancher&
3452 assert(what() == BRANCHER);
3453 return *reinterpret_cast<Brancher*>(who & ~3);
3454 }
3455 forceinline PropagatorGroup
3457 assert(what() == POST);
3458 return PropagatorGroup(static_cast<unsigned int>(who >> 2));
3459 }
3460
3461 /*
3462 * Post information
3463 */
3464 forceinline
3466 : h(home), pg(home.propagatorgroup()),
3467 pid(h.ssd.data().gpi.pid()),
3468 nested(h.pc.p.vti.what() != ViewTraceInfo::OTHER) {
3469 h.pc.p.vti.post(pg);
3470 }
3471
3472 forceinline
3474 if (!nested) {
3475 if (h.pc.p.bid_sc & Space::sc_trace)
3476 h.post(*this);
3477 h.pc.p.vti.other();
3478 }
3479 }
3480
3481
3482 /*
3483 * Propagate trace information
3484 *
3485 */
3486 forceinline
3488 const Propagator* p0, Status s0)
3489 : i(i0), g(g0), p(p0), s(s0) {}
3490 forceinline unsigned int
3492 return i;
3493 }
3494 forceinline PropagatorGroup
3496 return g;
3497 }
3498 forceinline const Propagator*
3500 return p;
3501 }
3502 forceinline PropagateTraceInfo::Status
3504 return s;
3505 }
3506
3507
3508 /*
3509 * Commit trace information
3510 *
3511 */
3512 forceinline
3514 unsigned int a0)
3515 : b(b0), c(c0), a(a0) {}
3516 forceinline unsigned int
3518 return b.id();
3519 }
3520 forceinline BrancherGroup
3522 return b.group();
3523 }
3524 forceinline const Brancher&
3526 return b;
3527 }
3528 forceinline const Choice&
3530 return c;
3531 }
3532 forceinline unsigned int
3534 return a;
3535 }
3536
3537
3538 /*
3539 * Post trace information
3540 *
3541 */
3542 forceinline
3544 : g(g0), s(s0), n(n0) {}
3545 forceinline PropagatorGroup
3547 return g;
3548 }
3549 forceinline PostTraceInfo::Status
3551 return s;
3552 }
3553 forceinline unsigned int
3555 return n;
3556 }
3557
3558
3559 /*
3560 * Propagator
3561 *
3562 */
3563 forceinline Propagator*
3564 Propagator::cast(ActorLink* al) {
3565 // Turning al into a reference is for gcc, assume is for MSVC
3566 GECODE_NOT_NULL(al);
3567 ActorLink& t = *al;
3568 return static_cast<Propagator*>(&t);
3569 }
3570
3571 forceinline const Propagator*
3572 Propagator::cast(const ActorLink* al) {
3573 // Turning al into a reference is for gcc, assume is for MSVC
3574 GECODE_NOT_NULL(al);
3575 const ActorLink& t = *al;
3576 return static_cast<const Propagator*>(&t);
3577 }
3578
3579 forceinline Propagator*
3580 Propagator::fwd(void) const {
3581 return static_cast<Propagator*>(prev());
3582 }
3583
3584 forceinline bool
3586 return Support::marked(gpi_disabled);
3587 }
3588
3589 forceinline void
3590 Propagator::disable(Space& home) {
3591 home.pc.p.bid_sc |= Space::sc_disabled;
3592 gpi_disabled = Support::fmark(gpi_disabled);
3593 }
3594
3595 forceinline void
3596 Propagator::enable(Space& home) {
3597 (void) home;
3598 gpi_disabled = Support::funmark(gpi_disabled);
3599 }
3600
3601 forceinline Kernel::GPI::Info&
3603 return *static_cast<Kernel::GPI::Info*>(Support::funmark(gpi_disabled));
3604 }
3605
3606 forceinline
3608 : gpi_disabled((home.propagator() != nullptr) ?
3609 // Inherit propagator information
3610 home.propagator()->gpi_disabled :
3611 // New propagator information
3612 static_cast<Space&>(home).ssd.data().gpi.allocate
3613 (home.propagatorgroup().gid)) {
3614 u.advisors = nullptr;
3615 assert((u.med == 0) && (u.size == 0));
3616 static_cast<Space&>(home).pl.head(this);
3617 }
3618
3619 forceinline
3621 : gpi_disabled(p.gpi_disabled) {
3622 u.advisors = nullptr;
3623 assert((u.med == 0) && (u.size == 0));
3624 // Set forwarding pointer
3625 p.prev(this);
3626 }
3627
3628 forceinline ModEventDelta
3630 return u.med;
3631 }
3632
3633 forceinline double
3634 Propagator::afc(void) const {
3635 return const_cast<Propagator&>(*this).gpi().afc;
3636 }
3637
3638#ifdef GECODE_HAS_CBS
3639 forceinline void
3640 Propagator::solndistrib(Space&, SendMarginal) const {}
3641
3642 forceinline void
3643 Propagator::domainsizesum(InDecision, unsigned int& size,
3644 unsigned int& size_b) const {
3645 size = 0;
3646 size_b = 0;
3647 }
3648#endif
3649
3650 forceinline unsigned int
3651 Propagator::id(void) const {
3652 return const_cast<Propagator&>(*this).gpi().pid;
3653 }
3654
3655 forceinline PropagatorGroup
3656 Propagator::group(void) const {
3657 return PropagatorGroup(const_cast<Propagator&>(*this).gpi().gid);
3658 }
3659
3660 forceinline void
3662 gpi().gid = g.id();
3663 }
3664
3665 forceinline ExecStatus
3667 p.u.size = s;
3668 return ES_SUBSUMED_;
3669 }
3670
3671 forceinline ExecStatus
3673 p.u.size = p.dispose(*this);
3674 return ES_SUBSUMED_;
3675 }
3676
3677 forceinline ExecStatus
3679 p.u.med = med;
3680 assert(p.u.med != 0);
3681 return ES_PARTIAL_;
3682 }
3683
3684 forceinline ExecStatus
3686 p.u.med = AllVarConf::med_combine(p.u.med,med);
3687 assert(p.u.med != 0);
3688 return ES_PARTIAL_;
3689 }
3690
3691
3692
3693 /*
3694 * Brancher
3695 *
3696 */
3697 forceinline Brancher*
3698 Brancher::cast(ActorLink* al) {
3699 // Turning al into a reference is for gcc, assume is for MSVC
3700 GECODE_NOT_NULL(al);
3701 ActorLink& t = *al;
3702 return static_cast<Brancher*>(&t);
3703 }
3704
3705 forceinline const Brancher*
3706 Brancher::cast(const ActorLink* al) {
3707 // Turning al into a reference is for gcc, assume is for MSVC
3708 GECODE_NOT_NULL(al);
3709 const ActorLink& t = *al;
3710 return static_cast<const Brancher*>(&t);
3711 }
3712
3713 forceinline
3715 gid(_home.branchergroup().gid) {
3716 Space& home = static_cast<Space&>(_home);
3717 bid = home.pc.p.bid_sc >> Space::sc_bits;
3718 home.pc.p.bid_sc += (1 << Space::sc_bits);
3719 if ((home.pc.p.bid_sc >> Space::sc_bits) == 0U)
3720 throw TooManyBranchers("Brancher::Brancher");
3721 // If no brancher available, make it the first one
3722 if (home.b_status == &static_cast<Space&>(home).bl) {
3723 home.b_status = this;
3724 if (home.b_commit == &static_cast<Space&>(home).bl)
3725 home.b_commit = this;
3726 }
3727 home.bl.tail(this);
3728 }
3729
3730 forceinline
3732 : bid(b.bid), gid(b.gid) {
3733 // Set forwarding pointer
3734 b.prev(this);
3735 }
3736
3737 forceinline unsigned int
3738 Brancher::id(void) const {
3739 return bid;
3740 }
3741
3742 forceinline BrancherGroup
3743 Brancher::group(void) const {
3744 return BrancherGroup(gid);
3745 }
3746
3747 forceinline void
3749 gid = g.id();
3750 }
3751
3752
3753 forceinline void
3754 Space::kill(Brancher& b) {
3755 assert(!failed());
3756 // Make sure that neither b_status nor b_commit does not point to b!
3757 if (b_commit == &b)
3758 b_commit = Brancher::cast(b.next());
3759 if (b_status == &b)
3760 b_status = Brancher::cast(b.next());
3761 b.unlink();
3762 rfree(&b,b.dispose(*this));
3763 }
3764
3765 forceinline void
3766 Space::kill(Propagator& p) {
3767 assert(!failed());
3768 p.unlink();
3769 rfree(&p,p.dispose(*this));
3770 // Is the space already stable?
3771 if (pc.p.active < &pc.p.queue[0])
3772 return;
3773 // Enforce that empty queues are ignored
3774 do {
3775 assert(pc.p.active >= &pc.p.queue[0]);
3776 // First propagator or link back to queue?
3777 if (pc.p.active != pc.p.active->next())
3778 return; // A propagator is left in the queue
3779 } while (--pc.p.active >= &pc.p.queue[0]);
3780 // The space is stable now
3781 assert(pc.p.active < &pc.p.queue[0]);
3782 }
3783
3784 forceinline Brancher*
3785 Space::brancher(unsigned int id) {
3786 /*
3787 * Due to weakly monotonic propagators the following scenario might
3788 * occur: a brancher has been committed with all its available
3789 * choices. Then, propagation determines less information
3790 * than before and the brancher now will create new choices.
3791 * Later, during recomputation, all of these choices
3792 * can be used together, possibly interleaved with
3793 * choices for other branchers. That means all branchers
3794 * must be scanned to find the matching brancher for the choice.
3795 *
3796 * b_commit tries to optimize scanning as it is most likely that
3797 * recomputation does not generate new choices during recomputation
3798 * and hence b_commit is moved from newer to older branchers.
3799 */
3800 Brancher* b_old = b_commit;
3801 // Try whether we are lucky
3802 while (b_commit != Brancher::cast(&bl))
3803 if (id != b_commit->id())
3804 b_commit = Brancher::cast(b_commit->next());
3805 else
3806 return b_commit;
3807 if (b_commit == Brancher::cast(&bl)) {
3808 // We did not find the brancher, start at the beginning
3809 b_commit = Brancher::cast(bl.next());
3810 while (b_commit != b_old)
3811 if (id != b_commit->id())
3812 b_commit = Brancher::cast(b_commit->next());
3813 else
3814 return b_commit;
3815 }
3816 return nullptr;
3817 }
3818
3819
3820 /*
3821 * Local objects
3822 *
3823 */
3824
3825 forceinline LocalObject*
3827 // Turning al into a reference is for gcc, assume is for MSVC
3828 GECODE_NOT_NULL(al);
3829 ActorLink& t = *al;
3830 return static_cast<LocalObject*>(&t);
3831 }
3832
3833 forceinline const LocalObject*
3835 // Turning al into a reference is for gcc, assume is for MSVC
3836 GECODE_NOT_NULL(al);
3837 const ActorLink& t = *al;
3838 return static_cast<const LocalObject*>(&t);
3839 }
3840
3841 forceinline
3843 (void) home;
3844 ActorLink::cast(this)->prev(nullptr);
3845 }
3846
3847 forceinline
3851
3852 forceinline LocalObject*
3854 if (prev() == nullptr)
3855 fwdcopy(home);
3856 return LocalObject::cast(prev());
3857 }
3858
3859 forceinline
3860 LocalHandle::LocalHandle(void) : o(nullptr) {}
3861 forceinline
3863 forceinline
3865 forceinline LocalHandle&
3867 o = lh.o;
3868 return *this;
3869 }
3870 forceinline
3872 forceinline LocalObject*
3873 LocalHandle::object(void) const { return o; }
3874 forceinline void
3876 forceinline void
3878 object(lh.object()->fwd(home));
3879 }
3880
3881
3882 /*
3883 * Choices
3884 *
3885 */
3886 forceinline
3887 Choice::Choice(const Brancher& b, const unsigned int a)
3888 : bid(b.id()), alt(a) {}
3889
3890 forceinline unsigned int
3892 return alt;
3893 }
3894
3895 forceinline unsigned int
3896 Choice::id(void) const {
3897 return bid;
3898 }
3899
3900 forceinline
3902
3903
3904
3905 /*
3906 * No-good literal
3907 *
3908 */
3909 forceinline bool
3910 NGL::leaf(void) const {
3911 return Support::marked(nl);
3912 }
3913 forceinline NGL*
3914 NGL::next(void) const {
3915 return static_cast<NGL*>(Support::funmark(nl));
3916 }
3917 forceinline void
3918 NGL::leaf(bool l) {
3919 nl = l ? Support::fmark(nl) : Support::funmark(nl);
3920 }
3921 forceinline void
3923 nl = Support::marked(nl) ? Support::mark(n) : n;
3924 }
3925 forceinline NGL*
3926 NGL::add(NGL* n, bool l) {
3927 nl = Support::marked(nl) ? Support::mark(n) : n;
3928 n->leaf(l);
3929 return n;
3930 }
3931
3932 forceinline
3934 : nl(nullptr) {}
3935 forceinline
3937 : nl(nullptr) {}
3938 forceinline
3940 : nl(nullptr) {}
3941 forceinline size_t
3943 return sizeof(*this);
3944 }
3945
3946 /*
3947 * Advisor
3948 *
3949 */
3950 template<class A>
3951 forceinline
3953 // Store propagator and forwarding in prev()
3954 ActorLink::prev(&p);
3955 // Link to next advisor in next()
3956 ActorLink::next(c.advisors); c.advisors = static_cast<A*>(this);
3957 }
3958
3959 forceinline
3961
3962 forceinline bool
3963 Advisor::disposed(void) const {
3964 return prev() == nullptr;
3965 }
3966
3967 forceinline Advisor*
3968 Advisor::cast(ActorLink* al) {
3969 return static_cast<Advisor*>(al);
3970 }
3971
3972 forceinline const Advisor*
3973 Advisor::cast(const ActorLink* al) {
3974 return static_cast<const Advisor*>(al);
3975 }
3976
3977 forceinline ActorLink*
3978 Advisor::link(Advisor& a) {
3979 return static_cast<ActorLink*>(&a);
3980 }
3981
3982 forceinline Propagator&
3984 assert(!disposed());
3985 return *Propagator::cast(ActorLink::prev());
3986 }
3987
3988 template<class A>
3989 forceinline void
3991 assert(!disposed());
3992 ActorLink::prev(nullptr);
3993 // Shorten chains of disposed advisors by one, if possible
3994 Advisor* n = Advisor::cast(next());
3995 if ((n != nullptr) && n->disposed())
3996 next(n->next());
3997 }
3998
3999 forceinline const ViewTraceInfo&
4000 Advisor::operator ()(const Space& home) const {
4001 return home.pc.p.vti;
4002 }
4003
4004 template<class A>
4005 forceinline ExecStatus
4007 a.dispose(*this,c);
4008 return ES_FIX;
4009 }
4010
4011 template<class A>
4012 forceinline ExecStatus
4014 a.dispose(*this,c);
4015 return ES_NOFIX;
4016 }
4017
4018 template<class A>
4019 forceinline ExecStatus
4021 a.dispose(*this,c);
4022 return ES_NOFIX_FORCE;
4023 }
4024
4025
4026
4027 /*
4028 * Advisor council
4029 *
4030 */
4031 template<class A>
4032 forceinline
4034
4035 template<class A>
4036 forceinline
4038 : advisors(nullptr) {}
4039
4040 template<class A>
4041 forceinline bool
4042 Council<A>::empty(void) const {
4043 ActorLink* a = advisors;
4044 while ((a != nullptr) && static_cast<A*>(a)->disposed())
4045 a = a->next();
4046 advisors = a;
4047 return a == nullptr;
4048 }
4049
4050 template<class A>
4051 forceinline void
4053 // Skip all disposed advisors
4054 {
4055 ActorLink* a = c.advisors;
4056 while ((a != nullptr) && static_cast<A*>(a)->disposed())
4057 a = a->next();
4058 c.advisors = a;
4059 }
4060 // Are there any advisors to be cloned?
4061 if (c.advisors != nullptr) {
4062 // The propagator in from-space
4063 Propagator* p_f = &static_cast<A*>(c.advisors)->propagator();
4064 // The propagator in to-space
4065 Propagator* p_t = Propagator::cast(p_f->prev());
4066 // Advisors in from-space
4067 ActorLink** a_f = &c.advisors;
4068 // Advisors in to-space
4069 A* a_t = nullptr;
4070 // Enter advisor link early so failed clone recovery can restore links.
4071 assert(p_f->u.advisors == nullptr);
4072 p_f->u.advisors = c.advisors;
4073 try {
4074 while (*a_f != nullptr) {
4075 if (static_cast<A*>(*a_f)->disposed()) {
4076 *a_f = (*a_f)->next();
4077 } else {
4078 // Run specific copying part
4079 A* a = new (home) A(home,*static_cast<A*>(*a_f));
4080 // Set propagator pointer
4081 a->prev(p_t);
4082 // Set forwarding pointer
4083 (*a_f)->prev(a);
4084 // Link
4085 a->next(a_t);
4086 a_t = a;
4087 advisors = a_t;
4088 a_f = (*a_f)->next_ref();
4089 }
4090 }
4091 } catch (...) {
4092 dispose(home);
4093 advisors = nullptr;
4094 for (ActorLink* a = c.advisors; a != nullptr; a = a->next())
4095 if (!static_cast<A*>(a)->disposed())
4096 a->prev(p_f);
4097 p_f->u.advisors = nullptr;
4098 throw;
4099 }
4100 advisors = a_t;
4101 } else {
4102 advisors = nullptr;
4103 }
4104 }
4105
4106 template<class A>
4107 forceinline void
4109 ActorLink* a = advisors;
4110 while (a != nullptr) {
4111 if (!static_cast<A*>(a)->disposed())
4112 static_cast<A*>(a)->dispose(home,*this);
4113 a = a->next();
4114 }
4115 }
4116
4117
4118
4119 /*
4120 * Advisor iterator
4121 *
4122 */
4123 template<class A>
4124 forceinline
4126 : a(c.advisors) {
4127 while ((a != nullptr) && static_cast<A*>(a)->disposed())
4128 a = a->next();
4129 }
4130
4131 template<class A>
4132 forceinline bool
4134 return a != nullptr;
4135 }
4136
4137 template<class A>
4138 forceinline void
4140 do {
4141 a = a->next();
4142 } while ((a != nullptr) && static_cast<A*>(a)->disposed());
4143 }
4144
4145 template<class A>
4146 forceinline A&
4148 return *static_cast<A*>(a);
4149 }
4150
4151
4152
4153 /*
4154 * Space
4155 *
4156 */
4157 forceinline void
4158 Space::enqueue(Propagator* p) {
4160 ActorLink* c = &pc.p.queue[p->cost(*this,p->u.med).ac];
4161 c->tail(ActorLink::cast(p));
4162 if (c > pc.p.active)
4163 pc.p.active = c;
4164 }
4165
4166 forceinline void
4168 pc.p.active = &pc.p.queue[PropCost::AC_MAX+1]+1;
4169 /*
4170 * Now active points beyond the last queue. This is essential as
4171 * enqueuing a propagator in a failed space keeps the space
4172 * failed.
4173 */
4174 }
4175 forceinline void
4177 s.fail();
4178 }
4179
4180 forceinline bool
4181 Space::failed(void) const {
4182 return pc.p.active > &pc.p.queue[PropCost::AC_MAX+1];
4183 }
4184 forceinline bool
4185 Home::failed(void) const {
4186 return s.failed();
4187 }
4188
4189 forceinline bool
4190 Space::stable(void) const {
4191 return ((pc.p.active < &pc.p.queue[0]) ||
4192 (pc.p.active > &pc.p.queue[PropCost::AC_MAX+1]));
4193 }
4194
4195 forceinline void
4197 if (p & AP_DISPOSE) {
4198 ap_notice_dispose(&a,d);
4199 }
4200 if (p & AP_VIEW_TRACE) {
4201 pc.p.bid_sc |= sc_trace;
4202 }
4203 if (p & AP_TRACE) {
4204 pc.p.bid_sc |= sc_trace;
4205 }
4206 // Currently unused
4207 if (p & AP_WEAKLY) {
4208 // Nothing to do
4209 }
4210 }
4211
4212 forceinline void
4214 // Check whether array has already been discarded as space
4215 // deletion is already in progress
4216 if ((p & AP_DISPOSE) && (d_fst != nullptr))
4217 ap_ignore_dispose(&a,d);
4218 if (p & AP_VIEW_TRACE) {
4219 // Nothing to do
4220 }
4221 if (p & AP_TRACE) {
4222 // Nothing to do
4223 }
4224 // Currently unused
4225 if (p & AP_WEAKLY) {
4226 // Nothing to do
4227 }
4228 }
4229
4230
4231
4232 /*
4233 * Variable implementation
4234 *
4235 */
4236 template<class VIC>
4237 forceinline ActorLink**
4238 VarImp<VIC>::actor(PropCond pc) {
4239 assert((pc >= 0) && (pc < pc_max+2));
4240 return (pc == 0) ? b.base : b.base+u.idx[pc-1];
4241 }
4242
4243 template<class VIC>
4244 forceinline ActorLink**
4245 VarImp<VIC>::actorNonZero(PropCond pc) {
4246 assert((pc > 0) && (pc < pc_max+2));
4247 return b.base+u.idx[pc-1];
4248 }
4249
4250 template<class VIC>
4251 forceinline unsigned int&
4253 assert((pc > 0) && (pc < pc_max+2));
4254 return u.idx[pc-1];
4255 }
4256
4257 template<class VIC>
4258 forceinline unsigned int
4259 VarImp<VIC>::idx(PropCond pc) const {
4260 assert((pc > 0) && (pc < pc_max+2));
4261 return u.idx[pc-1];
4262 }
4263
4264 template<class VIC>
4265 forceinline
4267#ifdef GECODE_HAS_CBS
4268 : var_id(++home.var_id_counter)
4269#endif
4270 {
4271#ifndef GECODE_HAS_CBS
4272 (void) home;
4273#endif
4274 b.base = nullptr; entries = 0;
4275 for (PropCond pc=1; pc<pc_max+2; pc++)
4276 idx(pc) = 0;
4277 free_and_bits = 0;
4278 }
4279
4280 template<class VIC>
4281 forceinline
4283#ifdef GECODE_HAS_CBS
4284 : var_id(0)
4285#endif
4286 {
4287 b.base = nullptr; entries = 0;
4288 for (PropCond pc=1; pc<pc_max+2; pc++)
4289 idx(pc) = 0;
4290 free_and_bits = 0;
4291 }
4292
4293#ifdef GECODE_HAS_CBS
4294 template<class VIC>
4295 forceinline unsigned int
4296 VarImp<VIC>::id(void) const {
4297 return var_id;
4298 }
4299#endif
4300
4301 template<class VIC>
4302 forceinline unsigned int
4304 assert(!copied());
4305 return entries;
4306 }
4307
4308 template<class VIC>
4309 forceinline double
4310 VarImp<VIC>::afc(void) const {
4311 double d = 0.0;
4312 // Count the afc of each propagator
4313 {
4314 ActorLink** a = const_cast<VarImp<VIC>*>(this)->actor(0);
4315 ActorLink** e = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
4316 while (a < e) {
4317 d += Propagator::cast(*a)->afc(); a++;
4318 }
4319 }
4320 // Count the afc of each advisor's propagator
4321 {
4322 ActorLink** a = const_cast<VarImp<VIC>*>(this)->actorNonZero(pc_max+1);
4323 ActorLink** e = const_cast<VarImp<VIC>*>(this)->b.base+entries;
4324 while (a < e) {
4325 d += Advisor::cast(static_cast<ActorLink*>(Support::funmark(*a)))
4326 ->propagator().afc();
4327 a++;
4328 }
4329 }
4330 return d;
4331 }
4332
4333 template<class VIC>
4334 forceinline ModEvent
4336 return d.me;
4337 }
4338
4339 template<class VIC>
4340 forceinline unsigned int
4341 VarImp<VIC>::bits(void) const {
4342 return free_and_bits;
4343 }
4344
4345 template<class VIC>
4346 forceinline unsigned int&
4348 return free_and_bits;
4349 }
4350
4351#ifdef GECODE_HAS_VAR_DISPOSE
4352 template<class VIC>
4353 forceinline VarImp<VIC>*
4354 VarImp<VIC>::vars_d(Space& home) {
4355 return static_cast<VarImp<VIC>*>(home.vars_d<VIC>());
4356 }
4357
4358 template<class VIC>
4359 forceinline void
4360 VarImp<VIC>::vars_d(Space& home, VarImp<VIC>* x) {
4361 home.vars_d<VIC>(x);
4362 }
4363#endif
4364
4365 template<class VIC>
4366 forceinline bool
4368 return Support::marked(b.fwd);
4369 }
4370
4371 template<class VIC>
4372 forceinline VarImp<VIC>*
4374 assert(copied());
4375 return static_cast<VarImp<VIC>*>(Support::unmark(b.fwd));
4376 }
4377
4378 template<class VIC>
4379 forceinline VarImp<VIC>*
4380 VarImp<VIC>::next(void) const {
4381 assert(copied());
4382 return u.next;
4383 }
4384
4385 template<class VIC>
4386 forceinline
4388#ifdef GECODE_HAS_CBS
4389 : var_id(x.var_id)
4390#endif
4391 {
4392 VarImpBase** reg;
4393 free_and_bits = x.free_and_bits & ((1 << free_bits) - 1);
4394 if (x.b.base == nullptr) {
4395 // Variable implementation needs no index structure
4396 reg = &home.pc.c.vars_noidx;
4397 assert(x.degree() == 0);
4398 } else {
4399 reg = &home.pc.c.vars_u[idx_c];
4400 }
4401 // Save subscriptions in copy
4402 b.base = x.b.base;
4403 entries = x.entries;
4404 for (PropCond pc=1; pc<pc_max+2; pc++)
4405 idx(pc) = x.idx(pc);
4406
4407 // Set forwarding pointer
4408 x.b.fwd = static_cast<VarImp<VIC>*>(Support::mark(this));
4409 // Register original
4410 x.u.next = static_cast<VarImp<VIC>*>(*reg); *reg = &x;
4411 }
4412
4413 template<class VIC>
4414 forceinline ModEvent
4416 return static_cast<ModEvent>((med & VIC::med_mask) >> VIC::med_fst);
4417 }
4418
4419 template<class VIC>
4420 forceinline ModEventDelta
4422 return static_cast<ModEventDelta>(me << VIC::med_fst);
4423 }
4424
4425 template<class VIC>
4426 forceinline ModEvent
4428 return VIC::me_combine(me1,me2);
4429 }
4430
4431 template<class VIC>
4432 forceinline void
4434 bool force) {
4435 if (VIC::med_update(p.u.med,me) || force)
4436 home.enqueue(&p);
4437 }
4438
4439 template<class VIC>
4440 forceinline void
4442 if (b.base == nullptr)
4443 return;
4444 ActorLink** begin = actor(pc1);
4445 ActorLink** end = actorNonZero(pc2+1);
4446 while (end > begin) {
4447 end--;
4448 schedule(home,*Propagator::cast(*end),me);
4449 }
4450 }
4451
4452 template<class VIC>
4453 forceinline void
4454 VarImp<VIC>::resize(Space& home) {
4455 if (b.base == nullptr) {
4456 assert((free_and_bits >> free_bits) == 0);
4457 // Create fresh dependency array with four entries
4458 free_and_bits += 4 << free_bits;
4459 b.base = home.alloc<ActorLink*>(4);
4460 for (int i=0; i<pc_max+1; i++)
4461 u.idx[i] = 0;
4462 } else {
4463 // Resize dependency array
4464 unsigned int n = degree();
4465 // Find out whether the area is most likely in the special area
4466 // reserved for subscriptions. If yes, just resize mildly otherwise
4467 // more aggressively
4468 ActorLink** s = static_cast<ActorLink**>(home.mm.subscriptions());
4469 unsigned int m =
4470 ((s <= b.base) && (b.base < s+home.pc.p.n_sub)) ?
4471 (n+4) : ((n+1)*3>>1);
4472 ActorLink** prop = home.alloc<ActorLink*>(m);
4473 free_and_bits += (m-n) << free_bits;
4474 // Copy entries
4475 Heap::copy<ActorLink*>(prop, b.base, n);
4476 home.free<ActorLink*>(b.base,n);
4477 b.base = prop;
4478 }
4479 }
4480
4481 template<class VIC>
4482 forceinline void
4483 VarImp<VIC>::enter(Space& home, Propagator* p, PropCond pc) {
4484 assert(pc <= pc_max);
4485 // Count one new subscription
4486 home.pc.p.n_sub += 1;
4487 if ((free_and_bits >> free_bits) == 0)
4488 resize(home);
4489 free_and_bits -= 1 << free_bits;
4490
4491 // Enter subscription
4492 b.base[entries] = *actorNonZero(pc_max+1);
4493 entries++;
4494 for (PropCond j = pc_max; j > pc; j--) {
4495 *actorNonZero(j+1) = *actorNonZero(j);
4496 idx(j+1)++;
4497 }
4498 *actorNonZero(pc+1) = *actor(pc);
4499 idx(pc+1)++;
4500 *actor(pc) = ActorLink::cast(p);
4501
4502#ifdef GECODE_AUDIT
4503 ActorLink** f = actor(pc);
4504 while (f < (pc == pc_max+1 ? b.base+entries : actorNonZero(pc+1)))
4505 if (*f == p)
4506 goto found;
4507 else
4508 f++;
4510 found: ;
4511#endif
4512 }
4513
4514 template<class VIC>
4515 forceinline void
4516 VarImp<VIC>::enter(Space& home, ActorLink* a) {
4517 // Note that a might be a marked pointer
4518 // Count one new subscription
4519 home.pc.p.n_sub += 1;
4520 if ((free_and_bits >> free_bits) == 0)
4521 resize(home);
4522 free_and_bits -= 1 << free_bits;
4523
4524 // Enter subscription
4525 b.base[entries++] = *actorNonZero(pc_max+1);
4526 *actorNonZero(pc_max+1) = a;
4527 }
4528
4529 template<class VIC>
4530 forceinline void
4532 bool assigned, ModEvent me, bool schedule) {
4533 if (assigned) {
4534 // Do not subscribe, just schedule the propagator
4535 if (schedule)
4537 } else {
4538 enter(home,&p,pc);
4539 // Schedule propagator
4540 if (schedule && (pc != PC_GEN_ASSIGNED))
4541 VarImp<VIC>::schedule(home,p,me);
4542 }
4543 }
4544
4545 template<class VIC>
4546 forceinline void
4547 VarImp<VIC>::subscribe(Space& home, Advisor& a, bool assigned, bool fail) {
4548 if (!assigned) {
4549 ActorLink* ma = static_cast<ActorLink*>
4550 (Support::ptrjoin(Advisor::link(a),fail ? 1 : 0));
4551 enter(home,ma);
4552 }
4553 }
4554
4555 template<class VIC>
4556 forceinline void
4558 bool assigned, ModEvent me) {
4559 if (assigned)
4561 else if (pc != PC_GEN_ASSIGNED)
4562 VarImp<VIC>::schedule(home,p,me);
4563 }
4564
4565 template<class VIC>
4566 void
4567 VarImp<VIC>::remove(Space& home, Propagator* p, PropCond pc) {
4568 assert(pc <= pc_max);
4569 ActorLink* a = ActorLink::cast(p);
4570 // Find actor in dependency array
4571 ActorLink** f = actor(pc);
4572#ifdef GECODE_AUDIT
4573 while (f < actorNonZero(pc+1))
4574 if (*f == a)
4575 goto found;
4576 else
4577 f++;
4579 found: ;
4580#else
4581 while (*f != a) f++;
4582#endif
4583 // Remove actor
4584 *f = *(actorNonZero(pc+1)-1);
4585 for (PropCond j = pc+1; j< pc_max+1; j++) {
4586 *(actorNonZero(j)-1) = *(actorNonZero(j+1)-1);
4587 idx(j)--;
4588 }
4589 *(actorNonZero(pc_max+1)-1) = b.base[entries-1];
4590 idx(pc_max+1)--;
4591 entries--;
4592 free_and_bits += 1 << free_bits;
4593 home.pc.p.n_sub -= 1;
4594 }
4595
4596 template<class VIC>
4597 forceinline void
4599 if ((b.base != nullptr) && !home.is_partial_clone())
4600 remove(home,&p,pc);
4601 }
4602
4603 template<class VIC>
4604 void
4605 VarImp<VIC>::remove(Space& home, ActorLink* a) {
4606 // Note that a might be a marked pointer
4607 // Find actor in dependency array
4608 ActorLink** f = actorNonZero(pc_max+1);
4609#ifdef GECODE_AUDIT
4610 while (f < b.base+entries)
4611 if (*f == a)
4612 goto found;
4613 else
4614 f++;
4616 found: ;
4617#else
4618 while (*f != a) f++;
4619#endif
4620 // Remove actor
4621 *f = b.base[--entries];
4622 free_and_bits += 1 << free_bits;
4623 home.pc.p.n_sub -= 1;
4624 }
4625
4626 template<class VIC>
4627 forceinline void
4629 if ((b.base != nullptr) && !home.is_partial_clone()) {
4630 ActorLink* ma = static_cast<ActorLink*>
4631 (Support::ptrjoin(Advisor::link(a),fail ? 1 : 0));
4632 remove(home,ma);
4633 }
4634 }
4635
4636 template<class VIC>
4637 forceinline void
4639 unsigned int n_sub = degree();
4640 home.pc.p.n_sub -= n_sub;
4641 unsigned int n = (free_and_bits >> free_bits) + n_sub;
4642 home.free<ActorLink*>(b.base,n);
4643 // Must be nullptr such that cloning works
4644 b.base = nullptr;
4645 // Must be 0 such that degree works
4646 entries = 0;
4647 // Must be nullptr such that afc works
4648 for (PropCond pc=1; pc<pc_max+2; pc++)
4649 idx(pc) = 0;
4650 free_and_bits &= (1 << free_bits) - 1;
4651 }
4652
4653 template<class VIC>
4654 forceinline bool
4656 /*
4657 * An advisor that is executed might remove itself due to subsumption.
4658 * As entries are removed from front to back, the advisors must
4659 * be iterated in forward direction.
4660 */
4661 ActorLink** la = actorNonZero(pc_max+1);
4662 ActorLink** le = b.base+entries;
4663 if (la == le)
4664 return true;
4665 d.me = me;
4666 // An advisor that is run, might be removed during execution.
4667 // As removal is done from the back the advisors have to be executed
4668 // in inverse order.
4669 do {
4670 Advisor* a = Advisor::cast
4671 (static_cast<ActorLink*>(Support::funmark(*la)));
4672 assert(!a->disposed());
4673 Propagator& p = a->propagator();
4674 switch (p.advise(home,*a,d)) {
4675 case ES_FIX:
4676 break;
4677 case ES_FAILED:
4678 return false;
4679 case ES_NOFIX:
4680 schedule(home,p,me);
4681 break;
4682 case ES_NOFIX_FORCE:
4683 schedule(home,p,me,true);
4684 break;
4685 case ES_SUBSUMED_:
4686 default:
4688 }
4689 } while (++la < le);
4690 return true;
4691 }
4692
4693 template<class VIC>
4694 void
4695 VarImp<VIC>::_fail(Space& home) {
4696 /*
4697 * An advisor that is executed might remove itself due to subsumption.
4698 * As entries are removed from front to back, the advisors must
4699 * be iterated in forward direction.
4700 */
4701 ActorLink** la = actorNonZero(pc_max+1);
4702 ActorLink** le = b.base+entries;
4703 if (la == le)
4704 return;
4705 // An advisor that is run, might be removed during execution.
4706 // As removal is done from the back the advisors have to be executed
4707 // in inverse order.
4708 do {
4709 if (Support::marked(*la)) {
4710 Advisor* a = Advisor::cast(static_cast<ActorLink*>
4711 (Support::unmark(*la)));
4712 assert(!a->disposed());
4713 Propagator& p = a->propagator();
4714 p.advise(home,*a);
4715 }
4716 } while (++la < le);
4717 }
4718
4719 template<class VIC>
4720 ModEvent
4722 _fail(home);
4723 return ME_GEN_FAILED;
4724 }
4725
4726 // Clang incorrectly reports an error on the access to u.idx[1] for BoolVarImp,
4727 // even though the access is guarded by pc_max > 0 which implies that the size is sufficient.
4728#pragma clang diagnostic push
4729#pragma clang diagnostic ignored "-Warray-bounds"
4730
4731 template<class VIC>
4732 forceinline void
4733 VarImp<VIC>::update(VarImp<VIC>* x, ActorLink**& sub) {
4734 // this refers to the variable to be updated (clone)
4735 // x refers to the original
4736 // Recover from copy
4737 x->b.base = b.base;
4738 x->u.idx[0] = u.idx[0];
4739 if (pc_max > 0 && sizeof(ActorLink**) > sizeof(unsigned int))
4740 x->u.idx[1] = u.idx[1];
4741
4742 unsigned int np =
4743 static_cast<unsigned int>(x->actorNonZero(pc_max+1) - x->actor(0));
4744 unsigned int na =
4745 static_cast<unsigned int >(x->b.base + x->entries -
4746 x->actorNonZero(pc_max+1));
4747 unsigned int n = na + np;
4748 assert(n == x->degree());
4749
4750 ActorLink** f = x->b.base;
4751 ActorLink** t = sub;
4752
4753 sub += n;
4754 b.base = t;
4755 // Process propagator subscriptions
4756 while (np >= 4) {
4757 ActorLink* p3 = f[3]->prev();
4758 ActorLink* p0 = f[0]->prev();
4759 ActorLink* p1 = f[1]->prev();
4760 ActorLink* p2 = f[2]->prev();
4761 t[0] = p0; t[1] = p1; t[2] = p2; t[3] = p3;
4762 np -= 4; t += 4; f += 4;
4763 }
4764 if (np >= 2) {
4765 ActorLink* p0 = f[0]->prev();
4766 ActorLink* p1 = f[1]->prev();
4767 t[0] = p0; t[1] = p1;
4768 np -= 2; t += 2; f += 2;
4769 }
4770 if (np > 0) {
4771 ActorLink* p0 = f[0]->prev();
4772 t[0] = p0;
4773 t += 1; f += 1;
4774 }
4775 // Process advisor subscriptions
4776 while (na >= 4) {
4777 ptrdiff_t m0, m1, m2, m3;
4778 ActorLink* p3 =
4779 static_cast<ActorLink*>(Support::ptrsplit(f[3],m3))->prev();
4780 ActorLink* p0 =
4781 static_cast<ActorLink*>(Support::ptrsplit(f[0],m0))->prev();
4782 ActorLink* p1 =
4783 static_cast<ActorLink*>(Support::ptrsplit(f[1],m1))->prev();
4784 ActorLink* p2 =
4785 static_cast<ActorLink*>(Support::ptrsplit(f[2],m2))->prev();
4786 t[0] = static_cast<ActorLink*>(Support::ptrjoin(p0,m0));
4787 t[1] = static_cast<ActorLink*>(Support::ptrjoin(p1,m1));
4788 t[2] = static_cast<ActorLink*>(Support::ptrjoin(p2,m2));
4789 t[3] = static_cast<ActorLink*>(Support::ptrjoin(p3,m3));
4790 na -= 4; t += 4; f += 4;
4791 }
4792 if (na >= 2) {
4793 ptrdiff_t m0, m1;
4794 ActorLink* p0 =
4795 static_cast<ActorLink*>(Support::ptrsplit(f[0],m0))->prev();
4796 ActorLink* p1 =
4797 static_cast<ActorLink*>(Support::ptrsplit(f[1],m1))->prev();
4798 t[0] = static_cast<ActorLink*>(Support::ptrjoin(p0,m0));
4799 t[1] = static_cast<ActorLink*>(Support::ptrjoin(p1,m1));
4800 na -= 2; t += 2; f += 2;
4801 }
4802 if (na > 0) {
4803 ptrdiff_t m0;
4804 ActorLink* p0 =
4805 static_cast<ActorLink*>(Support::ptrsplit(f[0],m0))->prev();
4806 t[0] = static_cast<ActorLink*>(Support::ptrjoin(p0,m0));
4807 }
4808 }
4809#pragma clang diagnostic pop
4810
4811 template<class VIC>
4812 forceinline void
4813 VarImp<VIC>::update(Space& home, ActorLink**& sub) {
4814 VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home.pc.c.vars_u[idx_c]);
4815 while (x != nullptr) {
4816 VarImp<VIC>* n = x->next(); x->forward()->update(x,sub); x = n;
4817 }
4818 }
4819
4820 template<class VIC>
4821 forceinline void
4822 VarImp<VIC>::recover(Space& home, ActorLink**&) {
4823 VarImp<VIC>* x = static_cast<VarImp<VIC>*>(home.pc.c.vars_u[idx_c]);
4824 while (x != nullptr) {
4825 if (x->copied()) {
4826 VarImp<VIC>* n = x->next();
4827 VarImp<VIC>* copy = x->forward();
4828 x->b.base = copy->b.base;
4829 x->u.idx[0] = copy->u.idx[0];
4830 if (pc_max > 0 && sizeof(ActorLink**) > sizeof(unsigned int))
4831 x->u.idx[1] = copy->u.idx[1];
4832 x = n;
4833 } else {
4834 break;
4835 }
4836 }
4837 }
4838
4839
4840
4841 /*
4842 * Variable disposer
4843 *
4844 */
4845 template<class VarImp>
4847#ifdef GECODE_HAS_VAR_DISPOSE
4848 Space::vd[VarImp::idx_d] = this;
4849#endif
4850 }
4851
4852 template<class VarImp>
4853 void
4855 VarImp* x = static_cast<VarImp*>(_x);
4856 do {
4857 x->dispose(home); x = static_cast<VarImp*>(x->next_d());
4858 } while (x != nullptr);
4859 }
4860
4861 /*
4862 * Statistics
4863 */
4864
4865 forceinline void
4867 propagate = 0;
4868 }
4869 forceinline
4873 forceinline StatusStatistics&
4875 propagate += s.propagate;
4876 return *this;
4877 }
4878 forceinline StatusStatistics
4880 StatusStatistics t(s);
4881 return t += *this;
4882 }
4883
4884 forceinline void
4886
4887 forceinline
4891 forceinline CloneStatistics
4894 return s;
4895 }
4896 forceinline CloneStatistics&
4898 return *this;
4899 }
4900
4901 forceinline void
4903
4904 forceinline
4908 forceinline CommitStatistics
4911 return s;
4912 }
4913 forceinline CommitStatistics&
4915 return *this;
4916 }
4917
4918 /*
4919 * Cost computation
4920 *
4921 */
4922
4923 forceinline
4924 PropCost::PropCost(PropCost::ActualCost ac0) : ac(ac0) {}
4925
4926 forceinline PropCost
4927 PropCost::cost(PropCost::Mod m,
4929 unsigned int n) {
4930 if (n < 2)
4931 return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
4932 else if (n == 2)
4933 return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
4934 else if (n == 3)
4935 return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
4936 else
4937 return (m == LO) ? lo : hi;
4938 }
4939
4940 forceinline PropCost
4942 return AC_RECORD;
4943 }
4944 forceinline PropCost
4945 PropCost::crazy(PropCost::Mod m, unsigned int n) {
4946 return cost(m,AC_CRAZY_LO,AC_CRAZY_HI,n);
4947 }
4948 forceinline PropCost
4950 assert(n >= 0);
4951 return crazy(m,static_cast<unsigned int>(n));
4952 }
4953 forceinline PropCost
4954 PropCost::cubic(PropCost::Mod m, unsigned int n) {
4955 return cost(m,AC_CUBIC_LO,AC_CUBIC_HI,n);
4956 }
4957 forceinline PropCost
4959 assert(n >= 0);
4960 return cubic(m,static_cast<unsigned int>(n));
4961 }
4962 forceinline PropCost
4964 return cost(m,AC_QUADRATIC_LO,AC_QUADRATIC_HI,n);
4965 }
4966 forceinline PropCost
4968 assert(n >= 0);
4969 return quadratic(m,static_cast<unsigned int>(n));
4970 }
4971 forceinline PropCost
4972 PropCost::linear(PropCost::Mod m, unsigned int n) {
4973 return cost(m,AC_LINEAR_LO,AC_LINEAR_HI,n);
4974 }
4975 forceinline PropCost
4977 assert(n >= 0);
4978 return linear(m,static_cast<unsigned int>(n));
4979 }
4980 forceinline PropCost
4982 return (m == LO) ? AC_TERNARY_LO : AC_TERNARY_HI;
4983 }
4984 forceinline PropCost
4986 return (m == LO) ? AC_BINARY_LO : AC_BINARY_HI;
4987 }
4988 forceinline PropCost
4990 return (m == LO) ? AC_UNARY_LO : AC_UNARY_HI;
4991 }
4992
4993 /*
4994 * Iterators for propagators and branchers of a space
4995 *
4996 */
4997 forceinline
4999 : home(home0), q(home.pc.p.active) {
5000 while (q >= &home.pc.p.queue[0]) {
5001 if (q->next() != q) {
5002 c = q->next(); e = q; q--;
5003 return;
5004 }
5005 q--;
5006 }
5007 q = nullptr;
5008 if (!home.pl.empty()) {
5009 c = Propagator::cast(home.pl.next());
5010 e = Propagator::cast(&home.pl);
5011 } else {
5012 c = e = nullptr;
5013 }
5014 }
5015 forceinline bool
5017 return c != nullptr;
5018 }
5019 forceinline void
5021 c = c->next();
5022 if (c == e) {
5023 if (q == nullptr) {
5024 c = nullptr;
5025 } else {
5026 while (q >= &home.pc.p.queue[0]) {
5027 if (q->next() != q) {
5028 c = q->next(); e = q; q--;
5029 return;
5030 }
5031 q--;
5032 }
5033 q = nullptr;
5034 if (!home.pl.empty()) {
5035 c = Propagator::cast(home.pl.next());
5036 e = Propagator::cast(&home.pl);
5037 } else {
5038 c = nullptr;
5039 }
5040 }
5041 }
5042 }
5043 forceinline Propagator&
5045 return *Propagator::cast(c);
5046 }
5047
5048
5049 forceinline
5051 : home(home0), q(home.pc.p.active) {
5052 while (q >= &home.pc.p.queue[0]) {
5053 if (q->next() != q) {
5054 c = q->next(); e = q; q--;
5055 return;
5056 }
5057 q--;
5058 }
5059 q = c = e = nullptr;
5060 }
5061 forceinline bool
5063 return c != nullptr;
5064 }
5065 forceinline void
5067 c = c->next();
5068 if (c == e) {
5069 if (q == nullptr) {
5070 c = nullptr;
5071 } else {
5072 while (q >= &home.pc.p.queue[0]) {
5073 if (q->next() != q) {
5074 c = q->next(); e = q; q--;
5075 return;
5076 }
5077 q--;
5078 }
5079 q = c = e = nullptr;
5080 }
5081 }
5082 }
5083 forceinline Propagator&
5085 return *Propagator::cast(c);
5086 }
5087
5088
5089 forceinline
5091 c = Propagator::cast(home.pl.next());
5092 e = Propagator::cast(&home.pl);
5093 }
5094 forceinline bool
5096 return c != e;
5097 }
5098 forceinline void
5100 c = c->next();
5101 }
5102 forceinline Propagator&
5104 return *Propagator::cast(c);
5105 }
5106
5107
5108 forceinline
5110 : c(Brancher::cast(home.bl.next())), e(&home.bl) {}
5111 forceinline bool
5113 return c != e;
5114 }
5115 forceinline void
5117 c = c->next();
5118 }
5119 forceinline Brancher&
5121 return *Brancher::cast(c);
5122 }
5123
5124
5125 /*
5126 * Groups of actors
5127 */
5128 forceinline
5129 Group::Group(unsigned int gid0) : gid(gid0) {}
5130
5131 forceinline bool
5132 Group::in(Group actor) const {
5133 return (gid == GROUPID_ALL) || (gid == actor.gid);
5134 }
5135
5136 forceinline bool
5137 Group::in(void) const {
5138 return (gid != GROUPID_ALL) && (gid != GROUPID_DEF);
5139 }
5140
5141 forceinline
5142 Group::Group(const Group& g) : gid(g.gid) {}
5143
5144 forceinline Group&
5146 gid=g.gid; return *this;
5147 }
5148
5149 forceinline unsigned int
5150 Group::id(void) const {
5151 return gid;
5152 }
5153
5154
5155 forceinline
5157
5158 forceinline
5161
5162 forceinline
5165
5166 forceinline PropagatorGroup&
5168 return static_cast<PropagatorGroup&>(Group::operator =(g));
5169 }
5170
5171 forceinline Home
5173 return Home(home,nullptr,*this,BrancherGroup::def);
5174 }
5175
5176 forceinline bool
5178 return id() == g.id();
5179 }
5180 forceinline bool
5182 return id() != g.id();
5183 }
5184
5185 forceinline PropagatorGroup&
5187 if (id() != GROUPID_ALL)
5188 p.group(*this);
5189 return *this;
5190 }
5191
5192
5193 forceinline
5195
5196 forceinline
5198 : Group(gid) {}
5199
5200 forceinline
5203
5204 forceinline BrancherGroup&
5206 return static_cast<BrancherGroup&>(Group::operator =(g));
5207 }
5208
5209 forceinline Home
5211 return Home(home,nullptr,PropagatorGroup::def,*this);
5212 }
5213
5214 forceinline bool
5216 return id() == g.id();
5217 }
5218 forceinline bool
5220 return id() != g.id();
5221 }
5222
5223 forceinline BrancherGroup&
5225 if (id() != GROUPID_ALL)
5226 p.group(*this);
5227 return *this;
5228 }
5229
5230
5231 /*
5232 * Iterators for propagators and branchers in a group
5233 *
5234 */
5235 forceinline
5237 : ps(const_cast<Space&>(home)), g(g0) {
5238 while (ps() && !g.in(ps.propagator().group()))
5239 ++ps;
5240 }
5241 forceinline bool
5243 return ps();
5244 }
5245 forceinline void
5247 do
5248 ++ps;
5249 while (ps() && !g.in(ps.propagator().group()));
5250 }
5251 forceinline const Propagator&
5253 return ps.propagator();
5254 }
5255
5256 forceinline
5258 : bs(const_cast<Space&>(home)), g(g0) {
5259 while (bs() && !g.in(bs.brancher().group()))
5260 ++bs;
5261 }
5262 forceinline bool
5264 return bs();
5265 }
5266 forceinline void
5268 do
5269 ++bs;
5270 while (bs() && !g.in(bs.brancher().group()));
5271 }
5272 forceinline const Brancher&
5274 return bs.brancher();
5275 }
5276
5277
5278 /*
5279 * Space construction support
5280 *
5281 */
5282 template<class T>
5283 forceinline T&
5285 return alloc<T>(1);
5286 }
5287 template<class T, typename A1>
5288 forceinline T&
5289 Space::construct(A1 const& a1) {
5290 T& t = *static_cast<T*>(ralloc(sizeof(T)));
5291 new (&t) T(a1);
5292 return t;
5293 }
5294 template<class T, typename A1, typename A2>
5295 forceinline T&
5296 Space::construct(A1 const& a1, A2 const& a2) {
5297 T& t = *static_cast<T*>(ralloc(sizeof(T)));
5298 new (&t) T(a1,a2);
5299 return t;
5300 }
5301 template<class T, typename A1, typename A2, typename A3>
5302 forceinline T&
5303 Space::construct(A1 const& a1, A2 const& a2, A3 const& a3) {
5304 T& t = *static_cast<T*>(ralloc(sizeof(T)));
5305 new (&t) T(a1,a2,a3);
5306 return t;
5307 }
5308 template<class T, typename A1, typename A2, typename A3, typename A4>
5309 forceinline T&
5310 Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) {
5311 T& t = *static_cast<T*>(ralloc(sizeof(T)));
5312 new (&t) T(a1,a2,a3,a4);
5313 return t;
5314 }
5315 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
5316 forceinline T&
5317 Space::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) {
5318 T& t = *static_cast<T*>(ralloc(sizeof(T)));
5319 new (&t) T(a1,a2,a3,a4,a5);
5320 return t;
5321 }
5322
5323}
5324
5325// STATISTICS: kernel-core
Class for AFC (accumulated failure count) management.
Definition afc.hpp:40
Base-class for both propagators and branchers.
Definition core.hpp:635
friend class Space
Definition core.hpp:637
friend class LocalObject
Definition core.hpp:641
virtual ~Actor(void)
To avoid warnings.
friend class ActorLink
Definition core.hpp:636
friend class VarImp
Definition core.hpp:642
friend class Advisor
Definition core.hpp:639
friend class Propagator
Definition core.hpp:638
friend class Brancher
Definition core.hpp:640
virtual Actor * copy(Space &home)=0
Create copy.
friend class Council
Definition core.hpp:643
virtual size_t dispose(Space &home)
Delete actor and return its size.
Definition core.hpp:3358
Base-class for advisors.
Definition core.hpp:1301
friend class SubscribedPropagators
Definition core.hpp:1305
Propagator & propagator(void) const
Return the advisor's propagator.
Definition core.hpp:3983
Advisor(Space &home, Propagator &p, Council< A > &c)
Constructor for creation.
Definition core.hpp:3952
friend class VarImp
Definition core.hpp:1302
void dispose(Space &home, Council< A > &c)
Dispose the advisor.
Definition core.hpp:3990
friend class Advisors
Definition core.hpp:1304
friend class Council
Definition core.hpp:1303
const ViewTraceInfo & operator()(const Space &home) const
Provide access to view trace information.
Definition core.hpp:4000
Class to iterate over advisors of a council.
Definition core.hpp:1275
Advisors(const Council< A > &c)
Initialize.
Definition core.hpp:4125
bool operator()(void) const
Test whether there advisors left.
Definition core.hpp:4133
void operator++(void)
Move iterator to next advisor.
Definition core.hpp:4139
A & advisor(void) const
Return advisor.
Definition core.hpp:4147
static const int idx_c
Index for cloning.
Definition var-type.hpp:467
static ModEventDelta med_combine(ModEventDelta med1, ModEventDelta med2)
Combine modification event delta med1 with med2.
Definition var-type.hpp:897
Archive representation
Definition archive.hpp:42
Group of branchers.
Definition core.hpp:806
unsigned int size(Space &home) const
Return number of branchers in a group.
static BrancherGroup def
Group of branchers not in any user-defined group.
Definition core.hpp:857
static BrancherGroup all
Group of all branchers.
Definition core.hpp:854
BrancherGroup & operator=(const BrancherGroup &g)
Assignment operator.
Definition core.hpp:5205
BrancherGroup & move(Space &home, BrancherGroup g)
Move branchers from group g to this group.
BrancherGroup(unsigned int gid)
Initialize with group id gid.
Definition core.hpp:5197
BrancherGroup & move(Space &home, unsigned int id)
Move brancher with id id to this group.
friend class Brancher
Definition core.hpp:807
Home operator()(Space &home)
To augment a space argument.
Definition core.hpp:5210
bool operator!=(BrancherGroup g) const
Test whether this group is different from group g.
Definition core.hpp:5219
void kill(Space &home)
Kill all branchers in a group.
bool operator==(BrancherGroup g) const
Test whether this group is equal to group g.
Definition core.hpp:5215
BrancherGroup(void)
Constructor.
Definition core.hpp:5194
Base-class for branchers.
Definition core.hpp:1453
virtual NGL * ngl(Space &home, const Choice &c, unsigned int a) const
Create no-good literal for choice c and alternative a.
virtual const Choice * choice(Space &home)=0
Return choice.
friend class Space
Definition core.hpp:1455
virtual ExecStatus commit(Space &home, const Choice &c, unsigned int a)=0
Commit for choice c and alternative a.
friend class ActorLink
Definition core.hpp:1454
unsigned int id(void) const
Return brancher id.
Definition core.hpp:3738
virtual void print(const Space &home, const Choice &c, unsigned int a, std::ostream &o) const
Print branch for choice c and alternative a.
virtual const Choice * choice(const Space &home, Archive &e)=0
Return choice from e.
BrancherGroup group(void) const
Return group brancher belongs to.
Definition core.hpp:3743
virtual bool status(const Space &home) const =0
Check status of brancher, return true if alternatives left.
Brancher(Home home)
Constructor for creation.
Definition core.hpp:3714
friend class Choice
Definition core.hpp:1456
void operator++(void)
Move iterator to next brancher.
Definition core.hpp:5267
const Brancher & brancher(void) const
Return propagator.
Definition core.hpp:5273
bool operator()(void) const
Test whether there are branchers left.
Definition core.hpp:5263
Branchers(const Space &home, BrancherGroup g)
Initialize.
Definition core.hpp:5257
Choice for performing commit
Definition core.hpp:1423
Choice(const Brancher &b, const unsigned int a)
Initialize for particular brancher b and alternatives a.
Definition core.hpp:3887
friend class Space
Definition core.hpp:1424
virtual void archive(Archive &e) const
Archive into e.
virtual ~Choice(void)
Destructor.
Definition core.hpp:3901
unsigned int alternatives(void) const
Return number of alternatives.
Definition core.hpp:3891
Statistics for execution of clone
Definition core.hpp:1742
CloneStatistics operator+(const CloneStatistics &s)
Return sum with s.
Definition core.hpp:4892
void reset(void)
Reset information.
Definition core.hpp:4885
CloneStatistics & operator+=(const CloneStatistics &s)
Increment by statistics s.
Definition core.hpp:4897
CloneStatistics(void)
Initialize.
Definition core.hpp:4888
Statistics for execution of commit
Definition core.hpp:1758
CommitStatistics & operator+=(const CommitStatistics &s)
Increment by statistics s.
Definition core.hpp:4914
void reset(void)
Reset information.
Definition core.hpp:4902
CommitStatistics operator+(const CommitStatistics &s)
Return sum with s.
Definition core.hpp:4909
CommitStatistics(void)
Initialize.
Definition core.hpp:4905
Commit trace information.
Definition core.hpp:1014
BrancherGroup group(void) const
Return brancher group.
Definition core.hpp:3521
friend class Space
Definition core.hpp:1015
unsigned int alternative(void) const
Return alternative.
Definition core.hpp:3533
const Brancher & b
Brancher.
Definition core.hpp:1018
CommitTraceInfo(const Brancher &b, const Choice &c, unsigned int a)
Initialize.
Definition core.hpp:3513
unsigned int id(void) const
Return brancher identifier.
Definition core.hpp:3517
unsigned int a
Alternative.
Definition core.hpp:1022
const Choice & c
Choice.
Definition core.hpp:1020
const Choice & choice(void) const
Return choice.
Definition core.hpp:3529
const Brancher & brancher(void) const
Return brancher.
Definition core.hpp:3525
Council of advisors
Definition core.hpp:1250
bool empty(void) const
Test whether council has advisor left.
Definition core.hpp:4042
void update(Space &home, Council< A > &c)
Update during cloning (copies all advisors).
Definition core.hpp:4052
void dispose(Space &home)
Dispose council.
Definition core.hpp:4108
friend class Advisor
Definition core.hpp:1251
Council(void)
Default constructor.
Definition core.hpp:4033
Generic domain change information to be supplied to advisors.
Definition core.hpp:209
friend class VarImp
Definition core.hpp:210
Base-class for freelist-managed objects.
Definition manager.hpp:100
Group baseclass for controlling actors.
Definition core.hpp:680
static Group all
Group of all actors.
Definition core.hpp:724
static Group def
Group of actors not in any user-defined group.
Definition core.hpp:727
static const unsigned int GROUPID_ALL
Fake id for group of all actors.
Definition core.hpp:690
Group(void)
Constructor.
bool in(void) const
Check whether this is a real group (and not just default).
Definition core.hpp:5137
friend class CommitTraceInfo
Definition core.hpp:686
static Support::Mutex m
Mutex for protection.
Definition core.hpp:702
friend class PostTraceInfo
Definition core.hpp:687
static const unsigned int GROUPID_MAX
The maximal group number.
Definition core.hpp:694
Group & operator=(const Group &g)
Assignment operator.
Definition core.hpp:5145
unsigned int id(void) const
Return a unique id for the group.
Definition core.hpp:5150
static const unsigned int GROUPID_DEF
Pre-defined default group id.
Definition core.hpp:692
unsigned int gid
The group id.
Definition core.hpp:696
friend class Propagator
Definition core.hpp:682
friend class Brancher
Definition core.hpp:683
static unsigned int next
Next group id.
Definition core.hpp:699
friend class PropagateTraceInfo
Definition core.hpp:685
Group(unsigned int gid0)
Construct with predefined group id gid0.
Definition core.hpp:5129
friend class Home
Definition core.hpp:681
friend class ViewTraceInfo
Definition core.hpp:684
Base class for heap allocated objects.
Definition heap.hpp:344
static T * copy(T *d, const T *s, long unsigned int n)
Copy n objects starting at s to d.
Definition heap.hpp:593
Home class for posting propagators
Definition core.hpp:863
PropagatorGroup pg
A propagator group.
Definition core.hpp:871
BrancherGroup branchergroup(void) const
Return brancher group.
Definition core.hpp:3416
Home(Space &s, Propagator *p=nullptr, PropagatorGroup pg=PropagatorGroup::def, BrancherGroup bg=BrancherGroup::def)
Initialize the home with space s and propagator p and group g.
Definition core.hpp:3368
void notice(Actor &a, ActorProperty p, bool duplicate=false)
Notice actor property.
Definition core.hpp:3301
Propagator * p
A propagator (possibly) that is currently being rewritten.
Definition core.hpp:869
Space & s
The space where the propagator is to be posted.
Definition core.hpp:867
void fail(void)
Mark space as failed.
Definition core.hpp:4176
BrancherGroup bg
A brancher group.
Definition core.hpp:873
Propagator * propagator(void) const
Return propagator (or nullptr) for currently rewritten propagator.
Definition core.hpp:3408
PropagatorGroup propagatorgroup(void) const
Return propagator group.
Definition core.hpp:3412
friend class PostInfo
Definition core.hpp:864
Home operator()(Propagator &p)
Return a home extended by propagator to be rewritten.
Definition core.hpp:3384
bool failed(void) const
Check whether corresponding space is failed.
Definition core.hpp:4185
Home & operator=(const Home &h)
Assignment operator.
Definition core.hpp:3375
Class for storing propagator information.
Definition gpi.hpp:42
unsigned int gid
Group identifier.
Definition gpi.hpp:47
Manage memory for space.
Definition manager.hpp:122
void * subscriptions(void) const
Get the memory area for subscriptions.
Definition manager.hpp:299
Class to store data shared among several spaces.
Handles for local (space-shared) objects.
Definition core.hpp:1569
LocalHandle(void)
Create local handle pointing to nullptr object.
Definition core.hpp:3860
~LocalHandle(void)
Destructor.
Definition core.hpp:3871
void update(Space &home, LocalHandle &lh)
Updating during cloning.
Definition core.hpp:3877
LocalHandle & operator=(const LocalHandle &lh)
Assignment operator.
Definition core.hpp:3866
LocalObject * object(void) const
Access to the local object.
Definition core.hpp:3873
Local (space-shared) object.
Definition core.hpp:1544
static LocalObject * cast(ActorLink *al)
Static cast for a non-null pointer (to give a hint to optimizer).
Definition core.hpp:3826
friend class Space
Definition core.hpp:1546
LocalObject * fwd(Space &home)
Return forwarding pointer.
Definition core.hpp:3853
friend class ActorLink
Definition core.hpp:1545
LocalObject(Home home)
Constructor for creation.
Definition core.hpp:3842
friend class LocalHandle
Definition core.hpp:1547
Information passed by meta search engines.
Definition core.hpp:1628
MetaInfo(unsigned long int r, RestartReason rr, unsigned long long int s, unsigned long long int f, const Space *l, NoGoods &ng)
Constructor for restart-based engine.
Definition core.hpp:3147
const NoGoods & nogoods(void) const
Return no-goods recorded from restart.
Definition core.hpp:3188
const unsigned long long int f
Number of failures since last restart.
Definition core.hpp:1662
Type
Which type of information is provided.
Definition core.hpp:1631
@ PORTFOLIO
Information is provided by a portfolio-based engine.
Definition core.hpp:1635
@ RESTART
Information is provided by a restart-based engine.
Definition core.hpp:1633
unsigned long long int fail(void) const
Return number of failures since last restart.
Definition core.hpp:3178
const RestartReason rr
Reason for restarting.
Definition core.hpp:1658
const Type t
Type of information.
Definition core.hpp:1652
unsigned int asset(void) const
Return number of asset in portfolio.
Definition core.hpp:3193
const Space * l
Last solution found.
Definition core.hpp:1664
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
const unsigned long int r
Number of restarts.
Definition core.hpp:1656
RestartReason reason(void) const
Return reason for restarting.
Definition core.hpp:3169
const unsigned long long int s
Number of solutions since last restart.
Definition core.hpp:1660
const unsigned int a
Number of asset in portfolio.
Definition core.hpp:1671
RestartReason
Reason for restarting.
Definition core.hpp:1638
@ RR_NO
No reason - used for PORTFOLIO.
Definition core.hpp:1640
@ 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
const NoGoods & ng
No-goods from restart.
Definition core.hpp:1666
Type type(void) const
Return type of information.
Definition core.hpp:3160
No-good literal recorded during search.
Definition core.hpp:1351
bool leaf(void) const
Test whether literal is a leaf.
Definition core.hpp:3910
virtual ExecStatus prune(Space &home)=0
Propagate the negation of the no-good literal.
virtual void cancel(Space &home, Propagator &p)=0
Cancel propagator p from all views of the no-good literal.
virtual void subscribe(Space &home, Propagator &p)=0
Subscribe propagator p to all views of the no-good literal.
virtual bool notice(void) const
Whether dispose must always be called (returns false).
virtual NGL::Status status(const Space &home) const =0
Test the status of the no-good literal.
NGL(void)
Constructor for creation.
Definition core.hpp:3933
virtual NGL * copy(Space &home)=0
Create copy.
Status
The status of a no-good literal.
Definition core.hpp:1357
@ SUBSUMED
The literal is subsumed.
Definition core.hpp:1359
@ FAILED
The literal is failed.
Definition core.hpp:1358
@ NONE
The literal is neither failed nor subsumed.
Definition core.hpp:1360
virtual void reschedule(Space &home, Propagator &p)=0
Schedule propagator p for all views of the no-good literal.
virtual ~NGL(void)
To avoid warnings.
NGL * next(void) const
Return pointer to next literal.
Definition core.hpp:3914
virtual size_t dispose(Space &home)
Dispose.
Definition core.hpp:3942
NGL * add(NGL *n, bool l)
Add node n and mark it as leaf l and return n.
Definition core.hpp:3926
No-goods recorded from restarts.
Definition core.hpp:1599
static NoGoods eng
Empty no-goods.
Definition core.hpp:1621
virtual ~NoGoods(void)
Destructor.
Definition core.hpp:3140
NoGoods(void)
Initialize.
Definition core.hpp:3121
std::atomic< unsigned long int > n
Number of no-goods.
Definition core.hpp:1602
unsigned long int ng(void) const
Return number of no-goods posted.
Definition core.hpp:3132
virtual void post(Space &home) const
Post no-goods.
NoGoods & operator=(const NoGoods &ng)
Assignment operator.
Definition core.hpp:3127
Configuration class for variable implementations without index structure.
Definition core.hpp:103
static bool med_update(ModEventDelta &med, ModEvent me)
Update modification even delta med by me, return true on change.
Definition core.hpp:130
static const int free_bits
Freely available bits.
Definition core.hpp:112
static const int idx_c
Index for update.
Definition core.hpp:106
static const int med_fst
Start of bits for modification event delta.
Definition core.hpp:114
static const int med_lst
End of bits for modification event delta.
Definition core.hpp:116
static const PropCond pc_max
Maximal propagation condition.
Definition core.hpp:110
static const int idx_d
Index for disposal.
Definition core.hpp:108
static Gecode::ModEvent me_combine(ModEvent me1, ModEvent me2)
Combine modification events me1 and me2.
Definition core.hpp:126
static const int med_mask
Bitmask for modification event delta.
Definition core.hpp:118
Class to set group information when a post function is executed.
Definition core.hpp:957
Space & h
The home space.
Definition core.hpp:961
friend class Space
Definition core.hpp:958
PostInfo(Home home)
Set information.
Definition core.hpp:3465
bool nested
Whether it is used nested.
Definition core.hpp:967
unsigned int pid
Next free propagator id.
Definition core.hpp:965
PropagatorGroup pg
The propagator group.
Definition core.hpp:963
~PostInfo(void)
Reset information.
Definition core.hpp:3473
Post trace information.
Definition core.hpp:1041
unsigned int propagators(void) const
Return number of posted propagators.
Definition core.hpp:3554
friend class Space
Definition core.hpp:1042
PropagatorGroup group(void) const
Return propagator group.
Definition core.hpp:3546
PropagatorGroup g
Propagator group.
Definition core.hpp:1053
Status
Post status.
Definition core.hpp:1046
@ SUBSUMED
Propagator not posted as already subsumed.
Definition core.hpp:1049
@ FAILED
Posting failed.
Definition core.hpp:1048
@ POSTED
Propagator was posted.
Definition core.hpp:1047
Status status(void) const
Return post status.
Definition core.hpp:3550
friend class PostInfo
Definition core.hpp:1043
PostTraceInfo(PropagatorGroup g, Status s, unsigned int n)
Initialize.
Definition core.hpp:3543
Status s
Status.
Definition core.hpp:1055
unsigned int n
Number of posted propagators.
Definition core.hpp:1057
Propagation cost.
Definition core.hpp:493
ActualCost ac
Actual cost.
Definition core.hpp:516
friend class Space
Definition core.hpp:494
static PropCost unary(PropCost::Mod m)
Single variable for modifier pcm.
Definition core.hpp:4989
static PropCost ternary(PropCost::Mod m)
Three variables for modifier pcm.
Definition core.hpp:4981
static PropCost record(void)
For recording information (no propagation allowed).
Definition core.hpp:4941
static PropCost crazy(PropCost::Mod m, unsigned int n)
Exponential complexity for modifier m and size measure n.
Definition core.hpp:4945
static PropCost quadratic(PropCost::Mod m, unsigned int n)
Quadratic complexity for modifier m and size measure n.
Definition core.hpp:4963
static PropCost linear(PropCost::Mod m, unsigned int n)
Linear complexity for modifier pcm and size measure n.
Definition core.hpp:4972
static PropCost cubic(PropCost::Mod m, unsigned int n)
Cubic complexity for modifier m and size measure n.
Definition core.hpp:4954
static PropCost binary(PropCost::Mod m)
Two variables for modifier pcm.
Definition core.hpp:4985
Mod
Propagation cost modifier.
Definition core.hpp:519
@ HI
Expensive.
Definition core.hpp:521
ActualCost
The actual cost values that are used.
Definition core.hpp:497
@ AC_TERNARY_LO
Three variables, cheap.
Definition core.hpp:509
@ AC_TERNARY_HI
Three variables, expensive.
Definition core.hpp:507
@ AC_BINARY_LO
Two variables, cheap.
Definition core.hpp:510
@ AC_CUBIC_LO
Cubic complexity, cheap.
Definition core.hpp:501
@ AC_UNARY_HI
Only single variable, expensive.
Definition core.hpp:512
@ AC_RECORD
Reserved for recording information.
Definition core.hpp:498
@ AC_BINARY_HI
Two variables, expensive.
Definition core.hpp:508
@ AC_LINEAR_HI
Linear complexity, expensive.
Definition core.hpp:505
@ AC_CUBIC_HI
Cubic complexity, expensive.
Definition core.hpp:502
@ AC_MAX
Maximal cost value.
Definition core.hpp:513
@ AC_CRAZY_LO
Exponential complexity, cheap.
Definition core.hpp:499
@ AC_LINEAR_LO
Linear complexity, cheap.
Definition core.hpp:506
@ AC_UNARY_LO
Only single variable, cheap.
Definition core.hpp:511
@ AC_QUADRATIC_LO
Quadratic complexity, cheap.
Definition core.hpp:503
@ AC_CRAZY_HI
Exponential complexity, expensive.
Definition core.hpp:500
@ AC_QUADRATIC_HI
Quadratic complexity, expensive.
Definition core.hpp:504
Propagate trace information.
Definition core.hpp:978
unsigned int i
Propagator id.
Definition core.hpp:990
Status
Propagator status.
Definition core.hpp:982
@ SUBSUMED
Propagator is subsumed.
Definition core.hpp:986
@ FIX
Propagator computed fixpoint.
Definition core.hpp:983
@ NOFIX
Propagator did not compute fixpoint.
Definition core.hpp:984
@ FAILED
Propagator failed.
Definition core.hpp:985
PropagateTraceInfo(unsigned int i, PropagatorGroup g, const Propagator *p, Status s)
Initialize.
Definition core.hpp:3487
const Propagator * propagator(void) const
Return pointer to non-subsumed propagator.
Definition core.hpp:3499
unsigned int id(void) const
Return propagator identifier.
Definition core.hpp:3491
Status status(void) const
Return propagator status.
Definition core.hpp:3503
const Propagator * p
Propagator.
Definition core.hpp:994
PropagatorGroup g
Propagator group.
Definition core.hpp:992
PropagatorGroup group(void) const
Return propagator group.
Definition core.hpp:3495
Group of propagators.
Definition core.hpp:734
unsigned int size(Space &home) const
Return number of propagators in a group.
bool operator==(PropagatorGroup g) const
Test whether this group is equal to group g.
Definition core.hpp:5177
static PropagatorGroup def
Group of propagators not in any user-defined group.
Definition core.hpp:799
PropagatorGroup & move(Space &home, PropagatorGroup g)
Move propagators from group g to this group.
friend class PostTraceInfo
Definition core.hpp:738
PropagatorGroup(unsigned int gid)
Initialize with group id gid.
Definition core.hpp:5159
bool operator!=(PropagatorGroup g) const
Test whether this group is different from group g.
Definition core.hpp:5181
PropagatorGroup(void)
Constructor.
Definition core.hpp:5156
PropagatorGroup & operator=(const PropagatorGroup &g)
Assignment operator.
Definition core.hpp:5167
friend class Propagator
Definition core.hpp:735
void disable(Space &home)
Disable all propagators in a group.
PropagatorGroup & move(Space &home, unsigned int id)
Move propagator with id id to this group.
void enable(Space &home, bool s=true)
Enable all propagators in a group.
Home operator()(Space &home)
To augment a space argument.
Definition core.hpp:5172
friend class PropagateTraceInfo
Definition core.hpp:737
void kill(Space &home)
Kill all propagators in a group.
friend class ViewTraceInfo
Definition core.hpp:736
static PropagatorGroup all
Group of all propagators.
Definition core.hpp:796
Base-class for propagators.
Definition core.hpp:1073
virtual void reschedule(Space &home)=0
Schedule function.
size_t size
The size of the propagator (used during subsumption).
Definition core.hpp:1086
friend class SubscribedPropagators
Definition core.hpp:1079
friend class Space
Definition core.hpp:1075
double afc(void) const
Return the accumulated failure count.
Definition core.hpp:3634
virtual PropCost cost(const Space &home, const ModEventDelta &med) const =0
Cost function.
friend class ActorLink
Definition core.hpp:1074
virtual void advise(Space &home, Advisor &a)
Run advisor a to be run on failure in failed space.
Kernel::GPI::Info & gpi(void)
Provide access to global propagator information.
Definition core.hpp:3602
unsigned int id(void) const
Return propagator id.
Definition core.hpp:3651
friend class VarImp
Definition core.hpp:1076
virtual ExecStatus advise(Space &home, Advisor &a, const Delta &d)
Advise function.
friend class Advisor
Definition core.hpp:1077
PropagatorGroup group(void) const
Return group propagator belongs to.
Definition core.hpp:3656
ModEventDelta modeventdelta(void) const
Return the modification event delta.
Definition core.hpp:3629
Propagator * fwd(void) const
Return forwarding pointer during copying.
Definition core.hpp:3580
friend class PropagatorGroup
Definition core.hpp:1080
friend class Council
Definition core.hpp:1078
bool disabled(void) const
Whether propagator is currently disabled.
Definition core.hpp:3585
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)=0
Propagation function.
ModEventDelta med
A set of modification events (used during propagation).
Definition core.hpp:1084
Propagator(Home home)
Constructor for posting.
Definition core.hpp:3607
Gecode::ActorLink * advisors
A list of advisors (used during cloning).
Definition core.hpp:1088
bool operator()(void) const
Test whether there are propagators left.
Definition core.hpp:5242
const Propagator & propagator(void) const
Return propagator.
Definition core.hpp:5252
void operator++(void)
Move iterator to next propagator.
Definition core.hpp:5246
Propagators(const Space &home, PropagatorGroup g)
Initialize.
Definition core.hpp:5236
Class to iterate over branchers of a space.
Definition core.hpp:2799
Brancher & brancher(void) const
Return propagator.
Definition core.hpp:5120
void operator++(void)
Move iterator to next brancher.
Definition core.hpp:5116
Branchers(Space &home)
Initialize.
Definition core.hpp:5109
bool operator()(void) const
Test whether there are branchers left.
Definition core.hpp:5112
void operator++(void)
Move iterator to next propagator.
Definition core.hpp:5099
Propagator & propagator(void) const
Return propagator.
Definition core.hpp:5103
bool operator()(void) const
Test whether there are propagators left.
Definition core.hpp:5095
IdlePropagators(Space &home)
Initialize.
Definition core.hpp:5090
Class to iterate over propagators of a space.
Definition core.hpp:2728
bool operator()(void) const
Test whether there are propagators left.
Definition core.hpp:5016
Propagators(Space &home)
Initialize.
Definition core.hpp:4998
void operator++(void)
Move iterator to next propagator.
Definition core.hpp:5020
Propagator & propagator(void) const
Return propagator.
Definition core.hpp:5044
ScheduledPropagators(Space &home)
Initialize.
Definition core.hpp:5050
Propagator & propagator(void) const
Return propagator.
Definition core.hpp:5084
bool operator()(void) const
Test whether there are propagators left.
Definition core.hpp:5062
void operator++(void)
Move iterator to next propagator.
Definition core.hpp:5066
Computation spaces.
Definition core.hpp:1775
T * realloc(T *b, long unsigned int n, long unsigned int m)
Reallocate block of n objects starting at b to m objects of type T from the space heap.
Definition core.hpp:2952
Space * source
Source space during clone construction.
Definition core.hpp:1887
friend void trace(Home home, TraceFilter tf, int te, Tracer &t)
Create tracer.
struct Gecode::Space::@055132133326276162005044145100211202071356247106::@275070317317120154232063063134255170030071110047 p
Data only available during propagation or branching.
void * ralloc(size_t s)
Allocate memory on space heap.
Definition core.hpp:2863
double afc_decay(void) const
Return AFC decay factor.
Definition core.hpp:3348
struct Gecode::Space::@055132133326276162005044145100211202071356247106::@155123175027073262103111264343315000271204104107 c
Data available only during copying.
void afc_unshare(void)
Unshare AFC information for all propagators.
T & construct(void)
Construction routines.
Definition core.hpp:5284
friend class LocalObject
Definition core.hpp:1787
ActorLink queue[PropCost::AC_MAX+1]
Scheduled propagators according to cost.
Definition core.hpp:1865
LocalObject * local
Linked list of local objects.
Definition core.hpp:1885
void * rrealloc(void *b, size_t n, size_t m)
Reallocate memory block starting at b from size n to size s.
Definition core.hpp:2871
friend class VarImpDisposer
Definition core.hpp:1786
void rfree(void *p, size_t s)
Free memory previously allocated with alloc (might be reused later).
Definition core.hpp:2867
VarImpBase * vars_noidx
Keep variables during copying without index structure.
Definition core.hpp:1883
void * fl_alloc(void)
Allocate from freelist-managed memory.
Definition core.hpp:2886
friend class AFC
Definition core.hpp:1789
VarImpBase * vars_u[AllVarConf::idx_c]
Entries for updating variables.
Definition core.hpp:1881
friend class VarImp
Definition core.hpp:1785
friend class Advisor
Definition core.hpp:1783
friend class PostInfo
Definition core.hpp:1790
void afc_decay(double d)
Set AFC decay factor to d
Definition core.hpp:3353
friend class Propagator
Definition core.hpp:1777
void fl_dispose(FreeList *f, FreeList *l)
Return freelist-managed memory to freelist.
Definition core.hpp:2891
unsigned int n_sub
Number of subscriptions.
Definition core.hpp:1874
friend class PropagatorGroup
Definition core.hpp:1778
friend class Region
Definition core.hpp:1788
friend class Brancher
Definition core.hpp:1780
friend class Council
Definition core.hpp:1784
T * alloc(long unsigned int n)
Allocate block of n objects of type T from space heap.
Definition core.hpp:2901
unsigned int bid_sc
Id of next brancher to be created plus status control.
Definition core.hpp:1872
friend class BrancherGroup
Definition core.hpp:1781
ActorLink * active
Cost level with next propagator to be executed.
Definition core.hpp:1863
void free(T *b, long unsigned int n)
Delete n objects allocated from space heap starting at b.
Definition core.hpp:2927
ViewTraceInfo vti
View trace information.
Definition core.hpp:1876
friend class Actor
Definition core.hpp:1776
Home operator()(Propagator &p)
Return a home for this space with the information that p is being rewritten.
Definition core.hpp:3396
SpaceStatus status(void)
Query space status without collecting statistics.
Definition core.hpp:3306
Statistics for execution of status
Definition core.hpp:1724
void reset(void)
Reset information.
Definition core.hpp:4866
StatusStatistics(void)
Initialize.
Definition core.hpp:4870
unsigned long long int propagate
Number of propagator executions.
Definition core.hpp:1727
StatusStatistics operator+(const StatusStatistics &s)
Return sum with s.
Definition core.hpp:4879
StatusStatistics & operator+=(const StatusStatistics &s)
Increment by statistics s.
Definition core.hpp:4874
Iterator over subscribed propagators.
A mutex for mutual exclausion among several threads.
Definition thread.hpp:78
Exception: too many branchers
Definition exception.hpp:93
Trace filters.
Definition filter.hpp:133
Propagator for recording trace information.
Definition recorder.hpp:154
Base-class for variable implementations.
Definition core.hpp:177
Base class for Variable type disposer.
Definition core.hpp:185
virtual void dispose(Space &home, VarImpBase *x)
Dispose list of variable implementations starting at x.
virtual ~VarImpDisposerBase(void)
Destructor (not used).
VarImpDisposer(void)
Constructor (registers disposer with kernel).
Definition core.hpp:4846
virtual void dispose(Space &home, VarImpBase *x)
Dispose list of variable implementations starting at x.
Definition core.hpp:4854
Base-class for variable implementations.
Definition core.hpp:224
void subscribe(Space &home, Propagator &p, PropCond pc, bool assigned, ModEvent me, bool schedule)
Subscribe propagator p with propagation condition pc.
Definition core.hpp:4531
ModEvent fail(Space &home)
Run advisors to be run on failure and returns ME_GEN_FAILED.
Definition core.hpp:4721
void cancel(Space &home)
Cancel all subscriptions when variable implementation is assigned.
Definition core.hpp:4638
bool advise(Space &home, ModEvent me, Delta &d)
Run advisors when variable implementation has been modified with modification event me and domain cha...
Definition core.hpp:4655
VarImp(void)
Creation of static instances.
Definition core.hpp:4282
friend class SubscribedPropagators
Definition core.hpp:228
friend class Space
Definition core.hpp:225
double afc(void) const
Return accumulated failure count (plus degree).
Definition core.hpp:4310
unsigned int bits(void) const
Provide access to free bits.
Definition core.hpp:4341
ActorLink ** base
Subscribed actors.
Definition core.hpp:238
bool copied(void) const
Is variable already copied.
Definition core.hpp:4367
friend class VarImpDisposer
Definition core.hpp:227
static void reschedule(Space &home, Propagator &p, PropCond pc, bool assigned, ModEvent me)
Schedule propagator p.
Definition core.hpp:4557
static void schedule(Space &home, Propagator &p, ModEvent me, bool force=false)
Definition core.hpp:4433
unsigned int idx[pc_max+1]
Indices of subscribed actors.
Definition core.hpp:278
VarImp * forward(void) const
Use forward pointer if variable already copied.
Definition core.hpp:4373
static ModEvent me(const ModEventDelta &med)
Definition core.hpp:4415
VarImp * next(void) const
Return next copied variable.
static ModEvent me_combine(ModEvent me1, ModEvent me2)
Combine modifications events me1 and me2.
Definition core.hpp:4427
friend class Propagator
Definition core.hpp:226
unsigned int degree(void) const
Return degree (number of subscribed propagators and advisors).
Definition core.hpp:4303
VarImp(Space &home)
Creation.
Definition core.hpp:4266
static ModEventDelta med(ModEvent me)
Definition core.hpp:4421
VarImp< VIC > * fwd
Forwarding pointer.
Definition core.hpp:247
VarImp< VIC > * next
During cloning, points to the next copied variable.
Definition core.hpp:280
static ModEvent modevent(const Delta &d)
Return modification event.
Definition core.hpp:4335
View trace information.
Definition core.hpp:917
What what(void) const
Return what is currently executing.
Definition core.hpp:3441
friend class Space
Definition core.hpp:918
const Brancher & brancher(void) const
Return currently executing brancher.
Definition core.hpp:3451
const Propagator & propagator(void) const
Return currently executing propagator.
Definition core.hpp:3445
void other(void)
Record that nothing is known at this point.
Definition core.hpp:3437
friend class PostInfo
Definition core.hpp:919
What
What is currently executing.
Definition core.hpp:922
@ BRANCHER
A brancher is executing.
Definition core.hpp:926
@ POST
A post function is executing.
Definition core.hpp:928
@ PROPAGATOR
A propagator is currently executing.
Definition core.hpp:924
PropagatorGroup post(void) const
Return propagator group of currently executing post function.
Definition core.hpp:3456
ptrdiff_t who
Encoding a tagged pointer or a tagged group id.
Definition core.hpp:934
#define GECODE_KERNEL_REALLOC(T)
Definition core.hpp:2987
ExecStatus ES_NOFIX_PARTIAL(Propagator &p, const ModEventDelta &med)
Propagator p has not computed partial fixpoint
Definition core.hpp:3685
ExecStatus ES_FIX_PARTIAL(Propagator &p, const ModEventDelta &med)
Propagator p has computed partial fixpoint
Definition core.hpp:3678
ExecStatus ES_SUBSUMED_DISPOSED(Propagator &p, size_t s)
Propagator p is subsumed
Definition core.hpp:3666
ExecStatus ES_FIX_DISPOSE(Council< A > &c, A &a)
Advisor a must be disposed
Definition core.hpp:4006
ExecStatus ES_NOFIX_DISPOSE_FORCE(Council< A > &c, A &a)
Advisor a must be disposed and its propagator must be forcefully rescheduled
Definition core.hpp:4020
ExecStatus ES_NOFIX_DISPOSE(Council< A > &c, A &a)
Advisor a must be disposed and its propagator must be run
Definition core.hpp:4013
ExecStatus ES_SUBSUMED(Propagator &p)
Propagator p is subsumed
Definition core.hpp:3672
void ignore(Actor &a, ActorProperty p, bool duplicate=false)
Ignore actor property.
Definition core.hpp:4213
int ModEventDelta
Modification event deltas.
Definition core.hpp:94
bool failed(void) const
Check whether space is failed.
Definition core.hpp:4181
ActorProperty
Actor properties.
Definition core.hpp:560
void notice(Actor &a, ActorProperty p, bool duplicate=false)
Notice actor property.
Definition core.hpp:4196
bool stable(void) const
Return if space is stable (at fixpoint or failed).
Definition core.hpp:4190
void fail(void)
Fail space.
Definition core.hpp:4167
@ AP_VIEW_TRACE
Definition core.hpp:580
@ AP_DISPOSE
Actor must always be disposed.
Definition core.hpp:569
@ AP_TRACE
Definition core.hpp:585
@ AP_WEAKLY
Definition core.hpp:575
virtual ~Space(void)
Destructor.
Space(void)
Default constructor.
virtual bool slave(const MetaInfo &mi)
Slave configuration function for meta search engines.
virtual bool master(const MetaInfo &mi)
Master configuration function for meta search engines.
virtual void constrain(const Space &best)
Constrain function for best solution search.
Space(Space &s)
Constructor for cloning.
virtual Space * copy(void)=0
Copying member function.
const Choice * choice(Archive &e) const
Create new choice from e.
void print(const Choice &c, unsigned int a, std::ostream &o) const
Print branch for choice c and alternative a.
Space * clone(void) const
Clone space.
Definition core.hpp:3312
const Choice * choice(void)
Create new choice for current brancher.
SpaceStatus status(StatusStatistics &stat)
Query space status.
NGL * ngl(const Choice &c, unsigned int a)
Create no-good literal for choice c and alternative a.
void trycommit(const Choice &c, unsigned int a)
If possible, commit choice c for alternative a.
Definition core.hpp:3337
void commit(const Choice &c, unsigned int a)
Commit choice c for alternative a.
Definition core.hpp:3326
SpaceStatus
Space status
Definition core.hpp:1714
@ SS_BRANCH
Space must be branched (at least one brancher left)
Definition core.hpp:1717
@ SS_SOLVED
Space is solved (no brancher left)
Definition core.hpp:1716
@ SS_FAILED
Space is failed
Definition core.hpp:1715
#define GECODE_KERNEL_EXPORT
Definition kernel.hh:70
void * ptrjoin(void *p, ptrdiff_t m)
Join unmarked pointer p and m into marked pointer.
void * ptrsplit(void *p, ptrdiff_t &m)
Split possibly marked pointer p into mark m and unmarked pointer.
void * unmark(void *p)
Return unmarked pointer for a marked pointer p.
void * fmark(void *p)
Return marked pointer for p (possibly already marked).
void * funmark(void *p)
Return unmarked pointer for a possibly marked pointer p.
void * mark(void *p)
Return marked pointer for unmarked pointer p.
bool marked(void *p)
Check whether p is marked.
Gecode toplevel namespace
const PropCond PC_GEN_ASSIGNED
Propagation condition for an assigned variable.
Definition core.hpp:81
const ModEvent ME_GEN_NONE
Generic modification event: no modification.
Definition core.hpp:72
TFE propagator(PropagatorGroup g)
Only propagators (but not post functions) from g are considered.
ExecStatus
Definition core.hpp:479
@ ES_OK
Execution is okay.
Definition core.hpp:483
@ ES_FIX
Propagation has computed fixpoint.
Definition core.hpp:484
@ ES_SUBSUMED_
Internal: propagator is subsumed, do not use.
Definition core.hpp:480
@ ES_NOFIX_FORCE
Advisor forces rescheduling of propagator.
Definition core.hpp:485
@ ES_FAILED
Execution has resulted in failure.
Definition core.hpp:481
@ ES_PARTIAL_
Internal: propagator has computed partial fixpoint, do not use.
Definition core.hpp:486
@ ES_NOFIX
Propagation has not computed fixpoint.
Definition core.hpp:482
const ModEvent ME_GEN_FAILED
Generic modification event: failed variable.
Definition core.hpp:70
int PropCond
Type for propagation conditions.
Definition core.hpp:77
const ModEvent ME_GEN_ASSIGNED
Generic modification event: variable is assigned a value.
Definition core.hpp:74
const PropCond PC_GEN_NONE
Propagation condition to be ignored (convenience).
Definition core.hpp:79
int ModEvent
Type for modification events.
Definition core.hpp:67
const int * pi[]
Definition photo.cpp:14262
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56
#define GECODE_NOT_NULL(p)
Assert that a pointer is never nullptr.
Definition macros.hpp:75
#define GECODE_VTABLE_EXPORT
Definition support.hh:76