00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GC_NQ_SUBSUME_HH_
00021 #define GC_NQ_SUBSUME_HH_
00022
00023
00024 #include "gecode/int.hh"
00025
00026 #include "gecode/iter.hh"
00027
00028 #include <iostream>
00029
00030 namespace Gecode { namespace Int { namespace Rel {
00031
00032
00033 template <class View>
00034 class NqSubsume : public BinaryPropagator<View,PC_INT_DOM> {
00035 protected:
00036 using BinaryPropagator<View,PC_INT_DOM>::x0;
00037 using BinaryPropagator<View,PC_INT_DOM>::x1;
00038 unsigned int maxCheckSize;
00039
00041 NqSubsume(Space* home, bool share, NqSubsume<View>& p);
00043 NqSubsume(Space* home, View x0, View x1, unsigned int maxCheckSize_);
00044 public:
00046 virtual Actor* copy(Space* home, bool share);
00048 virtual PropCost cost(void) const;
00050 virtual ExecStatus propagate(Space* home);
00052 static ExecStatus post(Space* home, View x0, View x1,
00053 unsigned int maxCheckSize_ = Limits::Int::int_max);
00054 };
00055
00056
00057 template <class View>
00058 forceinline
00059 NqSubsume<View>::NqSubsume(Space* home, View x0, View x1, unsigned int maxCheckSize_)
00060 : BinaryPropagator<View,PC_INT_DOM>(home,x0,x1), maxCheckSize(maxCheckSize_) {}
00061
00062 template <class View>
00063 forceinline
00064 ExecStatus
00065 NqSubsume<View>::post(Space* home, View x0, View x1, unsigned int maxCheckSize_){
00066 if (x0.assigned()) {
00067 GECODE_ME_CHECK(x1.nq(home,x0.val()));
00068 } else if (x1.assigned()) {
00069 GECODE_ME_CHECK(x0.nq(home,x1.val()));
00070 } else if (same(x0,x1)) {
00071 return ES_FAILED;
00072 } else {
00073 (void) new (home) NqSubsume<View>(home,x0,x1,maxCheckSize_);
00074 }
00075 return ES_OK;
00076 }
00077
00078 template <class View>
00079 forceinline
00080 NqSubsume<View>::NqSubsume(Space* home, bool share, NqSubsume<View>& p)
00081 : BinaryPropagator<View,PC_INT_DOM>(home,share,p), maxCheckSize(p.maxCheckSize) {}
00082
00083 template <class View>
00084 forceinline
00085 Actor*
00086 NqSubsume<View>::copy(Space* home, bool share) {
00087 return new (home) NqSubsume<View>(home,share,*this);
00088 }
00089
00090 template <class View>
00091 forceinline
00092 PropCost
00093 NqSubsume<View>::cost(void) const {
00094 return PC_BINARY_LO;
00095 }
00096
00097 template <class View>
00098 forceinline
00099 ExecStatus
00100 NqSubsume<View>::propagate(Space* home) {
00101 if (x0.assigned()) {
00102 GECODE_ME_CHECK(x1.nq(home,x0.val()));
00103 return ES_SUBSUMED;
00104 } else if (x1.assigned()) {
00105 GECODE_ME_CHECK(x0.nq(home,x1.val()));
00106 return ES_SUBSUMED;
00107 } else {
00108
00109 Gecode::Int::IntView* a = &x0, *b = &x1;
00110 if(a->size() > b->size()) {
00111 a = &x1, b = &x0;
00112 }
00113
00114 if (a->size() <= maxCheckSize) {
00115 ViewRanges< IntView > ra(*a), rb(*b);
00116 while (ra() && rb()) {
00117 if ( (ra.min() <= rb.min() && ra.max() >= rb.min())
00118 || (rb.min() <= ra.min() && rb.max() >= ra.min())) {
00119 return ES_FIX;
00120 }
00121 while (ra() && ra.max() < rb.min()) ++ra;
00122 while (rb() && ra() && rb.max() < ra.min()) ++rb;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 return ES_SUBSUMED;
00135 }
00136 }
00137 return ES_FIX;
00138 }
00139
00140 }}}
00141
00142 #endif
00143