00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00027 #ifndef _SEARCH_NODE_H
00028 #define _SEARCH_NODE_H
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <iostream>
00038 #include <interval.h>
00039 #include <coconut_config.h>
00040 #include <model.h>
00041 #include <annotation.h>
00042 #include <map>
00043 #include <set>
00044 #include <list>
00045 #include <string>
00046 #include <gptr.h>
00047 #include <stdint.h>
00048 #include <database>
00049 #include <db_alltype>
00050
00051 using namespace vgtl;
00052
00053 #include <api_deltabase.h>
00054
00055 typedef enum {
00056 snr_root,
00057 snr_reduction,
00058 snr_relaxation,
00059 snr_split,
00060 snr_glue,
00061 snr_worknode,
00062 snr_virtual,
00063 } search_node_relation;
00064
00065 typedef uint32_t search_node_id;
00066
00067 #if 0
00068 class id_data
00069 {
00070 search_node_id _maxid;
00071
00072 vdbl::userid _dbuser;
00073
00074 public:
00075 id_data(const vdbl::userid& _dbu = vdbl::userid())
00076 : _maxid(0),
00077 _dbuser(_dbu) {}
00078
00079 search_node_id get_search_node_id() { return _maxid++; }
00080
00081 vdbl::userid get_dbuserid() const { return _dbuser; }
00082 };
00083 #endif
00084
00085 class search_node
00086 {
00087 protected:
00088 gptr<search_node>* __global_model;
00089 gptr<vdbl::database>* __dbase;
00090 vdbl::userid _dbuser;
00091 search_node_relation _snr;
00092 search_node_id _id;
00093 std::vector<annotation> _keep;
00094
00095 protected:
00096 search_node_id node_id() const { return _id; }
00097 search_node_relation parent_relation() const { return _snr; }
00098
00099 public:
00100 virtual bool is_delta() const { return false; }
00101
00102 search_node(const search_node_id& _i, const vdbl::userid& _dui,
00103 gptr<search_node>& _gm, gptr<vdbl::database>& _db,
00104 search_node_relation __snr = snr_reduction)
00105 :
00106 __global_model(&_gm), __dbase(&_db), _dbuser(_dui),
00107 _snr(__snr), _id(_i), _keep() {}
00108
00109 search_node(const search_node_id& _i, const vdbl::userid& _dui,
00110 gptr<search_node>* _gm, gptr<vdbl::database>& _db,
00111 search_node_relation __snr = snr_reduction)
00112 : __global_model(_gm), __dbase(&_db), _dbuser(_dui),
00113 _snr(__snr), _id(_i), _keep() {}
00114
00115 search_node(const search_node& __sn) : __global_model(__sn.__global_model),
00116 __dbase(__sn.__dbase), _dbuser(__sn._dbuser),
00117 _snr(__sn._snr), _id(__sn._id), _keep(__sn._keep) {}
00118
00119 search_node(const search_node_id& _i, const vdbl::userid& _dui,
00120 gptr<vdbl::database>& _db, search_node_relation __snr = snr_root)
00121 : __global_model(NULL), __dbase(&_db), _dbuser(_dui),
00122 _snr(__snr), _id(_i), _keep()
00123 {
00124 if(__dbase == NULL)
00125 {
00126 vdbl::database *__db = new vdbl::database;
00127 __dbase = new ptr<vdbl::database>(__db);
00128 }
00129 }
00130
00131 virtual ~search_node()
00132 {
00133 vdbl::database *_db = (*__dbase).get_local_copy();
00134 for(std::vector<annotation>::iterator __x = _keep.begin();
00135 __x != _keep.end(); ++__x)
00136 {
00137 vdbl::table* _dbt = (vdbl::table*)_db->get_table(__x->get_table(),
00138 _dbuser);
00139 _dbt->remove(__x->get_entry());
00140 }
00141 }
00142
00143 vdbl::userid get_dbuserid() const { return _dbuser; }
00144
00145 gptr<search_node>* global_model() const { return __global_model; }
00146
00147 gptr<vdbl::database>* database() const { return __dbase; }
00148
00149 search_node_id get_id() const { return _id; }
00150
00151 void keep(const annotation& _an) { _keep.push_back(_an); }
00152
00153 void keep(const std::vector<annotation>& _anv)
00154 { _keep.insert(_keep.end(), _anv.begin(), _anv.end()); }
00155
00156 void unkeep(const annotation& _an)
00157 {
00158 for(std::vector<annotation>::iterator __x = _keep.begin();
00159 __x != _keep.end(); ++__x)
00160 if(_an == *__x)
00161 {
00162 _keep.erase(__x);
00163 break;
00164 }
00165 }
00166
00167 void unkeep(const std::vector<annotation>& _anv)
00168 {
00169 for(std::vector<annotation>::const_iterator __x = _anv.begin();
00170 __x != _anv.end(); ++__x)
00171 unkeep(*__x);
00172 }
00173
00174 friend class search_graph;
00175 };
00176
00177 class delta_node : public search_node
00178 {
00179 private:
00180 std::vector<delta_id> di;
00181
00182 public:
00183
00184 delta_node(const search_node_id& _i, const vdbl::userid& _dui,
00185 std::vector<delta_id>& __d, gptr<search_node>& _gm,
00186 gptr<vdbl::database>& _db,
00187 search_node_relation _snr = snr_reduction)
00188 : search_node(_i, _dui, _gm, _db, _snr), di(__d)
00189 {}
00190
00191 virtual ~delta_node() {}
00192
00193 bool is_delta() const { return true; }
00194
00195 unsigned int n_deltas() const { return di.size(); }
00196
00197 delta_id get_delta_id(unsigned int i) const
00198 {
00199 return di[i];
00200 }
00201
00202 delta get_delta(unsigned int i);
00203
00204 const delta& get_delta(unsigned int i) const;
00205 };
00206
00207 class full_node : public search_node
00208 {
00209 protected:
00210 gptr<model>* _m;
00211
00212 public:
00213 std::vector<annotation> _ann;
00214
00215 protected:
00216 full_node(const search_node_id& _i, const vdbl::userid& _dui,
00217 gptr<model>& __mod, gptr<search_node>* _gm,
00218 gptr<vdbl::database>& _db,
00219 search_node_relation _snr = snr_reduction)
00220 : search_node(_i, _dui, _gm, _db, _snr), _ann()
00221 {
00222 _m = &__mod;
00223 }
00224
00225 full_node(const search_node_id& _i, const vdbl::userid& _dui,
00226 gptr<model>& __mod, gptr<search_node>* _gm,
00227 gptr<vdbl::database>& _db, const std::vector<annotation>& _a,
00228 search_node_relation _snr = snr_reduction)
00229 : search_node(_i, _dui, _gm, _db, _snr), _ann(_a)
00230 {
00231 _m = &__mod;
00232 }
00233
00234 public:
00235
00236 full_node(const search_node_id& _i, const vdbl::userid& _dui,
00237 gptr<model>& __mod, gptr<search_node>& _gm,
00238 gptr<vdbl::database>& _db,
00239 search_node_relation _snr = snr_reduction) :
00240 search_node(_i, _dui, _gm, _db, _snr), _ann()
00241 {
00242 _m = &__mod;
00243 }
00244
00245 full_node(const search_node_id& _i, const vdbl::userid& _dui,
00246 gptr<model>& __mod, gptr<search_node>& _gm,
00247 gptr<vdbl::database>& _db, const std::vector<annotation>& _a,
00248 search_node_relation _snr = snr_reduction) :
00249 search_node(_i, _dui, _gm, _db, _snr), _ann(_a)
00250 {
00251 _m = &__mod;
00252 }
00253
00254 virtual ~full_node() {}
00255
00256 bool is_delta() const { return false; }
00257
00258 const annotation& get_annotation(unsigned int i) const
00259 {
00260 return _ann[i];
00261 }
00262
00263 const std::vector<annotation>& get_annotations() const
00264 {
00265 return _ann;
00266 }
00267
00268 const model* get_model() const { return (*_m).get_local_copy(); }
00269
00270 const vdbl::database* get_database() const
00271 { return (*database()).get_local_copy(); }
00272
00273 model* get_model_ptr() const
00274 {
00275 return (*_m).get_local_copy();
00276 }
00277
00278 vdbl::database* get_database_ptr() const
00279 {
00280 return (*database()).get_local_copy();
00281 }
00282
00283 friend class delta_base;
00284 friend class dag_delta;
00285 friend class dag_undelta;
00286 };
00287
00288 class work_node : public full_node
00289 {
00290 private:
00291 typedef full_node _Base;
00292
00293 public:
00294 template <class _W, class _V, class _VR, class _P, class _R, class _I>
00295 class constraint_iterator_base;
00296
00297 typedef constraint_iterator_base<model::walker,const std::vector<model::walker>*,
00298 const std::vector<model::walker>&,const model::walker*,
00299 const model::walker&,
00300 std::vector<model::walker>::const_iterator> constraint_const_iterator;
00301 typedef constraint_iterator_base<model::walker,std::vector<model::walker>*,
00302 std::vector<model::walker>&,model::walker*,model::walker&,
00303 std::vector<model::walker>::iterator> constraint_iterator;
00304
00305 public:
00306 std::list<delta_id> deltas;
00307 std::map<delta_id,undelta> undeltas;
00308 vdbl::standard_table *dtable;
00309 vdbl::tableid dtable_id;
00310
00311
00312
00313 public:
00314 std::vector<interval> node_ranges;
00315 bool infeasible;
00316
00317 double log_vol;
00318 double gain_factor;
00319
00320 public:
00321 typedef uint32_t transaction_number;
00322
00323 private:
00324 transaction_number _tnum;
00325
00326 public:
00327 transaction_number get_transaction_number() { return ++_tnum; }
00328
00329 public:
00330 std::map<transaction_number,std::list<std::vector<delta> > > proposed_splits;
00331
00332 private:
00333 unsigned int n_bds;
00334 unsigned int n_lin;
00335 unsigned int n_quad;
00336 unsigned int n_poly;
00337 unsigned int n_other;
00338
00339 public:
00340 void init_cnumbers();
00341 void reset_node_ranges();
00342 void make_node_ranges(bool keep_old_ranges);
00343 double compute_log_volume(const std::vector<interval>& _r) const;
00344
00345 public:
00346 work_node(const work_node& __w) :
00347 _Base(__w),
00348 deltas(__w.deltas),
00349 undeltas(__w.undeltas),
00350 dtable(__w.dtable),
00351 dtable_id(__w.dtable_id),
00352 node_ranges(__w.node_ranges),
00353 infeasible(__w.infeasible),
00354 log_vol(__w.log_vol),
00355 gain_factor(__w.gain_factor),
00356 _tnum(__w._tnum),
00357 proposed_splits(__w.proposed_splits),
00358 n_bds(__w.n_bds),
00359 n_lin(__w.n_lin),
00360 n_quad(__w.n_quad),
00361 n_poly(__w.n_poly),
00362 n_other(__w.n_other)
00363 {}
00364
00365 work_node(const search_node_id& _i, const vdbl::userid& _dui,
00366 gptr<model>& __m, gptr<vdbl::database>& __d,
00367 const std::vector<annotation>& __an,
00368 const std::list<delta_id>& __de, gptr<search_node>* _gm,
00369 search_node_relation snr = snr_worknode);
00370
00371 virtual ~work_node() {}
00372
00373 const model* get_model() const { return (*_m).get_local_copy(); }
00374 model* get_model() { return (*_m).get_local_copy(); }
00375
00376 public:
00377
00378
00379
00380 model get(unsigned int __type);
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 constraint_const_iterator get_begin(unsigned int __type) const;
00393 constraint_const_iterator get_end(unsigned int __type) const;
00394
00395 constraint_iterator get_begin(unsigned int __type);
00396 constraint_iterator get_end(unsigned int __type);
00397
00398 delta get_delta(const delta_id& _id);
00399
00400 const delta& get_delta(const delta_id& _id) const;
00401
00402 double log_volume() const { return log_vol; }
00403 double gain() const { return gain_factor; }
00404 double reset_gain() {double ret = gain_factor; gain_factor = 1.; return ret;}
00405
00406
00407
00408 unsigned int n(unsigned int __type) const;
00409
00410 public:
00411 friend work_node operator+(const work_node& _w, const delta_id& _d);
00412 friend work_node operator-(const work_node& _w, const delta_id& _d);
00413 friend work_node& operator+=(work_node& _w, const delta_id& _d);
00414 friend work_node& operator-=(work_node& _w, const delta_id& _d);
00415
00416 template <template <class _Tp, class _A> class _Ctr, class _Al>
00417 friend work_node operator+(const work_node& _w, const _Ctr<delta_id,_Al>& _d);
00418
00419 template <template <class _Tp, class _A> class _Ctr, class _Al>
00420 friend work_node operator-(const work_node& _w, const _Ctr<delta_id,_Al>& _d);
00421
00422 template <template <class _Tp, class _A> class _Ctr, class _Al>
00423 friend work_node& operator+=(work_node& _w, const _Ctr<delta_id,_Al>& _d);
00424
00425 template <template <class _Tp, class _A> class _Ctr, class _Al>
00426 friend work_node& operator-=(work_node& _w, const _Ctr<delta_id,_Al>& _d);
00427
00428 friend class delta;
00429 friend class undelta;
00430 friend class work_node_comp_hook;
00431 };
00432
00433 template <class _W, class _V, class _VR, class _P, class _R, class _I>
00434 class work_node::constraint_iterator_base
00435 {
00436 private:
00437 typedef constraint_iterator_base<_W,_V,_VR,_P,_R,_I> _Self;
00438
00439 private:
00440 _V __cs;
00441 _I __c_cur;
00442 unsigned int __tp;
00443
00444 private:
00445 typedef _V _Vector;
00446 typedef _I _Iterator;
00447 typedef _VR _Reference;
00448
00449 public:
00450 typedef std::bidirectional_iterator_tag iterator_category;
00451
00452 typedef _W value_type;
00453 typedef _R reference;
00454 typedef _P pointer;
00455
00456 typedef size_t size_type;
00457 typedef ptrdiff_t difference_type;
00458
00459 public:
00460 constraint_iterator_base() : __cs(NULL), __c_cur() {}
00461 constraint_iterator_base(_Reference cs, unsigned int tp)
00462 : __cs(&cs), __tp(tp) {}
00463 constraint_iterator_base(const _Self& __c)
00464 : __cs(__c.__cs), __c_cur(__c.__c_cur), __tp(__c.__tp) {}
00465
00466 ~constraint_iterator_base() {}
00467
00468 reference operator*() const { return *__c_cur; }
00469 pointer operator->() const { return &(operator*()); }
00470
00471 bool operator==(const _Self& _c)
00472 { return __cs == _c.__cs && __c_cur == _c.__c_cur; }
00473
00474 bool operator!=(const _Self& _c)
00475 { return __cs != _c.__cs || __c_cur != _c.__c_cur; }
00476
00477 _Self& set(const _Iterator& _c)
00478 {
00479 for(__c_cur = _c; __c_cur != (*__cs).end(); ++__c_cur)
00480 {
00481 if((*__c_cur)->is(__tp))
00482 break;
00483 }
00484 return *this;
00485 }
00486
00487 _Self& operator++()
00488 {
00489 if(__c_cur != (*__cs).end())
00490 ++__c_cur;
00491 for(; __c_cur != (*__cs).end(); ++__c_cur)
00492 {
00493 if((*__c_cur)->is(__tp))
00494 break;
00495 }
00496 return *this;
00497 }
00498
00499 _Self operator++(int)
00500 {
00501 _Self __tmp = *this;
00502 ++__tmp;
00503 return __tmp;
00504 }
00505
00506 _Self& operator--()
00507 {
00508 if(__c_cur == (*__cs).begin())
00509 __c_cur = (*__cs).end();
00510 else if(__c_cur != (*__cs).end())
00511 --__c_cur;
00512 for(; __c_cur != (*__cs).begin(); --__c_cur)
00513 {
00514 if((*__c_cur)->is(__tp))
00515 break;
00516 }
00517 if(__c_cur == (*__cs).begin() && !(*__c_cur)->is(__tp))
00518 __c_cur = (*__cs).end();
00519 return *this;
00520 }
00521
00522 _Self operator--(int)
00523 {
00524 _Self __tmp = *this;
00525 --__tmp;
00526 return __tmp;
00527 }
00528
00529 _Self& operator=(const _Self& _c)
00530 {
00531 __cs = _c.__cs;
00532 __c_cur = _c.__c_cur;
00533 __tp = _c.__tp;
00534 return *this;
00535 }
00536 };
00537
00538 inline work_node::constraint_const_iterator
00539 work_node::get_begin(unsigned int __type) const
00540 {
00541 constraint_const_iterator __tmp((*_m)->constraints, __type);
00542 __tmp.set((*_m)->constraints.begin());
00543 return(__tmp);
00544 }
00545
00546 inline work_node::constraint_const_iterator
00547 work_node::get_end(unsigned int __type) const
00548 {
00549 constraint_const_iterator __tmp((*_m)->constraints, __type);
00550 __tmp.set((*_m)->constraints.end());
00551 return(__tmp);
00552 }
00553
00554 inline work_node::constraint_iterator work_node::get_begin(unsigned int __type)
00555 {
00556 constraint_iterator __tmp((*_m)->constraints, __type);
00557 __tmp.set((*_m)->constraints.begin());
00558 return(__tmp);
00559 }
00560
00561 inline work_node::constraint_iterator work_node::get_end(unsigned int __type)
00562 {
00563 constraint_iterator __tmp((*_m)->constraints, __type);
00564 __tmp.set((*_m)->constraints.end());
00565 return(__tmp);
00566 }
00567
00568 #include <api_delta.h>
00569
00570 inline work_node operator+(const work_node& _w, const delta_id& _i)
00571 {
00572 work_node _tmp(_w);
00573 const delta& _d(_tmp.get_delta(_i));
00574 if(!_d.apply3(_tmp, _w, _i))
00575 std::cerr << "Warning: Could not apply delta <" <<
00576 _i << "> to work node <" << _tmp.get_id() << ">!" << std::endl;
00577 return _tmp;
00578 }
00579
00580 inline work_node& operator+=(work_node& _w, const delta_id& _i)
00581 {
00582 const delta& _d(_w.get_delta(_i));
00583 if(!_d.apply(_w, _i))
00584 std::cerr << "Warning: Could not apply delta <" <<
00585 _i << "> to work node <" << _w.get_id() << ">!" << std::endl;
00586 return _w;
00587 }
00588
00589 template <template <class _Tp, class _A> class _Ctr, class _Al>
00590 inline work_node operator+(const work_node& _w, const _Ctr<delta_id, _Al>& _d)
00591 {
00592 work_node _tmp(_w);
00593 typename _Ctr<delta_id, _Al>::const_iterator __b, __e;
00594
00595 __e = _d.end();
00596 for(__b = _d.begin(); __b != __e; ++__b)
00597 _tmp += *__b;
00598 return _tmp;
00599 }
00600
00601 template <template <class _Tp, class _A> class _Ctr, class _Al>
00602 inline work_node operator-(const work_node& _w, const _Ctr<delta_id, _Al>& _d)
00603 {
00604 work_node _tmp(_w);
00605 typedef typename _Ctr<delta_id, _Al>::const_iterator _Ccit;
00606 typedef typename std::reverse_iterator<_Ccit> _rCcit;
00607 _rCcit __b, __e;
00608
00609 __e = _d.rend();
00610 for(__b = _d.rbegin(); __b != __e; ++__b)
00611 _tmp -= *__b;
00612 return _tmp;
00613 }
00614
00615 template <template <class _Tp, class _A> class _Ctr, class _Al>
00616 inline work_node& operator+=(work_node& _w, const _Ctr<delta_id, _Al>& _d)
00617 {
00618 typename _Ctr<delta_id, _Al>::const_iterator __b, __e;
00619
00620 __e = _d.end();
00621 for(__b = _d.begin(); __b != __e; ++__b)
00622 _w += *__b;
00623 return _w;
00624 }
00625
00626 template <template <class _Tp, class _A> class _Ctr, class _Al>
00627 inline work_node& operator-=(work_node& _w, const _Ctr<delta_id, _Al>& _d)
00628 {
00629 typedef typename _Ctr<delta_id, _Al>::const_iterator _Ccit;
00630 typedef typename std::reverse_iterator<_Ccit> _rCcit;
00631 _rCcit __b, __e;
00632
00633 __e = _d.rend();
00634 for(__b = _d.rbegin(); __b != __e; ++__b)
00635 _w -= *__b;
00636 return _w;
00637 }
00638
00639 inline delta delta_node::get_delta(unsigned int i)
00640 {
00641 vdbl::standard_table* dt =
00642 (vdbl::standard_table*)(*database())->get_table("deltas", get_dbuserid());
00643 vdbl::alltype<delta> *_at;
00644 vdbl::context _ctxdummy;
00645 bool ret = dt->retrieve(get_delta_id(i), dt->get_col_id("delta"), &_ctxdummy,
00646 (vdbl::alltype_base*)_at);
00647 if(ret == false)
00648 throw "Database inconsistency: unkown delta";
00649 return _at->content();
00650 }
00651
00652 inline const delta& delta_node::get_delta(unsigned int i) const
00653 {
00654 vdbl::standard_table* dt =
00655 (vdbl::standard_table*)(*database())->
00656 get_table("deltas", get_dbuserid());
00657 vdbl::alltype<delta> *_at;
00658 vdbl::context _ctxdummy;
00659 bool ret = dt->retrieve(get_delta_id(i), dt->get_col_id("delta"), &_ctxdummy,
00660 (vdbl::alltype_base*)_at);
00661 if(ret == false)
00662 throw "Database inconsistency: unkown delta";
00663 return _at->content();
00664 }
00665
00666 inline delta work_node::get_delta(const delta_id& _id)
00667 {
00668 bool error;
00669 const vdbl::row &_r(dtable->get_row(_id, error));
00670 if(error)
00671 throw "Database inconsistency: delta not found!";
00672 const vdbl::col &_c(_r.get_col(dtable->get_col_id("delta"), error));
00673 if(error)
00674 throw "Database inconsistency: delta table malformed!";
00675 delta _d;
00676 _c.get(_d);
00677 return _d;
00678 }
00679
00680 inline const delta& work_node::get_delta(const delta_id& _id) const
00681 {
00682 bool error;
00683 const vdbl::row *_r(dtable->get_row_ptr(_id));
00684 if(_r == NULL)
00685 throw "Database inconsistency: delta not found!";
00686 const vdbl::col &_c(_r->get_col(dtable->get_col_id("delta"), error));
00687 if(error)
00688 throw "Database inconsistency: delta table malformed!";
00689 const vdbl::typed_col<delta> *_cp =
00690 (const vdbl::typed_col<delta>*)_c.get_ptr_to_val();
00691 return _cp->get_val();
00692 }
00693
00694 inline void work_node::reset_node_ranges()
00695
00696 {
00697 unsigned int n = (**_m).number_of_nodes();
00698
00699 for(unsigned int i = 0; i < n; ++i)
00700 if((**_m).node(i) == (**_m).ground())
00701 node_ranges.push_back(interval(-INFINITY,INFINITY));
00702 }
00703
00704 inline unsigned int work_node::n(unsigned int __type) const
00705 {
00706 unsigned int h=0;
00707 std::vector<model::walker>::const_iterator __b, __e;
00708
00709 if(!(__type & ~ex_any))
00710 {
00711 if(__type & ex_bound)
00712 h += n_bds;
00713 if(__type & ex_linear)
00714 h += n_lin;
00715 if(__type & ex_quadratic)
00716 h += n_quad;
00717 if(__type & ex_polynomial)
00718 h += n_poly;
00719 if(__type & ex_other)
00720 h += n_other;
00721 }
00722 else
00723 {
00724 __e = (**_m).constraints.end();
00725 for(__b = (**_m).constraints.begin(); __b != __e; ++__b)
00726 if((*__b)->is(__type))
00727 h++;
00728 }
00729 return h;
00730 }
00731
00732 #endif // _SEARCH_NODE_H