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 #include <gecode/int/rel.hh>
00035 #include <gecode/int/bool.hh>
00036
00042 namespace Gecode { namespace Int { namespace Unshare {
00043
00045 template<class Var>
00046 class VarPtrLess {
00047 public:
00048 forceinline bool
00049 operator ()(const Var* a, const Var* b) {
00050 return a->varimp() < b->varimp();
00051 }
00052 };
00053
00054
00056 forceinline void
00057 link(Home home, IntVar** x, int n, IntPropLevel ipl) {
00058 if (home.failed()) {
00059 for (int i=1; i<n; i++)
00060 *x[i]=IntVar(home,x[0]->min(),x[0]->min());
00061 } else if (n > 2) {
00062 ViewArray<IntView> y(home,n);
00063 y[0]=*x[0];
00064 for (int i=1; i<n; i++)
00065 y[i]=*x[i]=IntVar(home,x[0]->min(),x[0]->max());
00066 if ((ipl == IPL_DOM) || (ipl == IPL_DEF)) {
00067 ExecStatus es = Rel::NaryEqDom<IntView>::post(home,y);
00068 (void) es; assert(es == ES_OK);
00069 } else {
00070 ExecStatus es = Rel::NaryEqBnd<IntView>::post(home,y);
00071 (void) es; assert(es == ES_OK);
00072 }
00073 } else if (n == 2) {
00074 *x[1]=IntVar(home,x[0]->min(),x[0]->max());
00075 if ((ipl == IPL_DOM) || (ipl == IPL_DEF)) {
00076 ExecStatus es = Rel::EqDom<IntView,IntView>::post(home,*x[0],*x[1]);
00077 (void) es; assert(es == ES_OK);
00078 } else {
00079 ExecStatus es = Rel::EqBnd<IntView,IntView>::post(home,*x[0],*x[1]);
00080 (void) es; assert(es == ES_OK);
00081 }
00082 }
00083 }
00084
00086 forceinline void
00087 link(Home home, BoolVar** x, int n, IntPropLevel) {
00088 if (home.failed()) {
00089 for (int i=1; i<n; i++)
00090 *x[i]=BoolVar(home,0,0);
00091 } else if (n > 2) {
00092 ViewArray<BoolView> y(home,n);
00093 y[0]=*x[0];
00094 for (int i=1; i<n; i++)
00095 y[i]=*x[i]=BoolVar(home,0,1);
00096 ExecStatus es = Bool::NaryEq<BoolView>::post(home,y);
00097 (void) es; assert(es == ES_OK);
00098 } else if (n == 2) {
00099 *x[1] = BoolVar(home,0,1);
00100 ExecStatus es = Bool::Eq<BoolView,BoolView>::post(home,*x[0],*x[1]);
00101 (void) es; assert(es == ES_OK);
00102 }
00103 }
00104
00106 template<class Var>
00107 forceinline void
00108 unshare(Home home, VarArgArray<Var>& x, IntPropLevel ipl) {
00109 int n=x.size();
00110 if (n < 2)
00111 return;
00112
00113 Region r;
00114 Var** y = r.alloc<Var*>(n);
00115 for (int i=0; i<n; i++)
00116 y[i]=&x[i];
00117
00118 VarPtrLess<Var> vpl;
00119 Support::quicksort<Var*,VarPtrLess<Var> >(y,n,vpl);
00120
00121
00122 for (int i=0; i<n;) {
00123 int j=i++;
00124 while ((i<n) && (y[j]->varimp() == y[i]->varimp()))
00125 i++;
00126 if (!y[j]->assigned())
00127 link(home,&y[j],i-j,ipl);
00128 }
00129 }
00130
00131 }}}
00132
00133 namespace Gecode {
00134
00135 void
00136 unshare(Home home, IntVarArgs& x, IntPropLevel ipl) {
00137 Int::Unshare::unshare<IntVar>(home,x,vbd(ipl));
00138 }
00139
00140 void
00141 unshare(Home home, BoolVarArgs& x, IntPropLevel) {
00142 Int::Unshare::unshare<BoolVar>(home,x,IPL_DEF);
00143 }
00144
00145 }
00146
00147