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
00033
00034
00035
00036
00037
00038 namespace Gecode { namespace Int { namespace Circuit {
00039
00040
00041
00042
00043
00044 template<class View, class Offset>
00045 forceinline
00046 Dom<View,Offset>::Dom(Home home, ViewArray<View>& x, Offset& o)
00047 : Base<View,Offset>(home,x,o) {}
00048
00049 template<class View, class Offset>
00050 forceinline
00051 Dom<View,Offset>::Dom(Space& home, bool share, Dom<View,Offset>& p)
00052 : Base<View,Offset>(home,share,p) {}
00053
00054 template<class View, class Offset>
00055 Actor*
00056 Dom<View,Offset>::copy(Space& home, bool share) {
00057 return new (home) Dom<View,Offset>(home,share,*this);
00058 }
00059
00060 template<class View, class Offset>
00061 PropCost
00062 Dom<View,Offset>::cost(const Space&, const ModEventDelta& med) const {
00063 if (View::me(med) == Int::ME_INT_VAL)
00064 return PropCost::linear(PropCost::LO, x.size());
00065 else
00066 return PropCost::quadratic(PropCost::HI, x.size());
00067 }
00068
00069 template<class View, class Offset>
00070 void
00071 Dom<View,Offset>::reschedule(Space& home) {
00072 for (int i=y.size(); i--; )
00073 if (y[i].assigned()) {
00074 View::schedule(home, *this, ME_INT_VAL);
00075 return;
00076 }
00077 View::schedule(home, *this, ME_INT_DOM);
00078 }
00079
00080 template<class View, class Offset>
00081 ExecStatus
00082 Dom<View,Offset>::propagate(Space& home, const ModEventDelta& med) {
00083 if (View::me(med) == Int::ME_INT_VAL) {
00084 GECODE_ES_CHECK((Int::Distinct::prop_val<View,true>(home,y)));
00085 ExecStatus escv = connected(home);
00086 if (escv != ES_FIX)
00087 return escv;
00088 if (y.size() < 2)
00089 return home.ES_SUBSUMED(*this);
00090 return home.ES_FIX_PARTIAL(*this,View::med(Int::ME_INT_DOM));
00091 }
00092
00093 if (dc.available()) {
00094 GECODE_ES_CHECK(dc.sync(home));
00095 } else {
00096 GECODE_ES_CHECK(dc.init(home,y));
00097 }
00098 bool assigned;
00099 GECODE_ES_CHECK(dc.propagate(home,assigned));
00100
00101 ExecStatus esc = connected(home);
00102 if (esc != ES_FIX)
00103 return esc;
00104
00105
00106
00107
00108 if (assigned)
00109 for (int i=y.size(); i--; )
00110 if (y[i].assigned())
00111 y.move_lst(i);
00112
00113 return path(home);
00114 }
00115
00116 template<class View, class Offset>
00117 ExecStatus
00118 Dom<View,Offset>::post(Home home, ViewArray<View>& x, Offset& o) {
00119 int n = x.size();
00120 if (n == 1) {
00121 GECODE_ME_CHECK(o(x[0]).eq(home,0));
00122 } else if (n == 2) {
00123 GECODE_ME_CHECK(o(x[0]).eq(home,1));
00124 GECODE_ME_CHECK(o(x[1]).eq(home,0));
00125 } else {
00126 for (int i=n; i--; ) {
00127 GECODE_ME_CHECK(o(x[i]).gq(home,0));
00128 GECODE_ME_CHECK(o(x[i]).le(home,n));
00129 GECODE_ME_CHECK(o(x[i]).nq(home,i));
00130 }
00131 (void) new (home) Dom<View,Offset>(home,x,o);
00132 }
00133 return ES_OK;
00134 }
00135
00136 }}}
00137
00138
00139