00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace Gecode {
00025
00034
00035 enum ViewSelStatus {
00036 VSS_NONE,
00037 VSS_SELECT,
00038 VSS_COMMIT
00039 };
00040
00067 template <class View, class Val, class ViewSel, class ValSel>
00068 class ViewValBranching : public Branching {
00069 protected:
00070 ViewArray<View> x;
00071 mutable int start;
00072
00073 ViewValBranching(Space* home, bool share, ViewValBranching& b);
00074 public:
00076 ViewValBranching(Space* home, ViewArray<View>& x);
00078 virtual bool status(const Space* home) const;
00080 virtual const BranchingDesc* description(const Space* home) const;
00082 virtual ExecStatus commit(Space* home, const BranchingDesc* d,
00083 unsigned int a);
00085 virtual Actor* copy(Space* home, bool share);
00086 };
00087
00092 template <class Val>
00093 class PosValDesc : public BranchingDesc {
00094 protected:
00095 const int _pos;
00096 const Val _val;
00097 const int _start;
00098 public:
00104 PosValDesc(const Branching* b, const int p, const Val& n, const int s=0);
00106 int pos(void) const;
00108 Val val(void) const;
00110 int start(void) const;
00112 virtual size_t size(void) const;
00113 };
00114
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 template <class Val>
00128 forceinline
00129 PosValDesc<Val>::PosValDesc(const Branching* b, const int p, const Val& n,
00130 const int s)
00131 : BranchingDesc(b,2), _pos(p), _val(n), _start(s) {}
00132
00133 template <class Val>
00134 forceinline int
00135 PosValDesc<Val>::pos(void) const {
00136 return _pos;
00137 }
00138
00139 template <class Val>
00140 forceinline Val
00141 PosValDesc<Val>::val(void) const {
00142 return _val;
00143 }
00144
00145 template <class Val>
00146 forceinline int
00147 PosValDesc<Val>::start(void) const {
00148 return _start;
00149 }
00150
00151 template <class Val>
00152 size_t
00153 PosValDesc<Val>::size(void) const {
00154 return sizeof(PosValDesc<Val>);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 template <class View, class Val, class ViewSel, class ValSel>
00164 forceinline
00165 ViewValBranching<View,Val,ViewSel,ValSel>
00166 ::ViewValBranching(Space* home, ViewArray<View>& x0)
00167 : Branching(home), x(x0), start(0) {}
00168
00169
00170 template <class View, class Val, class ViewSel, class ValSel>
00171 forceinline
00172 ViewValBranching<View,Val,ViewSel,ValSel>
00173 ::ViewValBranching(Space* home, bool share, ViewValBranching& b)
00174 : Branching(home,share,b), start(b.start) {
00175 x.update(home,share,b.x);
00176 }
00177
00178 template <class View, class Val, class ViewSel, class ValSel>
00179 Actor*
00180 ViewValBranching<View,Val,ViewSel,ValSel>::copy(Space* home, bool share) {
00181 return new (home)
00182 ViewValBranching<View,Val,ViewSel,ValSel>(home,share,*this);
00183 }
00184
00185 template <class View, class Val, class ViewSel, class ValSel>
00186 bool
00187 ViewValBranching<View,Val,ViewSel,ValSel>
00188 ::status(const Space*) const {
00189 for (int i=start; i < x.size(); i++)
00190 if (!x[i].assigned()) {
00191 start = i;
00192 return true;
00193 }
00194 return false;
00195 }
00196
00197 template <class View, class Val, class ViewSel, class ValSel>
00198 const BranchingDesc*
00199 ViewValBranching<View,Val,ViewSel,ValSel>
00200 ::description(const Space* home) const {
00201 assert(!x[start].assigned());
00202 ViewSel vs;
00203 ValSel vl;
00204 int i = start;
00205 int b = i++;
00206 if (vs.init(home,x[b]) != VSS_COMMIT)
00207 for (; i < x.size(); i++)
00208 if (!x[i].assigned())
00209 switch (vs.select(home,x[i])) {
00210 case VSS_SELECT: b=i; break;
00211 case VSS_COMMIT: b=i; goto create;
00212 case VSS_NONE: break;
00213 default: GECODE_NEVER;
00214 }
00215 create:
00216 return new PosValDesc<Val>(this,b-start,vl.val(home,x[b]),start);
00217 }
00218
00219 template <class View, class Val, class ViewSel, class ValSel>
00220 ExecStatus
00221 ViewValBranching<View,Val,ViewSel,ValSel>
00222 ::commit(Space* home, const BranchingDesc* d, unsigned int a) {
00223 const PosValDesc<Val>* pvd = static_cast<const PosValDesc<Val>*>(d);
00224
00225 x.drop_fst(pvd->start()); start = 0;
00226 ValSel vs;
00227 return me_failed(vs.tell(home,a,x[pvd->pos()],pvd->val()))
00228 ? ES_FAILED : ES_OK;
00229 }
00230
00231 }
00232
00233