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
00026
00027
00028
00029
00030
00031
00032 #ifndef MORE_GEN_UNIFYING_PARTIAL_ORDERING_H
00033 #define MORE_GEN_UNIFYING_PARTIAL_ORDERING_H
00034
00035
00036 #include <more/diag/debug.h>
00037 #include <more/gen/link.h>
00038 #include <more/gen/utility.h>
00039 #include <more/gen/iterator.h>
00040 #include <set>
00041
00042
00043 namespace more {
00044 namespace gen {
00045
00046 namespace bits_upo {
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 struct unifying_partial_ordering_base : noncopyable
00058 {
00059 private:
00060 typedef unsigned int algo_serial_type;
00061 public:
00062 struct element_base;
00063
00064 struct node_base : noncopyable
00065 {
00066 node_base(unifying_partial_ordering_base const* context_)
00067 : algo_serial(0), context(context_) {}
00068 std::set<node_base*> m_sups;
00069 std::set<node_base*> m_infs;
00070 algo_serial_type mutable algo_serial;
00071 union algo_cache_type {
00072 bool as_bool;
00073 int as_int;
00074 void* as_ptr;
00075 } algo_cache;
00076
00077 algo_cache_type& cache() { return algo_cache; }
00078 bool is_cached() { return algo_serial == context->algo_serial; }
00079 void set_cached() { algo_serial = context->algo_serial; }
00080
00081 link<element_base> users;
00082 unifying_partial_ordering_base const* context;
00083
00084 typedef std::set<node_base*>::iterator sup_iterator;
00085 typedef std::set<node_base*>::iterator inf_iterator;
00086 };
00087
00088 typedef link<element_base>::iterator user_iterator;
00089
00090 struct element_base : linked
00091 {
00092 protected:
00093 element_base()
00094 : ptr(0) {}
00095 element_base(node_base* p)
00096 : linked(p->users), ptr(p) {}
00097 element_base(element_base const& eb)
00098 : linked(eb.ptr->users), ptr(eb.ptr) {}
00099 element_base& operator=(element_base const& eb) {
00100 unlink();
00101 ptr = eb.ptr;
00102 link_to(ptr->users);
00103 return *this;
00104 }
00105 public:
00106 bool operator==(element_base const& rhs) const {
00107 return ptr == rhs.ptr;
00108 }
00109 bool operator!=(element_base const& rhs) const {
00110 return ptr != rhs.ptr;
00111 }
00112 bool operator<(element_base const& rhs) const {
00113 return ptr < rhs.ptr;
00114 }
00115
00116
00117 void clear_cache() const { ptr->context->clear_cache(); }
00118 void set_cached() const { ptr->set_cached(); }
00119 bool is_cached() const { return ptr->is_cached(); }
00120 node_base::algo_cache_type& cache() const { return ptr->cache(); }
00121
00122 protected:
00123 mutable node_base* ptr;
00124 friend class unifying_partial_ordering_base;
00125 };
00126
00127 unifying_partial_ordering_base(node_base* inf, node_base* sup)
00128 : m_min(inf), m_max(sup), algo_serial(0)
00129 {
00130 inf->m_sups.insert(sup);
00131 sup->m_infs.insert(inf);
00132 }
00133
00134 virtual ~unifying_partial_ordering_base() {}
00135
00136 void insert_impl(node_base*);
00137 static bool preceq_impl(node_base*, node_base*);
00138 private:
00139 static bool preceq_impl_x(node_base*, node_base*);
00140 public:
00141 static bool eq_impl(node_base* x, node_base* y) { return x == y; }
00142 void constrain_preceq_impl(node_base* x, node_base* y);
00143 void constrain_eq_impl(std::set<node_base*> const& S,
00144 node_base* new_node);
00145 template<typename OutputIterator>
00146 static bool
00147 copy_range_impl(node_base* x, node_base* y, OutputIterator it)
00148 {
00149 assert(x->context == y->context);
00150 x->context->clear_cache();
00151 return copy_range_impl_x(x, y, it);
00152 }
00153 private:
00154 template<typename OutputIterator>
00155 static bool
00156 copy_range_impl_x(node_base*, node_base*, OutputIterator);
00157 public:
00158 template<typename OutputIterator>
00159 static void
00160 copy_supremums_impl(node_base*, OutputIterator);
00161 template<typename OutputIterator>
00162 static void
00163 copy_infimums_impl(node_base*, OutputIterator);
00164
00165 protected:
00166 void clear_cache() const;
00167 void check_integrity();
00168 void check_integrity_from_bottom(node_base*);
00169 void check_integrity_from_top(node_base*);
00170 void dump_structure();
00171
00172
00173
00174 node_base* m_min;
00175 node_base* m_max;
00176 algo_serial_type mutable algo_serial;
00177 };
00178
00179 template<typename T>
00180 struct unify_if_equal
00181 : std::binary_function< T&, T, bool >
00182 {
00183 bool operator()(T& x, T const& y) {
00184 if (x == y)
00185 return true;
00186 else
00187 return false;
00188 }
00189 };
00190
00191 template<typename T>
00192 struct unify_none
00193 : std::binary_function< T&, T, bool >
00194 {
00195 bool operator()(T& x, T const& y)
00196 {
00197 return false;
00198 }
00199 };
00200
00201 template<typename T>
00202 struct unify_to_first
00203 : std::binary_function< T&, T, bool >
00204 {
00205 bool operator()(T& x, T const& y)
00206 {
00207 return true;
00208 }
00209 };
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 template<typename T, typename Unify = unify_if_equal<T> >
00222 struct unifying_partial_ordering : private unifying_partial_ordering_base
00223 {
00224 typedef T value_type;
00225 typedef Unify unify_function;
00226
00227 private:
00228 struct node : node_base
00229 {
00230 explicit node(unifying_partial_ordering_base const* context_)
00231 : node_base(context_) {}
00232 node(unifying_partial_ordering_base const* context_, T const& v)
00233 : node_base(context_), value(v) {}
00234 ~node() {}
00235 T value;
00236 };
00237
00238 public:
00239 struct const_element;
00240 struct infimum_iterator;
00241 struct const_infimum_iterator;
00242
00243
00244 struct element : element_base
00245 {
00246 typedef unifying_partial_ordering container;
00247 typedef trivial_iterator_tag iterator_category;
00248 typedef void difference_type;
00249 typedef unifying_partial_ordering::infimum_iterator infimum_iterator;
00250 typedef unifying_partial_ordering::infimum_iterator supremum_iterator;
00251 element() {}
00252 element(node_base* p)
00253 : element_base(p) {}
00254 element(element const& e)
00255 : element_base(e.ptr) {}
00256
00257 element& operator=(element const& e)
00258 {
00259 element_base::operator=(e);
00260 return *this;
00261 }
00262
00263 typedef T value_type;
00264 typedef T& reference;
00265 typedef T* pointer;
00266
00267 reference operator*() { return static_cast<node*>(ptr)->value; }
00268 pointer operator->() { return &static_cast<node*>(ptr)->value; }
00269
00270 infimum_iterator infimums_begin();
00271 infimum_iterator infimums_end();
00272
00273 supremum_iterator supremums_begin();
00274 supremum_iterator supremums_end();
00275
00276 private:
00277 friend class unifying_partial_ordering_base;
00278 friend class unifying_partial_ordering;
00279 friend class const_element;
00280 };
00281
00282
00283 struct const_element : element_base
00284 {
00285 typedef unifying_partial_ordering container;
00286 typedef trivial_iterator_tag iterator_category;
00287 typedef void difference_type;
00288 typedef unifying_partial_ordering::const_infimum_iterator
00289 infimum_iterator;
00290 typedef unifying_partial_ordering::const_infimum_iterator
00291 supremum_iterator;
00292 const_element() {}
00293 const_element(node_base* p)
00294 : element_base(p) {}
00295 const_element(element const& e)
00296 : element_base(e.ptr) {}
00297 const_element(const_element const& e)
00298 : element_base(e.ptr) {}
00299
00300 const_element& operator=(const_element const& e)
00301 {
00302 element_base::operator=(e);
00303 return *this;
00304 }
00305
00306 typedef T const value_type;
00307 typedef T const& reference;
00308 typedef T const* pointer;
00309
00310 reference operator*() const
00311 {
00312 return static_cast<node const*>(ptr)->value;
00313 }
00314
00315 pointer operator->() const
00316 {
00317 return &static_cast<node const*>(ptr)->value;
00318 }
00319
00320 infimum_iterator infimums_begin();
00321 infimum_iterator infimums_end();
00322
00323 supremum_iterator supremums_begin();
00324 supremum_iterator supremums_end();
00325
00326 private:
00327 friend class unifying_partial_ordering_base;
00328 friend class unifying_partial_ordering;
00329 };
00330
00331 private:
00332
00333
00334 struct const_proxy0
00335 {
00336 const_proxy0() {}
00337 explicit const_proxy0(node_base::inf_iterator it) : it_sub(it) {}
00338 typedef T const value_type;
00339 typedef T const& reference;
00340 typedef T const* pointer;
00341 reference operator*() const {
00342 return static_cast<node const*>(*it_sub)->value;
00343 }
00344 pointer operator->() const { return &(operator*()); }
00345 operator const_element() { return *it_sub; }
00346 protected:
00347 node_base::inf_iterator it_sub;
00348 };
00349
00350 struct proxy0
00351 {
00352 proxy0() {}
00353 explicit proxy0(node_base::inf_iterator it) : it_sub(it) {}
00354 typedef T value_type;
00355 typedef T& reference;
00356 typedef T* pointer;
00357 reference operator*() const {
00358 return static_cast<node*>(*it_sub)->value;
00359 }
00360 pointer operator->() const { return &(operator*()); }
00361 operator element() { return *it_sub; }
00362 protected:
00363 node_base::inf_iterator it_sub;
00364 };
00365
00366 public:
00367
00368
00369
00370 struct infimum_iterator
00371 : private proxy0
00372 {
00373 typedef std::bidirectional_iterator_tag iterator_category;
00374 typedef element value_type;
00375 typedef value_type& reference;
00376 typedef value_type* pointer;
00377 typedef std::ptrdiff_t difference_type;
00378 infimum_iterator() {}
00379 infimum_iterator(node_base::inf_iterator it) : proxy0(it) {}
00380
00381 proxy0& operator*() { return *this; }
00382 proxy0* operator->() { return this; }
00383
00384 infimum_iterator& operator++() { ++it_sub; return *this; }
00385 infimum_iterator& operator--() { --it_sub; return *this; }
00386
00387 infimum_iterator operator++(int)
00388 {
00389 infimum_iterator tmp = *this;
00390 ++*this;
00391 return tmp;
00392 }
00393
00394 infimum_iterator operator--(int)
00395 {
00396 infimum_iterator tmp = *this;
00397 --*this;
00398 return *this;
00399 }
00400
00401 bool operator==(infimum_iterator const& rhs) const
00402 {
00403 return it_sub == rhs.it_sub;
00404 }
00405 bool operator!=(infimum_iterator const& rhs) const
00406 {
00407 return it_sub != rhs.it_sub;
00408 }
00409 };
00410
00411
00412 struct const_infimum_iterator
00413 : private const_proxy0
00414 {
00415 typedef std::bidirectional_iterator_tag iterator_category;
00416 typedef const_element value_type;
00417 typedef value_type& reference;
00418 typedef value_type* pointer;
00419 typedef std::ptrdiff_t difference_type;
00420
00421 const_infimum_iterator() {}
00422 const_infimum_iterator(node_base::inf_iterator it)
00423 : const_proxy0(it) {}
00424 const_infimum_iterator(infimum_iterator const& it)
00425 : const_proxy0(it.it_sub) {}
00426
00427 const_proxy0& operator*() { return *this; }
00428 const_proxy0* operator->() { return this; }
00429
00430 const_infimum_iterator& operator++() { ++it_sub; return *this; }
00431 const_infimum_iterator& operator--() { --it_sub; return *this; }
00432 const_infimum_iterator operator++(int)
00433 {
00434 const_infimum_iterator tmp = *this;
00435 ++*this;
00436 return tmp;
00437 }
00438 const_infimum_iterator operator--(int)
00439 {
00440 const_infimum_iterator tmp = *this;
00441 --*this;
00442 return *this;
00443 }
00444
00445 bool operator==(const_infimum_iterator const& rhs) const
00446 {
00447 return it_sub == rhs.it_sub;
00448 }
00449 bool operator!=(const_infimum_iterator const& rhs) const
00450 {
00451 return it_sub != rhs.it_sub;
00452 }
00453 };
00454
00455 typedef infimum_iterator supremum_iterator;
00456
00457 typedef const_infimum_iterator const_supremum_iterator;
00458
00459
00460
00461 unifying_partial_ordering()
00462 : unifying_partial_ordering_base(MORE_NEW(node, this),
00463 MORE_NEW(node, this)) {}
00464
00465
00466
00467 explicit unifying_partial_ordering(unify_function const& fn)
00468 : unifying_partial_ordering_base(MORE_NEW(node, this),
00469 MORE_NEW(node, this)),
00470 unify(fn) {}
00471
00472
00473 unifying_partial_ordering(unifying_partial_ordering const& po)
00474 : unifying_partial_ordering_base(MORE_NEW(node, this),
00475 MORE_NEW(node, this)),
00476 unify(po.unify)
00477 {
00478 insert(po.min(), po.max());
00479 *min() = *po.min();
00480 *max() = *po.max();
00481 }
00482
00483
00484 unifying_partial_ordering&
00485 operator=(unifying_partial_ordering const& po)
00486 {
00487 clear();
00488 insert(po.min(), po.max());
00489 *min() = *po.min();
00490 *max() = *po.max();
00491 return *this;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 virtual ~unifying_partial_ordering()
00507 {
00508 clear();
00509 MORE_DELETE(node, static_cast<node*>(m_min));
00510 MORE_DELETE(node, static_cast<node*>(m_max));
00511 }
00512
00513
00514
00515 void clear();
00516
00517
00518
00519 static bool preceq(element e0, element e1)
00520 {
00521 return preceq_impl(e0.ptr, e1.ptr);
00522 }
00523
00524
00525
00526
00527 static bool eq(element e0, element e1)
00528 {
00529 return eq_impl(e0.ptr, e1.ptr);
00530 }
00531
00532
00533 bool constrain_preceq(element e0, element e1);
00534
00535
00536
00537 bool constrain_eq(element e0, element e1);
00538 private:
00539 bool constrain_eq(std::set<node_base*> const&);
00540 static node_base* copy_caching(node_base*, node_base*, node_base*);
00541
00542
00543 public:
00544
00545 element insert(T const& value)
00546 {
00547 node* ptr = MORE_NEW(node, this, value);
00548 insert_impl(ptr);
00549 return ptr;
00550 }
00551
00552
00553 element insert()
00554 {
00555 node* ptr = MORE_NEW(node, this);
00556 insert_impl(ptr);
00557 return ptr;
00558 }
00559
00560
00561
00562 void insert(const_element e_min, const_element e_max)
00563 {
00564 insert(e_min, e_max, min(), max());
00565 }
00566
00567
00568
00569 void insert(const_element e_min, const_element e_max,
00570 element e_min_dest, element e_max_dest)
00571 {
00572 if (e_min == e_max) return;
00573 if (e_min_dest == e_max_dest)
00574 throw std::logic_error(
00575 "more::gen::unifying_partial_ordering::insert: "
00576 "Invalid destination range.");
00577 e_min.clear_cache();
00578 for (node_base::sup_iterator it = e_min.ptr->m_sups.begin();
00579 it != e_min.ptr->m_sups.end(); ++it)
00580 {
00581 node_base* node_new
00582 = copy_caching(*it, e_max.ptr, e_max_dest.ptr);
00583 e_min_dest.ptr->m_sups.insert(node_new);
00584 node_new->m_infs.insert(e_min_dest.ptr);
00585 }
00586 }
00587
00588
00589
00590 const_element min() const { return m_min; }
00591
00592
00593
00594 const_element max() const { return m_max; }
00595
00596
00597
00598 element min() { return m_min; }
00599
00600
00601
00602 element max() { return m_max; }
00603
00604 template<typename OutputIterator>
00605 static void copy_range(element, element, OutputIterator);
00606 template<typename OutputIterator>
00607 static void copy_range(const_element, const_element,
00608 OutputIterator);
00609 template<typename OutputIterator>
00610 static void copy_supremums(element, OutputIterator);
00611 template<typename OutputIterator>
00612 static void copy_supremums(const_element, OutputIterator);
00613 template<typename OutputIterator>
00614 static void copy_infimums(element, OutputIterator);
00615 template<typename OutputIterator>
00616 static void copy_infimums(const_element, OutputIterator);
00617
00618
00619
00620
00621
00622
00623
00624
00625 static std::pair<const_infimum_iterator, const_infimum_iterator>
00626 infimum_range(const_element x)
00627 {
00628 return std::make_pair(const_infimum_iterator(x.ptr->m_infs.begin()),
00629 const_infimum_iterator(x.ptr->m_infs.end()));
00630 }
00631
00632
00633
00634 static std::pair<const_supremum_iterator, const_supremum_iterator>
00635 supremum_range(const_element x)
00636 {
00637 return std::make_pair(const_supremum_iterator(x.ptr->m_sups.begin()),
00638 const_supremum_iterator(x.ptr->m_sups.end()));
00639 }
00640
00641
00642
00643 static std::pair<infimum_iterator, infimum_iterator>
00644 infimum_range(element x)
00645 {
00646 return std::make_pair(infimum_iterator(x.ptr->m_infs.begin()),
00647 infimum_iterator(x.ptr->m_infs.end()));
00648 }
00649
00650
00651
00652 static std::pair<supremum_iterator, supremum_iterator>
00653 supremum_range(element x) {
00654 return std::make_pair(supremum_iterator(x.ptr->m_sups.begin()),
00655 supremum_iterator(x.ptr->m_sups.end()));
00656 }
00657
00658 private:
00659 unify_function unify;
00660 };
00661
00662 template<typename T, typename Unify>
00663 inline typename
00664 unifying_partial_ordering<T, Unify>::element::supremum_iterator
00665 unifying_partial_ordering<T, Unify>::element::supremums_begin()
00666 {
00667 return ptr->m_sups.begin();
00668 }
00669 template<typename T, typename Unify>
00670 inline typename
00671 unifying_partial_ordering<T, Unify>::element::supremum_iterator
00672 unifying_partial_ordering<T, Unify>::element::supremums_end()
00673 {
00674 return ptr->m_sups.end();
00675 }
00676
00677 template<typename T, typename Unify>
00678 inline typename
00679 unifying_partial_ordering<T, Unify>::element::infimum_iterator
00680 unifying_partial_ordering<T, Unify>::element::infimums_begin()
00681 {
00682 return ptr->m_infs.begin();
00683 }
00684 template<typename T, typename Unify>
00685 inline typename
00686 unifying_partial_ordering<T, Unify>::element::infimum_iterator
00687 unifying_partial_ordering<T, Unify>::element::infimums_end()
00688 {
00689 return ptr->m_infs.end();
00690 }
00691
00692 template<typename T, typename Unify>
00693 inline typename
00694 unifying_partial_ordering<T, Unify>::const_element::supremum_iterator
00695 unifying_partial_ordering<T, Unify>::const_element::supremums_begin()
00696 {
00697 return ptr->m_sups.begin();
00698 }
00699 template<typename T, typename Unify>
00700 inline typename
00701 unifying_partial_ordering<T, Unify>::const_element::supremum_iterator
00702 unifying_partial_ordering<T, Unify>::const_element::supremums_end()
00703 {
00704 return ptr->m_sups.end();
00705 }
00706
00707 template<typename T, typename Unify>
00708 inline typename
00709 unifying_partial_ordering<T, Unify>::const_element::infimum_iterator
00710 unifying_partial_ordering<T, Unify>::const_element::infimums_begin()
00711 {
00712 return ptr->m_infs.begin();
00713 }
00714 template<typename T, typename Unify>
00715 inline typename
00716 unifying_partial_ordering<T, Unify>::const_element::infimum_iterator
00717 unifying_partial_ordering<T, Unify>::const_element::infimums_end()
00718 {
00719 return ptr->m_infs.end();
00720 }
00721
00722 template<typename Element>
00723 std::pair< typename Element::supremum_iterator,
00724 typename Element::supremum_iterator >
00725 supremums(Element e)
00726 {
00727 return std::make_pair(e.supremums_begin(),
00728 e.supremums_end());
00729 }
00730 template<typename Element>
00731 std::pair< typename Element::infimum_iterator,
00732 typename Element::infimum_iterator >
00733 infimums(Element e)
00734 {
00735 return std::make_pair(e.infimums_begin(),
00736 e.infimums_end());
00737 }
00738
00739
00740 template<typename Element>
00741 inline bool preceq(Element e0, Element e1)
00742 {
00743 typedef typename Element::container container;
00744 return container::preceq(e0, e1);
00745 }
00746
00747
00748 template<typename Element>
00749 inline bool prec(Element e0, Element e1)
00750 {
00751 return e0 != e1 && preceq(e0, e1);
00752 }
00753
00754
00755 template<typename Element>
00756 inline bool succeq(Element e0, Element e1) { return preceq(e1, e0); }
00757
00758
00759 template<typename Element>
00760 inline bool succ(Element e0, Element e1) { return prec(e1, e0); }
00761
00762
00763 }
00764 using bits_upo::unifying_partial_ordering;
00765 using bits_upo::unify_to_first;
00766 using bits_upo::unify_if_equal;
00767 using bits_upo::unify_none;
00768
00769
00770
00771 }}
00772
00773 #include <more/bits/unifying_partial_ordering.tcc>
00774
00775 #endif