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 #include <gecode/int/channel.hh>
00039
00040 namespace Gecode {
00041
00042 void
00043 channel(Space& home, const IntVarArgs& x, int xoff,
00044 const IntVarArgs& y, int yoff,
00045 IntConLevel icl) {
00046 using namespace Int;
00047 using namespace Channel;
00048 int n = x.size();
00049 if (n != y.size())
00050 throw ArgumentSizeMismatch("Int::channel");
00051 if (x.same(home) || y.same(home))
00052 throw ArgumentSame("Int::channel");
00053 Limits::check(xoff,"Int::channel");
00054 Limits::check(yoff,"Int::channel");
00055 if ((xoff < 0) || (yoff < 0))
00056 throw OutOfLimits("Int::channel");
00057 if (home.failed()) return;
00058 if (n == 0)
00059 return;
00060
00061 if ((xoff < 2) && (yoff < 2) && (xoff == yoff)) {
00062 if (icl == ICL_DOM) {
00063 DomInfo<IntView>* di = home.alloc<DomInfo<IntView> >(2*(n+xoff));
00064 for (int i=n; i--; ) {
00065 di[xoff+i ].init(x[i],n+xoff);
00066 di[2*xoff+i+n].init(y[i],n+xoff);
00067 }
00068 if (xoff == 1) {
00069 IntVar x0(home,0,0);
00070 di[0].init(x0, n+xoff);
00071 IntVar y0(home,0,0);
00072 di[n+xoff].init(y0, n+xoff);
00073 }
00074 if (x.same(home,y)) {
00075 GECODE_ES_FAIL(home,(Dom<IntView,true>::post(home,n+xoff,di)));
00076 } else {
00077 GECODE_ES_FAIL(home,(Dom<IntView,false>::post(home,n+xoff,di)));
00078 }
00079 } else {
00080 ValInfo<IntView>* vi = home.alloc<ValInfo<IntView> >(2*(n+xoff));
00081 for (int i=n; i--; ) {
00082 vi[xoff+i ].init(x[i],n+xoff);
00083 vi[2*xoff+i+n].init(y[i],n+xoff);
00084 }
00085 if (xoff == 1) {
00086 IntVar x0(home,0,0);
00087 vi[0].init(x0, n+xoff);
00088 IntVar y0(home,0,0);
00089 vi[n+xoff].init(y0, n+xoff);
00090 }
00091 if (x.same(home,y)) {
00092 GECODE_ES_FAIL(home,(Val<IntView,true>::post(home,n+xoff,vi)));
00093 } else {
00094 GECODE_ES_FAIL(home,(Val<IntView,false>::post(home,n+xoff,vi)));
00095 }
00096 }
00097 } else {
00098 if (icl == ICL_DOM) {
00099 DomInfo<OffsetView>* di = home.alloc<DomInfo<OffsetView> >(2*n);
00100 for (int i=n; i--; ) {
00101 OffsetView oxi(x[i],-xoff);
00102 di[i ].init(oxi,n);
00103 OffsetView oyi(y[i],-yoff);
00104 di[i+n].init(oyi,n);
00105 }
00106 if (x.same(home,y)) {
00107 GECODE_ES_FAIL(home,(Dom<OffsetView,true>::post(home,n,di)));
00108 } else {
00109 GECODE_ES_FAIL(home,(Dom<OffsetView,false>::post(home,n,di)));
00110 }
00111 } else {
00112 ValInfo<OffsetView>* vi = home.alloc<ValInfo<OffsetView> >(2*n);
00113 for (int i=n; i--; ) {
00114 OffsetView oxi(x[i],-xoff);
00115 vi[i ].init(oxi,n);
00116 OffsetView oyi(y[i],-yoff);
00117 vi[i+n].init(oyi,n);
00118 }
00119 if (x.same(home,y)) {
00120 GECODE_ES_FAIL(home,(Val<OffsetView,true>::post(home,n,vi)));
00121 } else {
00122 GECODE_ES_FAIL(home,(Val<OffsetView,false>::post(home,n,vi)));
00123 }
00124 }
00125 }
00126
00127 }
00128
00129 void
00130 channel(Space& home, const IntVarArgs& x, const IntVarArgs& y,
00131 IntConLevel icl) {
00132 channel(home, x, 0, y, 0, icl);
00133 }
00134 void
00135 channel(Space& home, BoolVar x0, IntVar x1, IntConLevel) {
00136 using namespace Int;
00137 if (home.failed()) return;
00138 GECODE_ES_FAIL(home,Channel::LinkSingle::post(home,x0,x1));
00139 }
00140
00141 void
00142 channel(Space& home, const BoolVarArgs& x, IntVar y, int o,
00143 IntConLevel) {
00144 using namespace Int;
00145 if (x.same(home))
00146 throw ArgumentSame("Int::channel");
00147 Limits::check(o,"Int::channel");
00148 if (home.failed()) return;
00149 ViewArray<BoolView> xv(home,x);
00150 GECODE_ES_FAIL(home,Channel::LinkMulti::post(home,xv,y,o));
00151 }
00152
00153 }
00154
00155