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