63 Actor* Actor::sentinel;
104 std::ostream&)
const {
117#ifdef GECODE_HAS_VAR_DISPOSE
125#ifdef GECODE_HAS_VAR_DISPOSE
127 _vars_d[i] =
nullptr;
132 b_status = b_commit = Brancher::cast(&bl);
134 d_fst = d_cur = d_lst =
nullptr;
136 pc.p.active = &pc.p.queue[0]-1;
139 pc.p.queue[i].init();
140 pc.p.bid_sc = (reserved_bid+1) << sc_bits;
146 Space::ap_notice_dispose(
Actor* a,
bool duplicate) {
148 if (duplicate && (d_fst !=
nullptr)) {
149 for (
Actor** f = d_fst; f < d_cur; f++)
153 if (d_cur == d_lst) {
155 if (d_fst ==
nullptr) {
158#ifdef GECODE_HAS_FAULT_INJECTION
169 unsigned int n =
static_cast<unsigned int>(d_lst - d_fst);
172#ifdef GECODE_HAS_FAULT_INJECTION
187 Space::ap_ignore_dispose(
Actor* a,
bool duplicate) {
189 if (is_partial_clone())
192 assert(d_fst !=
nullptr);
210 if (is_partial_clone()) {
211 if (pc.c.source !=
nullptr) {
212 recover(*pc.c.source);
213 pc.c.source =
nullptr;
215 d_fst = d_cur = d_lst =
nullptr;
228 (void) (*a)->dispose(*
this);
232#ifdef GECODE_HAS_VAR_DISPOSE
235 if (_vars_d[i] !=
nullptr)
236 vd[i]->dispose(*
this, _vars_d[i]);
239 mm.release(ssd.data().sm);
250 Space::findtracerecorder(
void) {
251 for (
Actor** a=d_fst; a<d_cur; a++) {
255 std::swap(*d_fst,*a);
264 assert(pc.p.bid_sc & sc_trace);
265 TraceRecorder* tr = findtracerecorder();
266 if ((tr !=
nullptr) && (tr->events() &
TE_POST)) {
268 unsigned int n = ssd.data().gpi.pid() -
pi.pid;
276 PostTraceInfo pti(
pi.pg,s,n);
277 tr->tracer()._post(*
this,pti);
289 if (pc.p.active >= &pc.p.queue[0]) {
291 if ((pc.p.bid_sc & ((1 << sc_bits) - 1)) == 0) {
301 switch (
p->propagate(*
this,med_o)) {
310 assert(pc.p.active >= &pc.p.queue[0]);
313 if (pc.p.active != fst) {
314 p = Propagator::cast(fst);
326 p->unlink(); pl.head(
p);
327 f_stable_or_unstable:
330 assert(pc.p.active >= &pc.p.queue[0]);
333 if (pc.p.active != fst) {
334 p = Propagator::cast(fst);
337 }
while (--pc.p.active >= &pc.p.queue[0]);
338 assert(pc.p.active < &pc.p.queue[0]);
342 goto f_stable_or_unstable;
345 assert(
p->u.med != 0);
352 }
else if ((pc.p.bid_sc & ((1 << sc_bits) - 1)) == sc_disabled) {
358 goto d_put_into_idle;
363 switch (
p->propagate(*
this,med_o)) {
372 assert(pc.p.active >= &pc.p.queue[0]);
375 if (pc.p.active != fst) {
376 p = Propagator::cast(fst);
389 p->unlink(); pl.head(
p);
390 d_stable_or_unstable:
393 assert(pc.p.active >= &pc.p.queue[0]);
396 if (pc.p.active != fst) {
397 p = Propagator::cast(fst);
400 }
while (--pc.p.active >= &pc.p.queue[0]);
401 assert(pc.p.active < &pc.p.queue[0]);
405 goto d_stable_or_unstable;
408 assert(
p->u.med != 0);
418#define GECODE_STATUS_TRACE(q,s) \
419 if ((tr != nullptr) && (tr->events() & TE_PROPAGATE) && \
420 (tr->filter()(p->group()))) { \
421 PropagateTraceInfo pti(p->id(),p->group(),q, \
422 PropagateTraceInfo::s); \
423 tr->tracer()._propagate(*this,pti); \
435 goto t_put_into_idle;
436 pc.p.vti.propagator(*
p);
441 switch (
p->propagate(*
this,med_o)) {
452 assert(pc.p.active >= &pc.p.queue[0]);
455 if (pc.p.active != fst) {
456 p = Propagator::cast(fst);
470 p->unlink(); pl.head(
p);
471 t_stable_or_unstable:
474 assert(pc.p.active >= &pc.p.queue[0]);
477 if (pc.p.active != fst) {
478 p = Propagator::cast(fst);
481 }
while (--pc.p.active >= &pc.p.queue[0]);
482 assert(pc.p.active < &pc.p.queue[0]);
487 goto t_stable_or_unstable;
491 assert(
p->u.med != 0);
501#undef GECODE_STATUS_TRACE
529 while (b_status != Brancher::cast(&bl))
530 if (b_status->status(*
this)) {
535 b_status = Brancher::cast(b_status->next());
543 ssd.data().gpi.fail(
p->gpi());
554 switch (top->
propagate(*
this,top_med_o)) {
571 if (
failed() || (b_status == Brancher::cast(&bl))) {
574 Brancher* b = Brancher::cast(bl.next());
575 while (b != Brancher::cast(&bl)) {
577 b = Brancher::cast(b->next());
578 rfree(d,d->dispose(*
this));
581 b_status = b_commit = Brancher::cast(&bl);
588 Brancher* b = Brancher::cast(bl.next());
589 while (b != b_status) {
591 b = Brancher::cast(b->next());
593 rfree(d,d->dispose(*
this));
597 return b_status->choice(*
this);
602 unsigned int id; e >> id;
603 Brancher* b_cur = Brancher::cast(bl.next());
604 while (b_cur != Brancher::cast(&bl)) {
605 if (
id == b_cur->
id())
606 return b_cur->
choice(*
this,e);
607 b_cur = Brancher::cast(b_cur->next());
613 Space::_commit(
const Choice& c,
unsigned int a) {
614 if (a >=
c.alternatives())
620 if (pc.p.bid_sc & sc_trace) {
623 tr->
filter()(b->group())) {
625 tr->
tracer()._commit(*
this,cti);
627 ViewTraceInfo
vti = pc.p.vti;
628 pc.p.vti.brancher(*b);
639 throw SpaceNoBrancher(
"Space::commit");
644 Space::_trycommit(
const Choice& c,
unsigned int a) {
645 if (a >=
c.alternatives())
646 throw SpaceIllegalAlternative(
"Space::commit");
651 if (pc.p.bid_sc & sc_trace) {
652 TraceRecorder* tr = findtracerecorder();
653 if ((tr !=
nullptr) && (tr->events() &
TE_COMMIT) &&
654 tr->filter()(
b->group())) {
655 CommitTraceInfo cti(*b,
c,a);
656 tr->tracer()._commit(*
this,cti);
658 ViewTraceInfo
vti = pc.p.vti;
659 pc.p.vti.brancher(*b);
673 if (a >=
c.alternatives())
679 return b->ngl(*
this,
c,a);
687 if (a >=
c.alternatives())
693 b->print(*
this,
c,a,o);
701 Space::kill_brancher(
unsigned int id) {
705 b != Brancher::cast(&bl); b = Brancher::cast(b->next()))
728 var_id_counter(s.var_id_counter),
730 d_fst(&
Actor::sentinel),d_cur(nullptr),d_lst(nullptr) {
731#ifdef GECODE_HAS_VAR_DISPOSE
733 _vars_d[i] =
nullptr;
737 pc.c.vars_u[i] =
nullptr;
738 pc.c.vars_noidx =
nullptr;
739 pc.c.local =
nullptr;
743 b_status = b_commit = Brancher::cast(&bl);
749 Actor*
c = Actor::cast(a)->copy(*
this);
757 p->next(&pl); pl.prev(
p);
764 Actor*
c = Actor::cast(a)->copy(*
this);
772 p->next(&bl); bl.prev(
p);
775 if (s.b_status == &s.bl) {
776 b_status = Brancher::cast(&bl);
778 b_status = Brancher::cast(s.b_status->prev());
780 if (s.b_commit == &s.bl) {
781 b_commit = Brancher::cast(&bl);
783 b_commit = Brancher::cast(s.b_commit->prev());
787 pc.c.source =
nullptr;
788 mm.release(ssd.data().sm);
794 Space::_clone(
void) {
803 if (
c->d_fst != &Actor::sentinel)
808 unsigned int n =
static_cast<unsigned int>(d_cur - d_fst);
811 c->d_fst =
c->d_cur =
c->d_lst =
nullptr;
815#ifdef GECODE_HAS_FAULT_INJECTION
818 c->d_fst =
c->alloc<
Actor*>(n+1);
820 c->d_lst =
c->d_fst+n+1;
821 for (
Actor** d_fst_iter = d_fst; d_fst_iter != d_cur; d_fst_iter++) {
825 *(
c->d_cur++) = Actor::cast(
static_cast<ActorLink*
>
831 c->d_fst =
c->d_cur =
c->d_lst =
nullptr;
841 while (x !=
nullptr) {
843 x->b.base =
nullptr; x->u.idx[0] = 0;
844 if (
sizeof(ActorLink**) >
sizeof(
unsigned int))
845 *(1+&x->u.idx[0]) = 0;
849 c->update(
static_cast<ActorLink**
>(
c->mm.subscriptions()));
853 ActorLink* p_a = &pl;
854 ActorLink* c_a = p_a->next();
858 if (
p->u.advisors !=
nullptr) {
859 ActorLink*
a =
p->u.advisors;
860 p->u.advisors =
nullptr;
862 a->prev(
p);
a =
a->next();
863 }
while (a !=
nullptr);
865 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
869 ActorLink* p_a = &bl;
870 ActorLink* c_a = p_a->next();
873 c_a->prev(p_a); p_a = c_a; c_a = c_a->next();
878 for (ActorLink* l =
c->pc.c.local; l !=
nullptr; l = l->next())
882 c->pc.p.active = &
c->pc.p.queue[0]-1;
884 c->pc.p.queue[i].init();
886 c->pc.p.n_sub = pc.p.n_sub;
887 c->pc.p.bid_sc = pc.p.bid_sc;
890 c->pc.p.vti.other(); pc.p.vti.other();
903 if (mi.
last() !=
nullptr)
925 if (ssd.data().gpi.unshare()) {
929 = ssd.data().gpi.allocate(
p.gpi().pid,
p.gpi().gid);
933 p.gpi_disabled = gpi;
939 LocalObject::fwdcopy(
Space& home) {
990 if (g.
in(ps.propagator().group()))
991 ps.propagator().group(*
this);
1000 if (ps.propagator().id() == pid) {
1001 ps.propagator().group(*
this);
1015 if (
in(ps.propagator().group()))
1038 if (
in(ps.propagator().group()))
1039 ps.propagator().disable(home);
1058 if (
in(ps.propagator().group()))
1059 ps.propagator().enable(home);
1068 if (g.
in(bs.brancher().group()))
1069 bs.brancher().group(*
this);
1078 if (bs.brancher().id() == bid) {
1079 bs.brancher().group(*
this);
1093 if (
in(bs.brancher().group()))
Double-linked list for actors.
ActorLink * next(void) const
ActorLink * prev(void) const
Routines for double-linked list.
static ActorLink * cast(T *a)
Static cast for a non-null pointer (to give a hint to optimizer).
Base-class for both propagators and branchers.
virtual ~Actor(void)
To avoid warnings.
virtual Actor * copy(Space &home)=0
Create copy.
static const int idx_d
Index for dispose.
static const int idx_c
Index for cloning.
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.
static BrancherGroup all
Group of all branchers.
BrancherGroup & move(Space &home, BrancherGroup g)
Move branchers from group g to this group.
BrancherGroup(unsigned int gid)
Initialize with group id gid.
void kill(Space &home)
Kill all branchers in a group.
Base-class for branchers.
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(Space &home)=0
Return choice.
unsigned int id(void) const
Return brancher id.
virtual NGL * ngl(Space &home, const Choice &c, unsigned int a) const
Create no-good literal for choice c and alternative a.
Choice for performing commit
virtual void archive(Archive &e) const
Archive into e.
Statistics for execution of clone
Statistics for execution of commit
Commit trace information.
Generic domain change information to be supplied to advisors.
Group baseclass for controlling actors.
static Group all
Group of all actors.
static Group def
Group of actors not in any user-defined group.
static const unsigned int GROUPID_ALL
Fake id for group of all actors.
bool in(void) const
Check whether this is a real group (and not just default).
static Support::Mutex m
Mutex for protection.
static const unsigned int GROUPID_MAX
The maximal group number.
unsigned int id(void) const
Return a unique id for the group.
unsigned int gid
The group id.
bool in(Group a) const
Check whether actor group a is included in this group.
static unsigned int next
Next group id.
Class for storing propagator information.
No-good literal recorded during search.
virtual ~NGL(void)
To avoid warnings.
virtual bool notice(void) const
Whether dispose must always be called (returns false).
No-goods recorded from restarts.
virtual void post(Space &home) const
Post no-goods.
static NoGoods eng
Empty no-goods.
Class to set group information when a post function is executed.
@ SUBSUMED
Propagator not posted as already subsumed.
@ POSTED
Propagator was posted.
@ AC_RECORD
Reserved for recording information.
@ AC_MAX
Maximal cost value.
unsigned int size(Space &home) const
Return number of propagators in a group.
static PropagatorGroup def
Group of propagators not in any user-defined group.
PropagatorGroup & move(Space &home, PropagatorGroup g)
Move propagators from group g to this group.
PropagatorGroup(unsigned int gid)
Initialize with group id gid.
void disable(Space &home)
Disable all propagators in a group.
void enable(Space &home, bool s=true)
Enable all propagators in a group.
void kill(Space &home)
Kill all propagators in a group.
static PropagatorGroup all
Group of all propagators.
Base-class for propagators.
virtual void reschedule(Space &home)=0
Schedule function.
virtual ExecStatus advise(Space &home, Advisor &a, const Delta &d)
Advise function.
PropagatorGroup group(void) const
Return group propagator belongs to.
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)=0
Propagation function.
ModEventDelta med
A set of modification events (used during propagation).
Exception: Operation on failed space invoked
Exception: Commit with illegal alternative
Exception: Commit when no brancher present
Exception: Copy constructor did not call base class copy constructor
Exception: Operation on not stable space invoked
Class to iterate over branchers of a space.
Brancher & brancher(void) const
Return propagator.
Class to iterate over propagators of a space.
Propagator & propagator(void) const
Return propagator.
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.
struct Gecode::Space::@055132133326276162005044145100211202071356247106::@275070317317120154232063063134255170030071110047 p
Data only available during propagation or branching.
struct Gecode::Space::@055132133326276162005044145100211202071356247106::@155123175027073262103111264343315000271204104107 c
Data available only during copying.
void afc_unshare(void)
Unshare AFC information for all propagators.
LocalObject * local
Linked list of local objects.
void rfree(void *p, size_t s)
Free memory previously allocated with alloc (might be reused later).
unsigned int n_sub
Number of subscriptions.
T * alloc(long unsigned int n)
Allocate block of n objects of type T from space heap.
ViewTraceInfo vti
View trace information.
SpaceStatus status(void)
Query space status without collecting statistics.
Statistics for execution of status
unsigned long long int propagate
Number of propagator executions.
A lock as a scoped frontend for a mutex.
A mutex for mutual exclausion among several threads.
Exception: too many groups
Propagator for recording trace information.
int events(void) const
Which events to trace.
const TraceFilter & filter(void) const
Return trace filter.
Tracer & tracer(void) const
Return tracer.
Exception: unknown brancher
Exception: unknown propagator
Base-class for variable implementations.
Base class for Variable type disposer.
virtual void dispose(Space &home, VarImpBase *x)
Dispose list of variable implementations starting at x.
virtual ~VarImpDisposerBase(void)
Destructor (not used).
#define GECODE_STATUS_TRACE(q, s)
int ModEventDelta
Modification event deltas.
bool failed(void) const
Check whether space is failed.
bool stable(void) const
Return if space is stable (at fixpoint or failed).
void fail(void)
Fail space.
Space(void)
Default constructor.
virtual ~Space(void)
Destructor.
virtual bool slave(const MetaInfo &mi)
Slave configuration function for meta search engines.
virtual void constrain(const Space &best)
Constrain function for best solution search.
virtual bool master(const MetaInfo &mi)
Master configuration function for meta search engines.
virtual Space * copy(void)=0
Copying member function.
void print(const Choice &c, unsigned int a, std::ostream &o) const
Print branch for choice c and alternative a.
const Choice * choice(void)
Create new choice for current brancher.
NGL * ngl(const Choice &c, unsigned int a)
Create no-good literal for choice c and alternative a.
@ SS_BRANCH
Space must be branched (at least one brancher left)
@ SS_SOLVED
Space is solved (no brancher left)
@ SS_FAILED
Space is failed
@ TE_POST
Trace propagator posting.
@ TE_COMMIT
Trace commit operations by branchers.
@ SpaceDisposeNoticeArray
void check(Phase p)
Check failpoint for phase p.
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 * mark(void *p)
Return marked pointer for unmarked pointer p.
bool marked(void *p)
Check whether p is marked.
Gecode toplevel namespace
@ ES_FIX
Propagation has computed fixpoint.
@ ES_SUBSUMED_
Internal: propagator is subsumed, do not use.
@ ES_FAILED
Execution has resulted in failure.
@ ES_PARTIAL_
Internal: propagator has computed partial fixpoint, do not use.
@ ES_NOFIX
Propagation has not computed fixpoint.
Gecode::FloatVal b(9, 12)
Gecode::FloatVal a(-8, 5)
Gecode::IntArgs i({1, 2, 3, 4})
#define GECODE_NEVER
Assert that this command is never executed.
#define GECODE_ASSUME(p)
Assert certain property.