155 template<
class A>
class Council;
157 template<
class VIC>
class VarImp;
194 template<
class VarImp>
246 static const int idx_c = VIC::idx_c;
248 static const int idx_d = VIC::idx_d;
250 static const int free_bits = VIC::free_bits;
252 unsigned int entries;
254 unsigned int free_and_bits;
259 const unsigned var_id;
273 unsigned int idx[pc_max+1];
307 void resize(
Space& home);
325 void _fail(
Space& home);
329#ifdef GECODE_HAS_VAR_DISPOSE
344 unsigned int id(
void)
const;
444 unsigned int&
bits(
void);
455 static void*
operator new(size_t,
Space&);
457 static void operator delete(
void*,
Space&);
459 static void operator delete(
void*);
616 bool empty(
void)
const;
654 static void*
operator new(
size_t s,
Space& home);
656 static void operator delete(
void* p,
Space& home);
662 static void*
operator new(
size_t s);
664 static void operator delete(
void* p);
697 Group(
unsigned int gid0);
709 unsigned int id(
void)
const;
879 operator Space&(void);
995 unsigned int id(
void)
const;
1020 unsigned int id(
void)
const;
1090 void disable(
Space& home);
1092 void enable(
Space& home);
1193 double afc(
void)
const;
1195#ifdef GECODE_HAS_CBS
1205 typedef std::function<void(
unsigned int prop_id,
unsigned int var_id,
1206 int val,
double dens)> SendMarginal;
1207 virtual void solndistrib(
Space& home, SendMarginal send)
const;
1216 typedef std::function<bool(
unsigned int var_id)> InDecision;
1217 virtual void domainsizesum(InDecision in,
unsigned int&
size,
1218 unsigned int& size_b)
const;
1224 unsigned int id(
void)
const;
1301 bool disposed(
void)
const;
1324 static void*
operator new(
size_t s,
Space& home);
1326 static void operator delete(
void* p,
Space& home);
1331 static void operator delete(
void* p);
1334 static void*
operator new(
size_t s);
1373 virtual bool notice(
void)
const;
1379 bool leaf(
void)
const;
1392 static void*
operator new(
size_t s,
Space& home);
1394 static void operator delete(
void* s,
Space& home);
1396 static void operator delete(
void* p);
1402 static void*
operator new(
size_t s);
1421 unsigned int id(
void)
const;
1491 unsigned int a) = 0;
1516 std::ostream& o)
const;
1521 unsigned int id(
void)
const;
1593 unsigned long int n;
1601 unsigned long int ng(
void)
const;
1603 void ng(
unsigned long int n);
1630 const unsigned long int r;
1632 const unsigned long int s;
1634 const unsigned long int f;
1643 const unsigned int a;
1650 unsigned long int s,
1651 unsigned long int f,
1662 unsigned long int restart(
void)
const;
1664 unsigned long int solution(
void)
const;
1666 unsigned long int fail(
void)
const;
1675 unsigned int asset(
void)
const;
1767#ifdef GECODE_HAS_CBS
1769 unsigned int var_id_counter;
1794 Brancher* brancher(
unsigned int id);
1803 void kill_brancher(
unsigned int id);
1806 static const unsigned reserved_bid = 0U;
1809 static const unsigned int sc_bits = 2;
1811 static const unsigned int sc_fast = 0;
1813 static const unsigned int sc_disabled = 1;
1815 static const unsigned int sc_trace = 2;
1858 void enqueue(Propagator* p);
1863#ifdef GECODE_HAS_VAR_DISPOSE
1867 VarImpBase* _vars_d[AllVarConf::idx_d];
1869 template<
class VIC> VarImpBase* vars_d(
void)
const;
1871 template<
class VIC>
void vars_d(VarImpBase* x);
1874 void update(ActorLink** sub);
1939 void _commit(
const Choice& c,
unsigned int a);
1972 void _trycommit(
const Choice& c,
unsigned int a);
1976 TraceRecorder* findtracerecorder(
void);
1979 void post(
const PostInfo&
pi);
1988 void ap_notice_dispose(Actor* a,
bool d);
1996 void ap_ignore_dispose(Actor* a,
bool d);
2281 void print(
const Choice&
c,
unsigned int a, std::ostream& o)
const;
2436 T*
alloc(
long unsigned int n);
2444 T*
alloc(
long int n);
2452 T*
alloc(
unsigned int n);
2471 void free(T* b,
long unsigned int n);
2482 void free(T* b,
long int n);
2493 void free(T* b,
unsigned int n);
2504 void free(T* b,
int n);
2517 T*
realloc(T* b,
long unsigned int n,
long unsigned int m);
2530 T*
realloc(T* b,
long int n,
long int m);
2543 T*
realloc(T* b,
unsigned int n,
unsigned int m);
2556 T*
realloc(T* b,
int n,
int m);
2565 T**
realloc(T** b,
long unsigned int n,
long unsigned int m);
2574 T**
realloc(T** b,
long int n,
long int m);
2583 T**
realloc(T** b,
unsigned int n,
unsigned int m);
2592 T**
realloc(T** b,
int n,
int m);
2596 void rfree(
void*
p,
size_t s);
2598 void*
rrealloc(
void* b,
size_t n,
size_t m);
2600 template<
size_t>
void*
fl_alloc(
void);
2620 template<
class T,
typename A1>
2627 template<
class T,
typename A1,
typename A2>
2628 T&
construct(A1
const& a1, A2
const& a2);
2634 template<
class T,
typename A1,
typename A2,
typename A3>
2635 T&
construct(A1
const& a1, A2
const& a2, A3
const& a3);
2641 template<
class T,
typename A1,
typename A2,
typename A3,
typename A4>
2642 T&
construct(A1
const& a1, A2
const& a2, A3
const& a3, A4
const& a4);
2648 template<
class T,
typename A1,
typename A2,
typename A3,
typename A4,
typename A5>
2649 T&
construct(A1
const& a1, A2
const& a2, A3
const& a3, A4
const& a4, A5
const& a5);
2682 bool operator ()(
void)
const;
2684 void operator ++(
void);
2707 bool operator ()(
void)
const;
2709 void operator ++(
void);
2728 bool operator ()(
void)
const;
2730 void operator ++(
void);
2749 bool operator ()(
void)
const;
2751 void operator ++(
void);
2804 return mm.alloc(ssd.data().sm,s);
2808 return mm.reuse(
p,s);
2812 char* b =
static_cast<char*
>(_b);
2814 char*
p =
static_cast<char*
>(
ralloc(m));
2842 T*
p =
static_cast<T*
>(
ralloc(
sizeof(T)*n));
2843 for (
long unsigned int i=0; i<n; i++)
2844 (
void)
new (
p+i) T();
2851 return alloc<T>(
static_cast<long unsigned int>(n));
2856 return alloc<T>(
static_cast<long unsigned int>(n));
2862 return alloc<T>(
static_cast<long unsigned int>(n));
2868 for (
long unsigned int i=0; i<n; i++)
2870 rfree(b,n*
sizeof(T));
2876 free<T>(b,
static_cast<long unsigned int>(n));
2881 free<T>(b,
static_cast<long unsigned int>(n));
2887 free<T>(b,
static_cast<long unsigned int>(n));
2894 T*
p =
static_cast<T*
>(
ralloc(
sizeof(T)*m));
2895 for (
long unsigned int i=0; i<n; i++)
2896 (
void)
new (
p+i) T(b[i]);
2897 for (
long unsigned int i=n; i<m; i++)
2898 (
void)
new (
p+i) T();
2909 assert((n >= 0) && (m >= 0));
2910 return realloc<T>(b,
static_cast<long unsigned int>(n),
2911 static_cast<long unsigned int>(m));
2916 return realloc<T>(b,
static_cast<long unsigned int>(n),
2917 static_cast<long unsigned int>(m));
2922 assert((n >= 0) && (m >= 0));
2923 return realloc<T>(b,
static_cast<long unsigned int>(n),
2924 static_cast<long unsigned int>(m));
2927#define GECODE_KERNEL_REALLOC(T) \
2930 Space::realloc<T>(T* b, long unsigned int n, long unsigned int m) { \
2931 return static_cast<T*>(rrealloc(b,n*sizeof(T),m*sizeof(T))); \
2935 Space::realloc<T>(T* b, long int n, long int m) { \
2936 assert((n >= 0) && (m >= 0)); \
2937 return realloc<T>(b,static_cast<long unsigned int>(n), \
2938 static_cast<long unsigned int>(m)); \
2942 Space::realloc<T>(T* b, unsigned int n, unsigned int m) { \
2943 return realloc<T>(b,static_cast<long unsigned int>(n), \
2944 static_cast<long unsigned int>(m)); \
2948 Space::realloc<T>(T* b, int n, int m) { \
2949 assert((n >= 0) && (m >= 0)); \
2950 return realloc<T>(b,static_cast<long unsigned int>(n), \
2951 static_cast<long unsigned int>(m)); \
2966#undef GECODE_KERNEL_REALLOC
2971 return static_cast<T**
>(
rrealloc(b,n*
sizeof(T),m*
sizeof(T*)));
2976 assert((n >= 0) && (m >= 0));
2977 return realloc<T*>(b,
static_cast<long unsigned int>(n),
2978 static_cast<long unsigned int>(m));
2983 return realloc<T*>(b,
static_cast<long unsigned int>(n),
2984 static_cast<long unsigned int>(m));
2989 assert((n >= 0) && (m >= 0));
2990 return realloc<T*>(b,
static_cast<long unsigned int>(n),
2991 static_cast<long unsigned int>(m));
2995#ifdef GECODE_HAS_VAR_DISPOSE
2998 Space::vars_d(
void)
const {
2999 return _vars_d[VIC::idx_d];
3003 Space::vars_d(VarImpBase*
x) {
3004 _vars_d[VIC::idx_d] =
x;
3010 Actor::operator
delete(
void*) {}
3012 Actor::operator
delete(
void*,
Space&) {}
3014 Actor::operator
new(
size_t s,
Space& home) {
3015 return home.ralloc(s);
3027 return home.ralloc(s);
3032 Advisor::operator
delete(
void*) {}
3035 Advisor::operator
delete(
void*,
Space&) {}
3037 Advisor::operator
new(
size_t s,
Space& home) {
3038 return home.ralloc(s);
3042 NGL::operator
delete(
void*) {}
3046 NGL::operator
new(
size_t s,
Space& home) {
3047 return home.ralloc(s);
3075 unsigned long int s0,
3076 unsigned long int f0,
3154 p->_next = n; n->_prev = p;
3159 _next =
this; _prev =
this;
3166 this->_next = a; a->_prev =
this;
3167 a->_next = n; n->_prev = a;
3174 a->_next =
this; this->_prev = a;
3175 p->_next = a; a->_prev = p;
3180 return _next ==
this;
3198 return static_cast<const ActorLink*
>(&t);
3211 return static_cast<Actor*
>(&t);
3215 Actor::cast(
const ActorLink* al) {
3219 return static_cast<const Actor*
>(&t);
3224 s.notice(a,
p,duplicate);
3232 return const_cast<Space*
>(
this)->_clone();
3247 return ssd.data().gpi.decay();
3252 ssd.data().gpi.decay(d);
3257 return sizeof(*this);
3268 :
s(s0),
p(p0),
pg(pg0),
bg(bg0) {}
3295 return Home(*
this,&
p);
3340 return static_cast<What>(
who & 3);
3364 :
h(home),
pg(home.propagatorgroup()),
3367 h.pc.p.vti.post(
pg);
3373 if (
h.pc.p.bid_sc & Space::sc_trace)
3387 :
i(i0),
g(g0),
p(p0),
s(s0) {}
3413 :
b(b0),
c(c0),
a(a0) {}
3442 :
g(g0),
s(s0),
n(n0) {}
3470 Propagator::cast(
const ActorLink* al) {
3488 Propagator::disable(
Space& home) {
3489 home.pc.
p.
bid_sc |= Space::sc_disabled;
3494 Propagator::enable(Space& home) {
3510 static_cast<
Space&>(home).ssd.data().
gpi.allocate
3511 (home.propagatorgroup().gid)) {
3513 assert((u.med == 0) && (u.size == 0));
3514 static_cast<Space&
>(home).pl.head(
this);
3519 : gpi_disabled(p.gpi_disabled) {
3521 assert((u.med == 0) && (u.size == 0));
3533 return const_cast<Propagator&
>(*this).gpi().afc;
3536#ifdef GECODE_HAS_CBS
3538 Propagator::solndistrib(
Space&, SendMarginal)
const {}
3541 Propagator::domainsizesum(InDecision,
unsigned int& size,
3542 unsigned int& size_b)
const {
3550 return const_cast<Propagator&
>(*this).gpi().pid;
3571 p.u.size =
p.dispose(*
this);
3578 assert(
p.u.med != 0);
3585 assert(
p.u.med != 0);
3604 Brancher::cast(
const ActorLink* al) {
3608 return static_cast<const Brancher*
>(&t);
3613 gid(_home.branchergroup().gid) {
3615 bid = home.pc.
p.
bid_sc >> Space::sc_bits;
3616 home.pc.
p.
bid_sc += (1 << Space::sc_bits);
3617 if ((home.pc.
p.
bid_sc >> Space::sc_bits) == 0U)
3620 if (home.b_status == &
static_cast<Space&
>(home).bl) {
3621 home.b_status = this;
3622 if (home.b_commit == &static_cast<Space&>(home).bl)
3623 home.b_commit = this;
3630 : bid(b.bid), gid(b.gid) {
3656 b_commit = Brancher::cast(b.next());
3658 b_status = Brancher::cast(b.next());
3660 rfree(&b,b.dispose(*
this));
3664 Space::kill(Propagator& p) {
3671 Space::brancher(
unsigned int id) {
3688 while (b_commit != Brancher::cast(&bl))
3689 if (
id != b_commit->id())
3690 b_commit = Brancher::cast(b_commit->next());
3693 if (b_commit == Brancher::cast(&bl)) {
3695 b_commit = Brancher::cast(bl.next());
3696 while (b_commit != b_old)
3697 if (
id != b_commit->id())
3698 b_commit = Brancher::cast(b_commit->next());
3774 : bid(b.id()), alt(a) {}
3782 Choice::id(
void)
const {
3829 return sizeof(*this);
3849 Advisor::disposed(
void)
const {
3850 return prev() == NULL;
3854 Advisor::cast(ActorLink* al) {
3855 return static_cast<Advisor*
>(al);
3860 return static_cast<const Advisor*
>(al);
3865 assert(!disposed());
3872 assert(!disposed());
3876 if ((n != NULL) && n->disposed())
3882 return home.pc.
p.
vti;
3925 while ((a != NULL) &&
static_cast<A*
>(a)->disposed())
3937 while ((a != NULL) &&
static_cast<A*
>(a)->disposed())
3942 if (c.advisors != NULL) {
3946 Propagator* p_t = Propagator::cast(p_f->prev());
3951 while (*a_f != NULL) {
3952 if (
static_cast<A*
>(*a_f)->disposed()) {
3953 *a_f = (*a_f)->
next();
3956 A* a =
new (home) A(home,*
static_cast<A*
>(*a_f));
3981 if (!
static_cast<A*
>(a)->disposed())
3982 static_cast<A*
>(a)->
dispose(home,*
this);
3997 while ((a != NULL) &&
static_cast<A*
>(a)->disposed())
4012 }
while ((a != NULL) &&
static_cast<A*
>(a)->disposed());
4018 return *
static_cast<A*
>(a);
4030 ActorLink*
c = &pc.p.queue[
p->cost(*
this,
p->u.med).ac];
4032 if (
c > pc.p.active)
4061 return ((pc.p.active < &pc.p.queue[0]) ||
4068 ap_notice_dispose(&a,d);
4071 pc.p.bid_sc |= sc_trace;
4074 pc.p.bid_sc |= sc_trace;
4085 ap_ignore_dispose(&a,d);
4101 assert((pc >= 0) && (pc < pc_max+2));
4102 return (pc == 0) ? b.base : b.base+u.idx[pc-1];
4107 VarImp<VIC>::actorNonZero(
PropCond pc) {
4108 assert((pc > 0) && (pc < pc_max+2));
4109 return b.base+u.idx[pc-1];
4115 assert((pc > 0) && (pc < pc_max+2));
4122 assert((pc > 0) && (pc < pc_max+2));
4129#ifdef GECODE_HAS_CBS
4130 : var_id(++home.var_id_counter)
4133#ifndef GECODE_HAS_CBS
4136 b.base = NULL; entries = 0;
4137 for (
PropCond pc=1; pc<pc_max+2; pc++)
4145#ifdef GECODE_HAS_CBS
4149 b.base = NULL; entries = 0;
4150 for (
PropCond pc=1; pc<pc_max+2; pc++)
4155#ifdef GECODE_HAS_CBS
4179 d += Propagator::cast(*a)->afc(); a++;
4188 ->propagator().afc();
4204 return free_and_bits;
4210 return free_and_bits;
4213#ifdef GECODE_HAS_VAR_DISPOSE
4217 return static_cast<VarImp<VIC>*
>(home.vars_d<VIC>());
4222 VarImp<VIC>::vars_d(Space& home, VarImp<VIC>*
x) {
4223 home.vars_d<VIC>(
x);
4250#ifdef GECODE_HAS_CBS
4255 free_and_bits =
x.free_and_bits & ((1 << free_bits) - 1);
4256 if (
x.b.base == NULL) {
4259 assert(
x.degree() == 0);
4261 reg = &home.pc.
c.
vars_u[idx_c];
4265 entries =
x.entries;
4266 for (
PropCond pc=1; pc<pc_max+2; pc++)
4267 idx(pc) =
x.idx(pc);
4278 return static_cast<ModEvent>((
med & VIC::med_mask) >> VIC::med_fst);
4290 return VIC::me_combine(me1,me2);
4297 if (VIC::med_update(p.u.
med,
me) || force)
4312 VarImp<VIC>::resize(
Space& home) {
4313 if (b.base == NULL) {
4314 assert((free_and_bits >> free_bits) == 0);
4316 free_and_bits += 4 << free_bits;
4318 for (
int i=0; i<pc_max+1; i++)
4322 unsigned int n = degree();
4326 ActorLink** s =
static_cast<ActorLink**
>(home.mm.
subscriptions());
4328 ((s <= b.base) && (b.base < s+home.pc.
p.
n_sub)) ?
4329 (n+4) : ((n+1)*3>>1);
4330 ActorLink** prop = home.
alloc<ActorLink*>(m);
4331 free_and_bits += (m-n) << free_bits;
4334 home.
free<ActorLink*>(b.base,n);
4342 assert(pc <= pc_max);
4344 home.pc.p.n_sub += 1;
4345 if ((free_and_bits >> free_bits) == 0)
4347 free_and_bits -= 1 << free_bits;
4350 b.base[entries] = *actorNonZero(pc_max+1);
4352 for (
PropCond j = pc_max; j > pc; j--) {
4353 *actorNonZero(j+1) = *actorNonZero(j);
4356 *actorNonZero(pc+1) = *actor(pc);
4362 while (f < (pc == pc_max+1 ?
b.base+entries : actorNonZero(pc+1)))
4377 home.pc.p.n_sub += 1;
4378 if ((free_and_bits >> free_bits) == 0)
4380 free_and_bits -= 1 << free_bits;
4383 b.base[entries++] = *actorNonZero(pc_max+1);
4384 *actorNonZero(pc_max+1) =
a;
4425 assert(pc <= pc_max);
4430 while (f < actorNonZero(pc+1))
4438 while (*f != a) f++;
4441 *f = *(actorNonZero(pc+1)-1);
4442 for (
PropCond j = pc+1; j< pc_max+1; j++) {
4443 *(actorNonZero(j)-1) = *(actorNonZero(j+1)-1);
4446 *(actorNonZero(pc_max+1)-1) = b.base[entries-1];
4449 free_and_bits += 1 << free_bits;
4467 while (f < b.base+entries)
4475 while (*f != a) f++;
4478 *f = b.base[--entries];
4479 free_and_bits += 1 << free_bits;
4486 if (b.base != NULL) {
4495 unsigned int n_sub =
degree();
4496 home.pc.
p.
n_sub -= n_sub;
4497 unsigned int n = (free_and_bits >> free_bits) + n_sub;
4504 for (
PropCond pc=1; pc<pc_max+2; pc++)
4506 free_and_bits &= (1 << free_bits) - 1;
4517 ActorLink** la = actorNonZero(pc_max+1);
4528 assert(!a->disposed());
4530 switch (p.
advise(home,*a,d)) {
4545 }
while (++la < le);
4551 VarImp<VIC>::_fail(
Space& home) {
4557 ActorLink** la = actorNonZero(pc_max+1);
4568 assert(!a->disposed());
4572 }
while (++la < le);
4589 x->u.idx[0] = u.idx[0];
4590 if (pc_max > 0 &&
sizeof(
ActorLink**) >
sizeof(
unsigned int))
4591 x->u.idx[1] = u.idx[1];
4594 static_cast<unsigned int>(
x->actorNonZero(pc_max+1) -
x->actor(0));
4596 static_cast<unsigned int >(
x->b.base +
x->entries -
4597 x->actorNonZero(pc_max+1));
4598 unsigned int n = na + np;
4599 assert(n ==
x->degree());
4612 t[0] = p0; t[1] = p1; t[2] = p2; t[3] = p3;
4613 np -= 4; t += 4; f += 4;
4616 ActorLink* p0 = f[0]->prev();
4617 ActorLink* p1 = f[1]->prev();
4618 t[0] = p0; t[1] = p1;
4619 np -= 2; t += 2; f += 2;
4628 ptrdiff_t m0, m1, m2, m3;
4641 na -= 4; t += 4;
f += 4;
4651 na -= 2; t += 2;
f += 2;
4676 template<
class VarImp>
4678#ifdef GECODE_HAS_VAR_DISPOSE
4679 Space::vd[VarImp::idx_d] =
this;
4683 template<
class VarImp>
4688 x->dispose(home);
x =
static_cast<VarImp*
>(
x->next_d());
4689 }
while (
x != NULL);
4768 return (m ==
LO) ? lo : hi;
4782 return crazy(m,
static_cast<unsigned int>(n));
4791 return cubic(m,
static_cast<unsigned int>(n));
4800 return quadratic(m,
static_cast<unsigned int>(n));
4809 return linear(m,
static_cast<unsigned int>(n));
4830 : home(home0), q(home.pc.
p.
active) {
4831 while (q >= &home.pc.p.queue[0]) {
4832 if (q->next() != q) {
4833 c = q->next(); e = q; q--;
4839 if (!home.pl.empty()) {
4840 c = Propagator::cast(home.pl.next());
4841 e = Propagator::cast(&home.pl);
4857 while (q >= &home.pc.p.queue[0]) {
4858 if (q->next() != q) {
4859 c = q->next(); e = q; q--;
4865 if (!home.pl.empty()) {
4866 c = Propagator::cast(home.pl.next());
4867 e = Propagator::cast(&home.pl);
4876 return *Propagator::cast(c);
4882 : home(home0), q(home.pc.
p.
active) {
4883 while (q >= &home.pc.p.queue[0]) {
4884 if (q->next() != q) {
4885 c = q->next(); e = q; q--;
4903 while (q >= &home.pc.p.queue[0]) {
4904 if (q->next() != q) {
4905 c = q->next(); e = q; q--;
4916 return *Propagator::cast(c);
4922 c = Propagator::cast(home.pl.
next());
4923 e = Propagator::cast(&home.pl);
4935 return *Propagator::cast(c);
4941 : c(
Brancher::cast(home.bl.next())), e(&home.bl) {}
4952 return *Brancher::cast(c);
5009 return id() == g.
id();
5013 return id() != g.
id();
5047 return id() == g.
id();
5051 return id() != g.
id();
5068 : ps(const_cast<
Space&>(home)), g(g0) {
5069 while (ps() && !g.in(ps.propagator().group()))
5080 while (ps() && !g.in(ps.propagator().group()));
5084 return ps.propagator();
5089 : bs(const_cast<
Space&>(home)), g(g0) {
5090 while (bs() && !g.in(bs.brancher().group()))
5101 while (bs() && !g.in(bs.brancher().group()));
5105 return bs.brancher();
5118 template<
class T,
typename A1>
5121 T& t = *
static_cast<T*
>(
ralloc(
sizeof(T)));
5125 template<
class T,
typename A1,
typename A2>
5128 T& t = *
static_cast<T*
>(
ralloc(
sizeof(T)));
5132 template<
class T,
typename A1,
typename A2,
typename A3>
5135 T& t = *
static_cast<T*
>(
ralloc(
sizeof(T)));
5136 new (&t) T(a1,a2,a3);
5139 template<
class T,
typename A1,
typename A2,
typename A3,
typename A4>
5142 T& t = *
static_cast<T*
>(
ralloc(
sizeof(T)));
5143 new (&t) T(a1,a2,a3,a4);
5146 template<
class T,
typename A1,
typename A2,
typename A3,
typename A4,
typename A5>
5149 T& t = *
static_cast<T*
>(
ralloc(
sizeof(T)));
5150 new (&t) T(a1,a2,a3,a4,a5);
Class for AFC (accumulated failure count) management.
Double-linked list for actors.
ActorLink ** next_ref(void)
ActorLink * next(void) const
void init(void)
Initialize links (self-linked)
void unlink(void)
Remove from predecessor and successor.
void head(ActorLink *al)
Insert al directly after this.
void tail(ActorLink *al)
Insert al directly before this.
ActorLink * prev(void) const
Routines for double-linked list.
bool empty(void) const
Test whether actor link is empty (points to itself)
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 * copy(Space &home)=0
Create copy.
virtual size_t dispose(Space &home)
Delete actor and return its size.
friend class SubscribedPropagators
Propagator & propagator(void) const
Return the advisor's propagator.
Advisor(Space &home, Propagator &p, Council< A > &c)
Constructor for creation.
void dispose(Space &home, Council< A > &c)
Dispose the advisor.
const ViewTraceInfo & operator()(const Space &home) const
Provide access to view trace information.
Class to iterate over advisors of a council.
Advisors(const Council< A > &c)
Initialize.
bool operator()(void) const
Test whether there advisors left.
void operator++(void)
Move iterator to next advisor.
A & advisor(void) const
Return advisor.
static const int idx_c
Index for cloning.
static ModEventDelta med_combine(ModEventDelta med1, ModEventDelta med2)
Combine modification event delta med1 with med2.
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 & operator=(const BrancherGroup &g)
Assignment operator.
BrancherGroup & move(Space &home, BrancherGroup g)
Move branchers from group g to this group.
BrancherGroup(unsigned int gid)
Initialize with group id gid.
Home operator()(Space &home)
To augment a space argument.
bool operator!=(BrancherGroup g) const
Test whether this group is different from group g.
void kill(Space &home)
Kill all branchers in a group.
bool operator==(BrancherGroup g) const
Test whether this group is equal to group g.
BrancherGroup(void)
Constructor.
Base-class for branchers.
virtual const Choice * choice(Space &home)=0
Return choice.
virtual ExecStatus commit(Space &home, const Choice &c, unsigned int a)=0
Commit for choice c and alternative a.
unsigned int id(void) const
Return brancher id.
virtual const Choice * choice(const Space &home, Archive &e)=0
Return choice from e.
BrancherGroup group(void) const
Return group brancher belongs to.
virtual bool status(const Space &home) const =0
Check status of brancher, return true if alternatives left.
virtual NGL * ngl(Space &home, const Choice &c, unsigned int a) const
Create no-good literal for choice c and alternative a.
Brancher(Home home)
Constructor for creation.
void operator++(void)
Move iterator to next brancher.
const Brancher & brancher(void) const
Return propagator.
bool operator()(void) const
Test whether there are branchers left.
Branchers(const Space &home, BrancherGroup g)
Initialize.
Choice for performing commit
Choice(const Brancher &b, const unsigned int a)
Initialize for particular brancher b and alternatives a.
virtual void archive(Archive &e) const
Archive into e.
virtual ~Choice(void)
Destructor.
unsigned int alternatives(void) const
Return number of alternatives.
Statistics for execution of clone
CloneStatistics operator+(const CloneStatistics &s)
Return sum with s.
void reset(void)
Reset information.
CloneStatistics & operator+=(const CloneStatistics &s)
Increment by statistics s.
CloneStatistics(void)
Initialize.
Statistics for execution of commit
CommitStatistics & operator+=(const CommitStatistics &s)
Increment by statistics s.
void reset(void)
Reset information.
CommitStatistics operator+(const CommitStatistics &s)
Return sum with s.
CommitStatistics(void)
Initialize.
Commit trace information.
BrancherGroup group(void) const
Return brancher group.
unsigned int alternative(void) const
Return alternative.
const Brancher & b
Brancher.
CommitTraceInfo(const Brancher &b, const Choice &c, unsigned int a)
Initialize.
unsigned int id(void) const
Return brancher identifier.
unsigned int a
Alternative.
const Choice & choice(void) const
Return choice.
const Brancher & brancher(void) const
Return brancher.
bool empty(void) const
Test whether council has advisor left.
void update(Space &home, Council< A > &c)
Update during cloning (copies all advisors)
void dispose(Space &home)
Dispose council.
Council(void)
Default constructor.
Generic domain change information to be supplied to advisors.
Base-class for freelist-managed objects.
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)
friend class CommitTraceInfo
static Support::Mutex m
Mutex for protection.
friend class PostTraceInfo
static const unsigned int GROUPID_MAX
The maximal group number.
Group & operator=(const Group &g)
Assignment operator.
unsigned int id(void) const
Return a unique id for the group.
static const unsigned int GROUPID_DEF
Pre-defined default group id.
unsigned int gid
The group id.
static unsigned int next
Next group id.
friend class PropagateTraceInfo
Group(unsigned int gid0)
Construct with predefined group id gid0.
friend class ViewTraceInfo
Base class for heap allocated objects.
static T * copy(T *d, const T *s, long unsigned int n)
Copy n objects starting at s to d.
Home class for posting propagators
PropagatorGroup pg
A propagator group.
BrancherGroup branchergroup(void) const
Return brancher group.
void notice(Actor &a, ActorProperty p, bool duplicate=false)
Notice actor property.
Home(Space &s, Propagator *p=NULL, PropagatorGroup pg=PropagatorGroup::def, BrancherGroup bg=BrancherGroup::def)
Initialize the home with space s and propagator p and group g.
Propagator * p
A propagator (possibly) that is currently being rewritten.
Space & s
The space where the propagator is to be posted.
void fail(void)
Mark space as failed.
BrancherGroup bg
A brancher group.
Propagator * propagator(void) const
Return propagator (or NULL) for currently rewritten propagator.
PropagatorGroup propagatorgroup(void) const
Return propagator group.
Home operator()(Propagator &p)
Return a home extended by propagator to be rewritten.
bool failed(void) const
Check whether corresponding space is failed.
Home & operator=(const Home &h)
Assignment operator.
Class for storing propagator information.
unsigned int gid
Group identifier.
void * subscriptions(void) const
Get the memory area for subscriptions.
Class to store data shared among several spaces.
Handles for local (space-shared) objects.
LocalHandle(void)
Create local handle pointing to NULL object.
~LocalHandle(void)
Destructor.
void update(Space &home, LocalHandle &lh)
Updating during cloning.
LocalHandle & operator=(const LocalHandle &lh)
Assignment operator.
LocalObject * object(void) const
Access to the local object.
Local (space-shared) object.
static LocalObject * cast(ActorLink *al)
Static cast for a non-null pointer (to give a hint to optimizer)
LocalObject * fwd(Space &home)
Return forwarding pointer.
LocalObject(Home home)
Constructor for creation.
No-good literal recorded during search.
bool leaf(void) const
Test whether literal is a leaf.
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 NGL::Status status(const Space &home) const =0
Test the status of the no-good literal.
NGL(void)
Constructor for creation.
virtual NGL * copy(Space &home)=0
Create copy.
Status
The status of a no-good literal.
@ SUBSUMED
The literal is subsumed.
@ FAILED
The literal is failed.
@ NONE
The literal is neither failed nor subsumed.
virtual void reschedule(Space &home, Propagator &p)=0
Schedule propagator p for all views of the no-good literal.
NGL * next(void) const
Return pointer to next literal.
virtual size_t dispose(Space &home)
Dispose.
NGL * add(NGL *n, bool l)
Add node n and mark it as leaf l and return n.
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.
virtual ~NoGoods(void)
Destructor.
unsigned long int ng(void) const
Return number of no-goods posted.
unsigned long int n
Number of no-goods.
Configuration class for variable implementations without index structure.
static bool med_update(ModEventDelta &med, ModEvent me)
Update modification even delta med by me, return true on change.
static const int free_bits
Freely available bits.
static const int idx_c
Index for update.
static const int med_fst
Start of bits for modification event delta.
static const int med_lst
End of bits for modification event delta.
static const PropCond pc_max
Maximal propagation condition.
static const int idx_d
Index for disposal.
static Gecode::ModEvent me_combine(ModEvent me1, ModEvent me2)
Combine modification events me1 and me2.
static const int med_mask
Bitmask for modification event delta.
Class to set group information when a post function is executed.
PostInfo(Home home)
Set information.
bool nested
Whether it is used nested.
unsigned int pid
Next free propagator id.
PropagatorGroup pg
The propagator group.
~PostInfo(void)
Reset information.
unsigned int propagators(void) const
Return number of posted propagators.
PropagatorGroup group(void) const
Return propagator group.
PropagatorGroup g
Propagator group.
@ SUBSUMED
Propagator not posted as already subsumed.
@ POSTED
Propagator was posted.
Status status(void) const
Return post status.
PostTraceInfo(PropagatorGroup g, Status s, unsigned int n)
Initialize.
unsigned int n
Number of posted propagators.
ActualCost ac
Actual cost.
static PropCost unary(PropCost::Mod m)
Single variable for modifier pcm.
static PropCost ternary(PropCost::Mod m)
Three variables for modifier pcm.
static PropCost record(void)
For recording information (no propagation allowed)
static PropCost crazy(PropCost::Mod m, unsigned int n)
Exponential complexity for modifier m and size measure n.
static PropCost quadratic(PropCost::Mod m, unsigned int n)
Quadratic complexity for modifier m and size measure n.
static PropCost linear(PropCost::Mod m, unsigned int n)
Linear complexity for modifier pcm and size measure n.
static PropCost cubic(PropCost::Mod m, unsigned int n)
Cubic complexity for modifier m and size measure n.
static PropCost binary(PropCost::Mod m)
Two variables for modifier pcm.
Mod
Propagation cost modifier.
ActualCost
The actual cost values that are used.
@ AC_TERNARY_LO
Three variables, cheap.
@ AC_TERNARY_HI
Three variables, expensive.
@ AC_BINARY_LO
Two variables, cheap.
@ AC_CUBIC_LO
Cubic complexity, cheap.
@ AC_UNARY_HI
Only single variable, expensive.
@ AC_RECORD
Reserved for recording information.
@ AC_BINARY_HI
Two variables, expensive.
@ AC_LINEAR_HI
Linear complexity, expensive.
@ AC_CUBIC_HI
Cubic complexity, expensive.
@ AC_MAX
Maximal cost value.
@ AC_CRAZY_LO
Exponential complexity, cheap.
@ AC_LINEAR_LO
Linear complexity, cheap.
@ AC_UNARY_LO
Only single variable, cheap.
@ AC_QUADRATIC_LO
Quadratic complexity, cheap.
@ AC_CRAZY_HI
Exponential complexity, expensive.
@ AC_QUADRATIC_HI
Quadratic complexity, expensive.
Propagate trace information.
unsigned int i
Propagator id.
@ SUBSUMED
Propagator is subsumed.
@ FIX
Propagator computed fixpoint.
@ NOFIX
Propagator did not compute fixpoint.
@ FAILED
Propagator failed.
PropagateTraceInfo(unsigned int i, PropagatorGroup g, const Propagator *p, Status s)
Initialize.
const Propagator * propagator(void) const
Return pointer to non-subsumed propagator.
unsigned int id(void) const
Return propagator identifier.
Status status(void) const
Return propagator status.
const Propagator * p
Propagator.
PropagatorGroup g
Propagator group.
PropagatorGroup group(void) const
Return propagator group.
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.
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.
friend class PostTraceInfo
PropagatorGroup(unsigned int gid)
Initialize with group id gid.
bool operator!=(PropagatorGroup g) const
Test whether this group is different from group g.
PropagatorGroup(void)
Constructor.
PropagatorGroup & operator=(const PropagatorGroup &g)
Assignment operator.
void disable(Space &home)
Disable all propagators in a group.
void enable(Space &home, bool s=true)
Enable all propagators in a group.
Home operator()(Space &home)
To augment a space argument.
friend class PropagateTraceInfo
void kill(Space &home)
Kill all propagators in a group.
friend class ViewTraceInfo
static PropagatorGroup all
Group of all propagators.
Base-class for propagators.
virtual void reschedule(Space &home)=0
Schedule function.
size_t size
The size of the propagator (used during subsumption)
friend class SubscribedPropagators
double afc(void) const
Return the accumlated failure count.
virtual PropCost cost(const Space &home, const ModEventDelta &med) const =0
Cost function.
virtual ExecStatus advise(Space &home, Advisor &a, const Delta &d)
Advise function.
Kernel::GPI::Info & gpi(void)
Provide access to global propagator information.
unsigned int id(void) const
Return propagator id.
PropagatorGroup group(void) const
Return group propagator belongs to.
ModEventDelta modeventdelta(void) const
Return the modification event delta.
Propagator * fwd(void) const
Return forwarding pointer during copying.
friend class PropagatorGroup
bool disabled(void) const
Whether propagator is currently disabled.
virtual ExecStatus propagate(Space &home, const ModEventDelta &med)=0
Propagation function.
ModEventDelta med
A set of modification events (used during propagation)
Propagator(Home home)
Constructor for posting.
Gecode::ActorLink * advisors
A list of advisors (used during cloning)
bool operator()(void) const
Test whether there are propagators left.
const Propagator & propagator(void) const
Return propagator.
void operator++(void)
Move iterator to next propagator.
Propagators(const Space &home, PropagatorGroup g)
Initialize.
Class to iterate over branchers of a space.
Brancher & brancher(void) const
Return propagator.
void operator++(void)
Move iterator to next brancher.
Branchers(Space &home)
Initialize.
bool operator()(void) const
Test whether there are branchers left.
void operator++(void)
Move iterator to next propagator.
Propagator & propagator(void) const
Return propagator.
bool operator()(void) const
Test whether there are propagators left.
IdlePropagators(Space &home)
Initialize.
Class to iterate over propagators of a space.
bool operator()(void) const
Test whether there are propagators left.
Propagators(Space &home)
Initialize.
void operator++(void)
Move iterator to next propagator.
Propagator & propagator(void) const
Return propagator.
ScheduledPropagators(Space &home)
Initialize.
Propagator & propagator(void) const
Return propagator.
bool operator()(void) const
Test whether there are propagators left.
void operator++(void)
Move iterator to next 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.
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.
double afc_decay(void) const
Return AFC decay factor.
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.
ActorLink queue[PropCost::AC_MAX+1]
Scheduled propagators according to cost.
LocalObject * local
Linked list of local objects.
void * rrealloc(void *b, size_t n, size_t m)
Reallocate memory block starting at b from size n to size s.
friend class VarImpDisposer
void rfree(void *p, size_t s)
Free memory previously allocated with alloc (might be reused later)
VarImpBase * vars_noidx
Keep variables during copying without index structure.
void * fl_alloc(void)
Allocate from freelist-managed memory.
VarImpBase * vars_u[AllVarConf::idx_c]
Entries for updating variables.
void afc_decay(double d)
Set AFC decay factor to d
void fl_dispose(FreeList *f, FreeList *l)
Return freelist-managed memory to freelist.
unsigned int n_sub
Number of subscriptions.
friend class PropagatorGroup
T * alloc(long unsigned int n)
Allocate block of n objects of type T from space heap.
unsigned int bid_sc
Id of next brancher to be created plus status control.
friend class BrancherGroup
ActorLink * active
Cost level with next propagator to be executed.
void free(T *b, long unsigned int n)
Delete n objects allocated from space heap starting at b.
ViewTraceInfo vti
View trace information.
Home operator()(Propagator &p)
Return a home for this space with the information that p is being rewritten.
Statistics for execution of status
unsigned long int propagate
Number of propagator executions.
void reset(void)
Reset information.
StatusStatistics(void)
Initialize.
StatusStatistics operator+(const StatusStatistics &s)
Return sum with s.
StatusStatistics & operator+=(const StatusStatistics &s)
Increment by statistics s.
Iterator over subscribed propagators.
A mutex for mutual exclausion among several threads.
Exception: too many branchers
Propagator for recording trace information.
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.
VarImpDisposer(void)
Constructor (registers disposer with kernel)
virtual void dispose(Space &home, VarImpBase *x)
Dispose list of variable implementations starting at x.
Base-class for variable implementations.
void subscribe(Space &home, Propagator &p, PropCond pc, bool assigned, ModEvent me, bool schedule)
Subscribe propagator p with propagation condition pc.
ModEvent fail(Space &home)
Run advisors to be run on failure and returns ME_GEN_FAILED.
void cancel(Space &home)
Cancel all subscriptions when variable implementation is assigned.
bool advise(Space &home, ModEvent me, Delta &d)
Run advisors when variable implementation has been modified with modification event me and domain cha...
VarImp(void)
Creation of static instances.
friend class SubscribedPropagators
double afc(void) const
Return accumulated failure count (plus degree)
unsigned int bits(void) const
Provide access to free bits.
ActorLink ** base
Subscribed actors.
bool copied(void) const
Is variable already copied.
friend class VarImpDisposer
static void reschedule(Space &home, Propagator &p, PropCond pc, bool assigned, ModEvent me)
Schedule propagator p.
static void schedule(Space &home, Propagator &p, ModEvent me, bool force=false)
unsigned int idx[pc_max+1]
Indices of subscribed actors.
VarImp * forward(void) const
Use forward pointer if variable already copied.
static ModEvent me(const ModEventDelta &med)
VarImp * next(void) const
Return next copied variable.
static ModEvent me_combine(ModEvent me1, ModEvent me2)
Combine modifications events me1 and me2.
unsigned int degree(void) const
Return degree (number of subscribed propagators and advisors)
VarImp(Space &home)
Creation.
static ModEventDelta med(ModEvent me)
VarImp< VIC > * fwd
Forwarding pointer.
VarImp< VIC > * next
During cloning, points to the next copied variable.
static ModEvent modevent(const Delta &d)
Return modification event.
What what(void) const
Return what is currently executing.
const Brancher & brancher(void) const
Return currently executing brancher.
const Propagator & propagator(void) const
Return currently executing propagator.
void other(void)
Record that nothing is known at this point.
What
What is currently executing.
@ BRANCHER
A brancher is executing.
@ POST
A post function is executing.
@ PROPAGATOR
A propagator is currently executing.
PropagatorGroup post(void) const
Return propagator group of currently executing post function.
ptrdiff_t who
Encoding a tagged pointer or a tagged group id.
#define GECODE_KERNEL_REALLOC(T)
void update(const NoOffset &)
Integer-precision integer scale view.
ExecStatus ES_NOFIX_PARTIAL(Propagator &p, const ModEventDelta &med)
Propagator p has not computed partial fixpoint
ExecStatus ES_FIX_PARTIAL(Propagator &p, const ModEventDelta &med)
Propagator p has computed partial fixpoint
ExecStatus ES_SUBSUMED_DISPOSED(Propagator &p, size_t s)
Propagator p is subsumed
ExecStatus ES_FIX_DISPOSE(Council< A > &c, A &a)
Advisor a must be disposed
ExecStatus ES_NOFIX_DISPOSE_FORCE(Council< A > &c, A &a)
Advisor a must be disposed and its propagator must be forcefully rescheduled
ExecStatus ES_NOFIX_DISPOSE(Council< A > &c, A &a)
Advisor a must be disposed and its propagator must be run
ExecStatus ES_SUBSUMED(Propagator &p)
Propagator p is subsumed
void ignore(Actor &a, ActorProperty p, bool duplicate=false)
Ignore actor property.
int ModEventDelta
Modification event deltas.
bool failed(void) const
Check whether space is failed.
ActorProperty
Actor properties.
void notice(Actor &a, ActorProperty p, bool duplicate=false)
Notice actor property.
bool stable(void) const
Return if space is stable (at fixpoint or failed)
void fail(void)
Fail space.
@ AP_DISPOSE
Actor must always be disposed.
Space(void)
Default constructor.
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 trycommit(const Choice &c, unsigned int a, CommitStatistics &stat=unused_commit)
If possible, commit choice c for alternative a.
const Choice * choice(void)
Create new choice for current brancher.
void commit(const Choice &c, unsigned int a, CommitStatistics &stat=unused_commit)
Commit choice c for alternative a.
NGL * ngl(const Choice &c, unsigned int a)
Create no-good literal for choice c and alternative a.
SpaceStatus status(StatusStatistics &stat=unused_status)
Query space status.
Space * clone(CloneStatistics &stat=unused_clone) const
Clone space.
@ SS_BRANCH
Space must be branched (at least one brancher left)
@ SS_SOLVED
Space is solved (no brancher left)
@ SS_FAILED
Space is failed
void print(const Search::Statistics &stat, bool restart)
Print statistics.
#define GECODE_KERNEL_EXPORT
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.
const ModEvent ME_GEN_NONE
Generic modification event: no modification.
TFE propagator(PropagatorGroup g)
Only propagators (but not post functions) from g are considered.
@ ES_OK
Execution is okay.
@ ES_FIX
Propagation has computed fixpoint.
@ ES_NOFIX_FORCE
Advisor forces rescheduling of propagator.
@ __ES_SUBSUMED
Internal: propagator is subsumed, do not use.
@ __ES_PARTIAL
Internal: propagator has computed partial fixpoint, do not use.
@ ES_FAILED
Execution has resulted in failure.
@ ES_NOFIX
Propagation has not computed fixpoint.
const ModEvent ME_GEN_FAILED
Generic modification event: failed variable.
int PropCond
Type for propagation conditions.
const ModEvent ME_GEN_ASSIGNED
Generic modification event: variable is assigned a value.
Post propagator for SetVar x
const PropCond PC_GEN_NONE
Propagation condition to be ignored (convenience)
int ModEvent
Type for modification events.
Gecode::FloatVal b(9, 12)
Gecode::FloatVal a(-8, 5)
#define GECODE_NEVER
Assert that this command is never executed.
#define GECODE_NOT_NULL(p)
Assert that a pointer is never NULL.
#define GECODE_VTABLE_EXPORT