00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00028 #ifndef _SEARCH_NODE_HPP_
00029 #define _SEARCH_NODE_HPP_
00030
00031 #include <wnodectx.h>
00032
00033 namespace coco {
00034
00035 inline search_node::search_node(const search_node_id& _i, const vdbl::userid& _dui,
00036 gptr<search_node>& _gm, gptr<vdbl::database>& _db,
00037 search_node_relation __snr)
00038 : __global_model(new ptr<search_node>(*_gm)),
00039 __dbase(new ptr<vdbl::database>(*_db)),
00040 _dbuser(_dui), _snr(__snr), _id(_i), _keep(), _rid(VDBL_MAXROWID)
00041 {}
00042
00043 inline search_node::search_node(const search_node_id& _i, const vdbl::userid& _dui,
00044 gptr<search_node>* _gm, gptr<vdbl::database>& _db,
00045 search_node_relation __snr)
00046 : __global_model(_gm?new ptr<search_node>(**_gm):NULL),
00047 __dbase(new ptr<vdbl::database>(*_db)),
00048 _dbuser(_dui), _snr(__snr), _id(_i), _keep(), _rid(VDBL_MAXROWID)
00049 {}
00050
00051 inline search_node::search_node(const search_node& __sn)
00052 : __global_model(
00053 __sn.__global_model?new ptr<search_node>(**__sn.__global_model):NULL),
00054 __dbase(__sn.__dbase?new ptr<vdbl::database>(**__sn.__dbase):NULL),
00055 _dbuser(__sn._dbuser), _snr(__sn._snr), _id(__sn._id), _keep(__sn._keep),
00056 _rid(__sn._rid)
00057 {}
00058
00059 inline search_node::search_node(const search_node_id& _i, const vdbl::userid& _dui,
00060 gptr<vdbl::database>& _db,
00061 search_node_relation __snr)
00062 : __global_model(NULL), __dbase(new ptr<vdbl::database>(*_db)),
00063 _dbuser(_dui), _snr(__snr), _id(_i), _keep(), _rid(VDBL_MAXROWID)
00064 {}
00065
00066 inline search_node::~search_node()
00067 {
00068 if(__dbase)
00069 {
00070 vdbl::database *_db = (*__dbase).get_local_copy();
00071 for(std::vector<annotation>::iterator __x = _keep.begin();
00072 __x != _keep.end(); ++__x)
00073 {
00074 vdbl::table* _dbt = (vdbl::table*)_db->get_table(__x->get_table(), _dbuser);
00075 _dbt->remove(__x->get_entry());
00076 }
00077 delete __dbase;
00078 }
00079 if(__global_model) delete __global_model;
00080 }
00081
00082 inline void search_node::unkeep(const annotation& _an)
00083 {
00084 for(std::vector<annotation>::iterator __x = _keep.begin();
00085 __x != _keep.end(); ++__x)
00086 if(_an == *__x)
00087 {
00088 _keep.erase(__x);
00089 break;
00090 }
00091 }
00092
00093 inline void search_node::unkeep(const std::vector<annotation>& _anv)
00094 {
00095 for(std::vector<annotation>::const_iterator __x = _anv.begin();
00096 __x != _anv.end(); ++__x)
00097 unkeep(*__x);
00098 }
00099
00100 inline work_node::work_node(const work_node& __w)
00101 : _Base(__w),
00102 deltas(__w.deltas),
00103 parents_in_graph(__w.parents_in_graph),
00104 undeltas(__w.undeltas),
00105 dtable(__w.dtable),
00106 dtable_id(__w.dtable_id),
00107 gitable(__w.gitable),
00108 gitable_id(__w.gitable_id),
00109 wnc(new work_node_context(this)),
00110 __vdb(new vdbl::viewdbase(
00111 *this->database()->get_local_copy(),
00112 this->get_dbuserid(), *wnc,
00113 std::vector<std::pair<vdbl::tableid,vdbl::rowid> >(
00114 this->get_annotations().begin(),
00115 this->get_annotations().end()))),
00116 __vdbf(__w.__vdbf),
00117 node_ranges(__w.node_ranges),
00118 node_order(__w.node_order),
00119 infeasible(__w.infeasible),
00120 log_vol(__w.log_vol),
00121 gain_factor(__w.gain_factor),
00122 globalinfo(__w.globalinfo),
00123 _tnum(__w._tnum),
00124 proposed_splits(__w.proposed_splits),
00125 split_delta_ids(__w.split_delta_ids),
00126 n_bds(__w.n_bds),
00127 n_lin(__w.n_lin),
00128 n_quad(__w.n_quad),
00129 n_poly(__w.n_poly),
00130 n_other(__w.n_other)
00131 {
00132 set_deltanew_it(__w);
00133 }
00134
00135 inline work_node::~work_node() { delete __vdb; delete wnc; }
00136
00137 inline work_node::constraint_const_iterator
00138 work_node::get_begin(unsigned int __type) const
00139 {
00140 constraint_const_iterator __tmp((*_m)->constraints, __type);
00141 __tmp.set((*_m)->constraints.begin());
00142 return(__tmp);
00143 }
00144
00145 inline work_node::constraint_const_iterator
00146 work_node::get_end(unsigned int __type) const
00147 {
00148 constraint_const_iterator __tmp((*_m)->constraints, __type);
00149 __tmp.set((*_m)->constraints.end());
00150 return(__tmp);
00151 }
00152
00153 inline work_node::constraint_iterator work_node::get_begin(unsigned int __type)
00154 {
00155 constraint_iterator __tmp((*_m)->constraints, __type);
00156 __tmp.set((*_m)->constraints.begin());
00157 return(__tmp);
00158 }
00159
00160 inline work_node::constraint_iterator work_node::get_end(unsigned int __type)
00161 {
00162 constraint_iterator __tmp((*_m)->constraints, __type);
00163 __tmp.set((*_m)->constraints.end());
00164 return(__tmp);
00165 }
00166
00167 }
00168
00169 #include <api_delta.h>
00170 #include <api_cert.h>
00171
00172 namespace coco {
00173
00174 inline search_node& search_node::operator=(const search_node& __w)
00175 {
00176 if(this != &__w)
00177 {
00178 if(__global_model) delete __global_model;
00179 if(__w.__global_model)
00180 __global_model = new ptr<search_node>(**__w.__global_model);
00181 else
00182 __global_model = NULL;
00183 if(__dbase) delete __dbase;
00184 if(__w.__dbase)
00185 __dbase = new ptr<vdbl::database>(**__w.__dbase);
00186 else
00187 __dbase = NULL;
00188 _dbuser = __w._dbuser;
00189 _snr = __w._snr;
00190 _id = __w._id;
00191 _rid = __w._rid;
00192 _keep = __w._keep;
00193 }
00194 return *this;
00195 }
00196
00197 inline delta_node& delta_node::operator=(const delta_node& __w)
00198 {
00199 if(this != &__w)
00200 {
00201 ((_DBase*)this)->_DBase::operator=(*(_DBase*)&__w);
00202 di = __w.di;
00203 }
00204 return *this;
00205 }
00206
00207 inline full_node& full_node::operator=(const full_node& __w)
00208 {
00209 if(this != &__w)
00210 {
00211 if(_m) delete _m;
00212 ((_FBase*)this)->_FBase::operator=(*(_FBase*)&__w);
00213 if(__w._m)
00214 _m = new ptr<model>(**__w._m);
00215 else
00216 _m = NULL;
00217 _ann = __w._ann;
00218 }
00219 return *this;
00220 }
00221
00222 inline work_node& work_node::operator=(const full_node& __f)
00223 {
00224 if(this != &__f)
00225 {
00226 ((_Base*)this)->_Base::operator=(*(_Base*)&__f);
00227 deltas.clear();
00228 undeltas.clear();
00229 node_ranges.clear();
00230 node_order.clear();
00231 infeasible = false;
00232 gain_factor = 1.;
00233 _tnum = 0;
00234 proposed_splits.clear();
00235 n_bds = 0;
00236 n_lin = 0;
00237 n_quad = 0;
00238 n_poly = 0;
00239 n_other = 0;
00240 if(__vdb) delete __vdb;
00241 if(wnc) delete wnc;
00242 wnc = new work_node_context(this);
00243 __vdb = new vdbl::viewdbase(*this->database()->get_local_copy(),
00244 this->get_dbuserid(), *wnc,
00245 std::vector<std::pair<vdbl::tableid,vdbl::rowid> >(
00246 this->get_annotations().begin(),
00247 this->get_annotations().end()));
00248 init_all();
00249 set_rowid(__f.get_rowid());
00250 }
00251 return *this;
00252 }
00253
00254 inline work_node& work_node::operator=(const work_node& __w)
00255 {
00256 if(this != &__w)
00257 {
00258 ((_Base*)this)->_Base::operator=(*(_Base*)&__w);
00259 deltas = __w.deltas;
00260 parents_in_graph = __w.parents_in_graph;
00261 undeltas = __w.undeltas;
00262 dtable = __w.dtable;
00263 dtable_id = __w.dtable_id;
00264 gitable = __w.gitable;
00265 gitable_id = __w.gitable_id;
00266 node_ranges = __w.node_ranges;
00267 node_order = __w.node_order;
00268 infeasible = __w.infeasible;
00269 log_vol = __w.log_vol;
00270 gain_factor = __w.gain_factor;
00271 globalinfo = __w.globalinfo;
00272 _tnum = __w._tnum;
00273 proposed_splits = __w.proposed_splits;
00274 split_delta_ids = __w.split_delta_ids;
00275 n_bds = __w.n_bds;
00276 n_lin = __w.n_lin;
00277 n_quad = __w.n_quad;
00278 n_poly = __w.n_poly;
00279 n_other = __w.n_other;
00280 set_deltanew_it(__w);
00281 if(__vdb) delete __vdb;
00282 if(wnc) delete wnc;
00283 wnc = new work_node_context(this);
00284 __vdb = new vdbl::viewdbase(*this->database()->get_local_copy(),
00285 this->get_dbuserid(), *wnc,
00286 std::vector<std::pair<vdbl::tableid,vdbl::rowid> >(
00287 this->get_annotations().begin(),
00288 this->get_annotations().end()));
00289 __vdbf = __w.__vdbf;
00290 }
00291 return *this;
00292 }
00293
00295
00297 inline work_node operator+(const work_node& _w, const delta_id& _i)
00298 {
00299 work_node _tmp(_w);
00300 const delta& _d(const_cast<const work_node *>(&_tmp)->get_delta(_i));
00301 if(!_d.apply3(_tmp, _w, _i))
00302 std::cerr << "Warning: Could not apply delta <" <<
00303 _i << "> to work node <" << _tmp.get_id() << ">!" << std::endl;
00304 return _tmp;
00305 }
00306
00308
00310 inline work_node& operator+=(work_node& _w, const delta_id& _i)
00311 {
00312 const delta& _d(const_cast<const work_node&>(_w).get_delta(_i));
00313 if(!_d.apply(_w, _i))
00314 std::cerr << "Warning: Could not apply delta <" <<
00315 _i << "> to work node <" << _w.get_id() << ">!" << std::endl;
00316 return _w;
00317 }
00318
00320
00323 template <template <class _Tp, class _TA> class _Ctr, class _Al>
00324 inline work_node operator+(const work_node& _w, const _Ctr<delta_id, _Al>& _d)
00325 {
00326 work_node _tmp(_w);
00327 typename _Ctr<delta_id, _Al>::const_iterator __b, __e;
00328
00329 __e = _d.end();
00330 for(__b = _d.begin(); __b != __e; ++__b)
00331 _tmp += *__b;
00332 return _tmp;
00333 }
00334
00336
00339 template <template <class _Tp, class _TA> class _Ctr, class _Al>
00340 inline work_node& operator+=(work_node& _w, const _Ctr<delta_id, _Al>& _d)
00341 {
00342 typename _Ctr<delta_id, _Al>::const_iterator __b, __e;
00343
00344 __e = _d.end();
00345 for(__b = _d.begin(); __b != __e; ++__b)
00346 _w += *__b;
00347 return _w;
00348 }
00349
00351
00353 work_node operator-(const work_node& _w, const delta_id& _d);
00355
00357 work_node& operator-=(work_node& _w, const delta_id& _d);
00358
00360
00363 template <template <class _Tp, class _TA> class _Ctr, class _Al>
00364 inline work_node operator-(const work_node& _w, const _Ctr<delta_id, _Al>& _d)
00365 {
00366 work_node _tmp(_w);
00367 typedef typename _Ctr<delta_id, _Al>::const_iterator _Ccit;
00368 typedef typename std::reverse_iterator<_Ccit> _rCcit;
00369 _rCcit __b, __e;
00370
00371 __e = _d.rend();
00372 for(__b = _d.rbegin(); __b != __e; ++__b)
00373 _tmp -= *__b;
00374 return _tmp;
00375 }
00376
00378
00381 template <template <class _Tp, class _TA> class _Ctr, class _Al>
00382 inline work_node& operator-=(work_node& _w, const _Ctr<delta_id, _Al>& _d)
00383 {
00384 typedef typename _Ctr<delta_id, _Al>::const_iterator _Ccit;
00385 typedef typename std::reverse_iterator<_Ccit> _rCcit;
00386 _rCcit __b, __e;
00387
00388 __e = _d.rend();
00389 for(__b = _d.rbegin(); __b != __e; ++__b)
00390 _w -= *__b;
00391 return _w;
00392 }
00393
00394 inline delta delta_node::get_delta(unsigned int i)
00395 {
00396 vdbl::standard_table* dt =
00397 (vdbl::standard_table*)(*database())->get_table("deltas", get_dbuserid());
00398 vdbl::alltype<delta> *_at;
00399 vdbl::context _ctxdummy;
00400 bool ret = dt->retrieve(get_delta_id(i), dt->get_col_id("delta"), &_ctxdummy,
00401 (vdbl::alltype_base*&)_at);
00402 if(ret == false)
00403 throw api_exception(apiee_internal,
00404 "delta_node::get_delta: Database inconsistency: unkown delta");
00405 return _at->content();
00406 }
00407
00408 inline const delta& delta_node::get_delta(unsigned int i) const
00409 {
00410 vdbl::standard_table* dt =
00411 (vdbl::standard_table*)(*database())->
00412 get_table("deltas", get_dbuserid());
00413 vdbl::alltype<delta> *_at;
00414 vdbl::context _ctxdummy;
00415 bool ret = dt->retrieve(get_delta_id(i), dt->get_col_id("delta"), &_ctxdummy,
00416 (vdbl::alltype_base*&)_at);
00417 if(ret == false)
00418 throw api_exception(apiee_internal,
00419 "delta_node::get_delta: Database inconsistency: unkown delta");
00420 return _at->content();
00421 }
00422
00423 inline delta work_node::get_delta(const delta_id& _id)
00424 {
00425 bool error;
00426 const vdbl::row &_r(dtable->get_row(_id, error));
00427 if(error)
00428 throw api_exception(apiee_internal,
00429 "work_node::get_delta: Database inconsistency: unkown delta");
00430 const vdbl::col &_c(_r.get_col(dtable->get_col_id("delta"), error));
00431 if(error)
00432 throw api_exception(apiee_internal,
00433 "work_node::get_delta: Database inconsistency: delta table malformed!");
00434 delta _d;
00435 _c.get(_d);
00436 return _d;
00437 }
00438
00439 inline const delta& work_node::get_delta(const delta_id& _id) const
00440 {
00441 bool error;
00442 const vdbl::row *_r(dtable->get_row_ptr(_id));
00443 if(_r == NULL)
00444 throw api_exception(apiee_internal,
00445 "work_node::get_delta: Database inconsistency: unkown delta");
00446 const vdbl::col &_c(_r->get_col(dtable->get_col_id("delta"), error));
00447 if(error)
00448 throw api_exception(apiee_internal,
00449 "work_node::get_delta: Database inconsistency: delta table malformed!");
00450 const vdbl::typed_col<delta> *_cp =
00451 (const vdbl::typed_col<delta>*)_c.get_ptr_to_val();
00452 return _cp->get_val();
00453 }
00454
00455 inline certificate work_node::get_certificate(const delta_id& _id)
00456 {
00457 bool error;
00458 const vdbl::row &_r(dtable->get_row(_id, error));
00459 if(error)
00460 throw api_exception(apiee_internal,
00461 "work_node::get_certificate: Database inconsistency: unkown delta");
00462 vdbl::colid _cci(dtable->get_col_id("certificate"));
00463 const vdbl::col &_c(_r.get_col(_cci, error));
00464 certificate _C;
00465 if(error)
00466 {
00467 const vdbl::col &_d(dtable->get_def(_cci, error));
00468 if(error)
00469 throw api_exception(apiee_internal,
00470 "work_node::get_certificate: Database inconsistency: delta table malformed!");
00471 else
00472 _d.get(_C);
00473 }
00474 else
00475 _c.get(_C);
00476 return _C;
00477 }
00478
00479 inline const certificate& work_node::get_certificate(const delta_id& _id) const
00480 {
00481 bool error;
00482 const vdbl::row *_r(dtable->get_row_ptr(_id));
00483 if(_r == NULL)
00484 throw api_exception(apiee_internal,
00485 "work_node::get_certificate: Database inconsistency: unkown delta");
00486 vdbl::colid _cci(dtable->get_col_id("certificate"));
00487 const vdbl::col &_c(_r->get_col(_cci, error));
00488 const vdbl::typed_col<certificate> *_cp;
00489 if(error)
00490 {
00491 const vdbl::col &_d(dtable->get_def(_cci, error));
00492 if(error)
00493 throw api_exception(apiee_internal,
00494 "work_node::get_certificate: Database inconsistency: delta table malformed!");
00495 else
00496 _cp = (const vdbl::typed_col<certificate>*)_d.get_ptr_to_val();
00497 }
00498 else
00499 _cp = (const vdbl::typed_col<certificate>*)_c.get_ptr_to_val();
00500 return _cp->get_val();
00501 }
00502
00503 inline void work_node::reset_node_ranges()
00504
00505 {
00506 unsigned int n = (**_m).number_of_nodes();
00507
00508 for(unsigned int i = 0; i < n; ++i)
00509 if((**_m).node(i) == (**_m).ground())
00510 node_ranges.push_back(interval(-COCO_INF,COCO_INF));
00511 }
00512
00513 inline unsigned int work_node::n(unsigned int __type) const
00514 {
00515 unsigned int h=0;
00516 std::vector<expression_walker>::const_iterator __b, __e;
00517
00518 if(!(__type & ~ex_any))
00519 {
00520 if(__type & ex_bound)
00521 h += n_bds;
00522 if(__type & ex_linear)
00523 h += n_lin;
00524 if(__type & ex_quadratic)
00525 h += n_quad;
00526 if(__type & ex_polynomial)
00527 h += n_poly;
00528 if(__type & ex_other)
00529 h += n_other;
00530 }
00531 else
00532 {
00533 __e = (**_m).constraints.end();
00534 for(__b = (**_m).constraints.begin(); __b != __e; ++__b)
00535 if((*__b)->is(__type))
00536 h++;
00537 }
00538 return h;
00539 }
00540
00541 inline void work_node::set_deltanew_it(const work_node& __w)
00542 {
00543
00544
00545 deltanew_it = deltas.end();
00546 if ( ! deltas.empty() ) {
00547 std::list<delta_id>::const_iterator dit = __w.deltas.end();
00548 while ( (dit != __w.deltanew_it) && (dit != __w.deltas.begin()) )
00549 {
00550 dit--;
00551 deltanew_it--;
00552 }
00553 if ( (dit != __w.deltanew_it) && (dit == __w.deltas.begin()) )
00554 {
00555 throw api_exception(apiee_internal,
00556 "work_node::set_deltanew_it: Unable to find a properly set deltanew_it!");
00557 }
00558 }
00559
00560 }
00561
00562 template <class _TW, class _TV, class _VR, class _TP, class _TR, class _TI>
00563 inline
00564 typename work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::_Self&
00565 work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::set(
00566 const _Iterator& _c)
00567 {
00568 for(__c_cur = _c; __c_cur != (*__cs).end(); ++__c_cur)
00569 {
00570 if((*__c_cur)->is(__tp))
00571 break;
00572 }
00573 return *this;
00574 }
00575
00576 template <class _TW, class _TV, class _VR, class _TP, class _TR, class _TI>
00577 inline
00578 typename work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::_Self&
00579 work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::operator++()
00580 {
00581 if(__c_cur != (*__cs).end())
00582 ++__c_cur;
00583 for(; __c_cur != (*__cs).end(); ++__c_cur)
00584 {
00585 if((*__c_cur)->is(__tp))
00586 break;
00587 }
00588 return *this;
00589 }
00590
00591 template <class _TW, class _TV, class _VR, class _TP, class _TR, class _TI>
00592 inline
00593 typename work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::_Self
00594 work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::operator++(int)
00595 {
00596 _Self __tmp = *this;
00597 ++__tmp;
00598 return __tmp;
00599 }
00600
00601 template <class _TW, class _TV, class _VR, class _TP, class _TR, class _TI>
00602 inline
00603 typename work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::_Self&
00604 work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::operator--()
00605 {
00606 if(__c_cur == (*__cs).begin())
00607 __c_cur = (*__cs).end();
00608 else if(__c_cur != (*__cs).end())
00609 --__c_cur;
00610 for(; __c_cur != (*__cs).begin(); --__c_cur)
00611 {
00612 if((*__c_cur)->is(__tp))
00613 break;
00614 }
00615 if(__c_cur == (*__cs).begin() && !(*__c_cur)->is(__tp))
00616 __c_cur = (*__cs).end();
00617 return *this;
00618 }
00619
00620 template <class _TW, class _TV, class _VR, class _TP, class _TR, class _TI>
00621 inline
00622 typename work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::_Self
00623 work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::operator--(int)
00624 {
00625 _Self __tmp = *this;
00626 --__tmp;
00627 return __tmp;
00628 }
00629
00630 template <class _TW, class _TV, class _VR, class _TP, class _TR, class _TI>
00631 inline
00632 typename work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::_Self&
00633 work_node::constraint_iterator_base<_TW,_TV,_VR,_TP,_TR,_TI>::operator=(
00634 const _Self& _c)
00635 {
00636 if (this != & _c) {
00637 __cs = _c.__cs;
00638 __c_cur = _c.__c_cur;
00639 __tp = _c.__tp;
00640 }
00641 return *this;
00642 }
00643
00644 }
00645 #endif // _SEARCH_NODE_HPP_