00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gecode/set/projectors.hh"
00023 #include "gecode/support/dynamic-stack.hh"
00024
00025 using namespace Gecode::Set;
00026
00027 namespace Gecode {
00028
00032 class SetExpr::Node {
00033 private:
00035 unsigned int use;
00037 Node *left, *right;
00039 int signLeft, signRight;
00041 var_idx x;
00043 RelType rel;
00044 public:
00046 Node(const var_idx x);
00048 Node(Node* n0, int s0, RelType r, Node* n1, int s1);
00049
00051 void increment(void);
00053 GECODE_SET_EXPORT bool decrement(void);
00054
00056 void encode(SetExprCode& ret, bool monotone) const;
00058 int arity(void) const;
00059
00061 Iter::Ranges::Virt::Iterator* iter(void);
00062
00064 static void* operator new(size_t size);
00066 static void operator delete(void* p,size_t size);
00067 };
00068
00069
00070
00071
00072
00073
00074 forceinline void*
00075 SetExpr::Node::operator new(size_t size) {
00076 return Memory::malloc(size);
00077 }
00078
00079 forceinline void
00080 SetExpr::Node::operator delete(void* p, size_t) {
00081 Memory::free(p);
00082 }
00083
00084
00085 forceinline void
00086 SetExpr::Node::increment(void) {
00087 ++use;
00088 }
00089
00090 forceinline
00091 SetExpr::Node::Node(const var_idx x) :
00092 use(1),
00093 left(NULL), right(NULL), signLeft(0), signRight(0), x(x) {}
00094
00095 forceinline
00096 SetExpr::Node::Node(Node* l, int sL, RelType _rel, Node* r, int sR) :
00097 use(1),
00098 left(l), right(r), signLeft(sL), signRight(sR), rel(_rel) {
00099 if (left != NULL)
00100 left->increment();
00101 if (right != NULL)
00102 right->increment();
00103 }
00104
00105 bool
00106 SetExpr::Node::decrement(void) {
00107 if (--use == 0) {
00108 if (left != NULL && left->decrement())
00109 delete left;
00110 if (right != NULL && right->decrement())
00111 delete right;
00112 return true;
00113 }
00114 return false;
00115 }
00116
00117 int
00118 SetExpr::Node::arity(void) const {
00119 if (left==NULL && right==NULL)
00120 return x;
00121 return std::max( left==NULL ? 0 : left->arity(),
00122 right==NULL ? 0 : right->arity() );
00123 }
00124
00125 void
00126 SetExpr::Node::encode(SetExprCode& ret, bool monotone) const {
00127 if (left==NULL && right==NULL) {
00128 assert(x>=0);
00129 ret.add(SetExprCode::LAST+x);
00130 if (monotone)
00131 ret.add(SetExprCode::LUB);
00132 else
00133 ret.add(SetExprCode::GLB);
00134 return;
00135 }
00136 if (left==NULL) {
00137 ret.add(SetExprCode::UNIVERSE);
00138 } else {
00139 left->encode(ret, (signLeft==1) ? monotone : !monotone);
00140 }
00141 if (signLeft==-1)
00142 ret.add(SetExprCode::COMPLEMENT);
00143 if (right==NULL) {
00144 ret.add(SetExprCode::UNIVERSE);
00145 } else {
00146 right->encode(ret, (signRight==1) ? monotone : !monotone);
00147 }
00148 if (signRight==-1)
00149 ret.add(SetExprCode::COMPLEMENT);
00150 switch (rel) {
00151 case REL_INTER: ret.add(SetExprCode::INTER); break;
00152 case REL_UNION: ret.add(SetExprCode::UNION); break;
00153 default:
00154 GECODE_NEVER;
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 SetExpr::SetExpr(var_idx v) : ax(new Node(v)), sign(1) {}
00165
00166 SetExpr::SetExpr(const SetExpr& s, int ssign,
00167 RelType r,
00168 const SetExpr& t, int tsign)
00169 : ax(new Node(s.ax,s.sign*ssign,r,t.ax,t.sign*tsign)), sign(1) {}
00170
00171 SetExpr::SetExpr(const SetExpr& s, int sign)
00172 : ax(s.ax), sign(s.sign*sign) {
00173 if (ax != NULL)
00174 ax->increment();
00175 }
00176
00177 SetExpr::SetExpr(const SetExpr& s)
00178 : ax(s.ax), sign(s.sign) {
00179 if (ax != NULL)
00180 ax->increment();
00181 }
00182
00183 const SetExpr&
00184 SetExpr::operator=(const SetExpr& s) {
00185 if (this != &s) {
00186 if ((ax != NULL) && ax->decrement())
00187 delete ax;
00188 ax = s.ax;
00189 sign = s.sign;
00190 if (ax != NULL)
00191 ax->increment();
00192 }
00193 return *this;
00194 }
00195
00196 SetExpr::~SetExpr(void) {
00197 if ((ax != NULL) && ax->decrement())
00198 delete ax;
00199 }
00200
00201 int
00202 SetExpr::arity(void) const {
00203 return (ax==NULL) ? 0 : ax->arity();
00204 }
00205
00206 SetExprCode
00207 SetExpr::encode(void) const {
00208 SetExprCode ret;
00209 if (ax==NULL) {
00210 ret.add((sign==1) ? SetExprCode::EMPTY : SetExprCode::UNIVERSE);
00211 } else if (sign==-1) {
00212 ax->encode(ret, false);
00213 ret.add(SetExprCode::COMPLEMENT);
00214 } else {
00215 ax->encode(ret, true);
00216 }
00217 return ret;
00218 }
00219
00220 Iter::Ranges::Virt::Iterator*
00221 codeToIterator(const ViewArray<Set::SetView>& x,
00222 const SetExprCode& c, bool monotone) {
00223
00224 typedef Iter::Ranges::Virt::Iterator Iterator;
00225
00226 Support::DynamicStack<Iterator*> s;
00227
00228 int tmp = 0;
00229 for (int i=0; i<c.size(); i++) {
00230 switch (c[i]) {
00231 case SetExprCode::COMPLEMENT:
00232 {
00233 Iterator* it = s.pop();
00234 s.push(new Iter::Ranges::Virt::Compl<Limits::Set::int_min,
00235 Limits::Set::int_max> (it));
00236 }
00237 break;
00238 case SetExprCode::INTER:
00239 {
00240 Iterator* ri = s.pop();
00241 Iterator* li = s.pop();
00242 s.push(new Iter::Ranges::Virt::Inter(li, ri));
00243 }
00244 break;
00245 case SetExprCode::UNION:
00246 {
00247 Iterator* ri = s.pop();
00248 Iterator* li = s.pop();
00249 s.push(new Iter::Ranges::Virt::Union(li, ri));
00250 }
00251 break;
00252 case SetExprCode::GLB:
00253 if (monotone) {
00254 GlbRanges<SetView> r(x[tmp]);
00255 s.push(new Iter::Ranges::Virt::RangesTemplate<GlbRanges<SetView> >(r));
00256 } else {
00257 LubRanges<SetView> r(x[tmp]);
00258 s.push(new Iter::Ranges::Virt::RangesTemplate<LubRanges<SetView> >(r));
00259 }
00260 break;
00261 case SetExprCode::LUB:
00262 if (monotone) {
00263 LubRanges<SetView> r(x[tmp]);
00264 s.push(new Iter::Ranges::Virt::RangesTemplate<LubRanges<SetView> >(r));
00265 } else {
00266 GlbRanges<SetView> r(x[tmp]);
00267 s.push(new Iter::Ranges::Virt::RangesTemplate<GlbRanges<SetView> >(r));
00268 }
00269 break;
00270 case SetExprCode::EMPTY:
00271 {
00272 Iter::Ranges::Singleton it(1,0);
00273 s.push(new Iter::Ranges::Virt::RangesTemplate<Iter::Ranges::Singleton> (it));
00274 }
00275 break;
00276 case SetExprCode::UNIVERSE:
00277 {
00278 Iter::Ranges::Singleton it(Limits::Set::int_min,
00279 Limits::Set::int_max);
00280 s.push(new Iter::Ranges::Virt::RangesTemplate<Iter::Ranges::Singleton> (it));
00281 }
00282 break;
00283 default:
00284 tmp = c[i]-SetExprCode::LAST;
00285 break;
00286 }
00287 }
00288
00289 return s.top();
00290 }
00291
00292 SetExprRanges::SetExprRanges(const ViewArray<Set::SetView>& x,
00293 SetExpr& s,
00294 bool monotone) {
00295 i = new Iter(codeToIterator(x, s.encode(), monotone));
00296 }
00297
00298 SetExprRanges::SetExprRanges(const ViewArray<Set::SetView>& x,
00299 const SetExprCode& c,
00300 bool monotone) {
00301 i = new Iter(codeToIterator(x, c, monotone));
00302 }
00303
00304 }
00305
00306