Generated on Mon Aug 25 11:35:38 2008 for Gecode by doxygen 1.5.6

lex.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2003
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-07-11 09:33:32 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7290 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 namespace Gecode { namespace Int { namespace Rel {
00039 
00040   template <class View>
00041   inline
00042   Lex<View>::Lex(Space* home,                             
00043                  ViewArray<View>& x0, ViewArray<View>& y0, bool s)
00044     : Propagator(home), x(x0), y(y0), strict(s) {
00045     x.subscribe(home, this, PC_INT_BND);
00046     y.subscribe(home, this, PC_INT_BND);
00047   }
00048 
00049   template <class View>
00050   forceinline
00051   Lex<View>::Lex(Space* home, bool share, Lex<View>& p)
00052     : Propagator(home,share,p), strict(p.strict) {
00053     x.update(home,share,p.x);
00054     y.update(home,share,p.y);
00055   }
00056 
00057   template <class View>
00058   Actor*
00059   Lex<View>::copy(Space* home, bool share) {
00060     return new (home) Lex<View>(home,share,*this);
00061   }
00062 
00063   template <class View>
00064   inline Support::Symbol
00065   Lex<View>::ati(void) {
00066     return Reflection::mangle<View>("Gecode::Int::Rel::Lex");
00067   }
00068 
00069   template <class View>
00070   Reflection::ActorSpec
00071   Lex<View>::spec(const Space* home, Reflection::VarMap& m) const {
00072     Reflection::ActorSpec s(ati());
00073     return s << x.spec(home,m) << y.spec(home,m) << strict;
00074   }
00075 
00076   template <class View>
00077   void
00078   Lex<View>::post(Space* home, Reflection::VarMap& vars,
00079                   const Reflection::ActorSpec& spec) {
00080     spec.checkArity(3);
00081     ViewArray<View> x(home, vars, spec[0]);
00082     ViewArray<View> y(home, vars, spec[1]);
00083     bool s = spec[2]->toInt();
00084     (void) new (home) Lex<View>(home,x,y,s);
00085   }
00086 
00087   template <class View>
00088   PropCost
00089   Lex<View>::cost(ModEventDelta) const {
00090     return cost_lo(x.size(), PC_LINEAR_LO);
00091   }
00092 
00093   template <class View>
00094   ExecStatus
00095   Lex<View>::propagate(Space* home, ModEventDelta) {
00096     /*
00097      * State 1
00098      *
00099      */
00100     {
00101       int i = 0;
00102       int n = x.size();
00103 
00104       while ((i < n) && (x[i].min() == y[i].max())) {
00105         // case: =, >=
00106         GECODE_ME_CHECK(x[i].lq(home,y[i].max()));
00107         GECODE_ME_CHECK(y[i].gq(home,x[i].min()));
00108         i++;
00109       }
00110 
00111       if (i == n) // case: $
00112         return strict ? ES_FAILED : ES_SUBSUMED(this,sizeof(*this));
00113 
00114       // Possible cases left: <, <=, > (yields failure), ?
00115       GECODE_ME_CHECK(x[i].lq(home,y[i].max()));
00116       GECODE_ME_CHECK(y[i].gq(home,x[i].min()));
00117 
00118       if (x[i].max() < y[i].min()) // case: < (after tell)
00119         return ES_SUBSUMED(this,home);
00120 
00121       // x[i] can never be equal to y[i] (otherwise: >=)
00122       assert(!(x[i].assigned() && y[i].assigned() &&
00123                x[i].val() == y[i].val()));
00124       // Remove all elements between 0...i-1 as they are assigned and equal
00125       x.drop_fst(i); y.drop_fst(i);
00126       // After this, execution continues at [1]
00127     }
00128 
00129     /*
00130      * State 2
00131      *   prefix: (?|<=)
00132      *
00133      */
00134     {
00135       int i = 1;
00136       int n = x.size();
00137 
00138       while ((i < n) &&
00139              (x[i].min() == y[i].max()) &&
00140              (x[i].max() == y[i].min())) { // case: =
00141         assert(x[i].assigned() && y[i].assigned() &&
00142                (x[i].val() == y[i].val()));
00143         i++;
00144       }
00145 
00146       if (i == n) { // case: $
00147         if (strict)
00148           goto rewrite_le;
00149         else
00150           goto rewrite_lq;
00151       }
00152 
00153       if (x[i].max() < y[i].min()) // case: <
00154         goto rewrite_lq;
00155 
00156       if (x[i].min() > y[i].max()) // case: >
00157         goto rewrite_le;
00158 
00159       if (i > 1) {
00160         // Remove equal elements [1...i-1], keep element [0]
00161         x[i-1]=x[0]; x.drop_fst(i-1);
00162         y[i-1]=y[0]; y.drop_fst(i-1);
00163       }
00164     }
00165 
00166     if (x[1].max() <= y[1].min()) {
00167       // case: <= (invariant: not =, <)
00168       /*
00169        * State 3
00170        *   prefix: (?|<=),<=
00171        *
00172        */
00173       int i = 2;
00174       int n = x.size();
00175 
00176       while ((i < n) && (x[i].max() == y[i].min())) // case: <=, =
00177         i++;
00178 
00179       if (i == n) { // case: $
00180         if (strict)
00181           return ES_FIX;
00182         else
00183           goto rewrite_lq;
00184       }
00185 
00186       if (x[i].max() < y[i].min()) // case: <
00187         goto rewrite_lq;
00188 
00189       if (x[i].min() > y[i].max()) { // case: >
00190         // Eliminate [i]...[n-1]
00191         for (int j=i; j<n; j++) {
00192           x[j].cancel(home,this,PC_INT_BND);
00193           y[j].cancel(home,this,PC_INT_BND);
00194         }
00195         x.size(i); y.size(i);
00196         strict = true;
00197       }
00198 
00199       return ES_FIX;
00200     }
00201 
00202     if (x[1].min() >= y[1].max()) {
00203       // case: >= (invariant: not =, >)
00204       /*
00205        * State 4
00206        *   prefix: (?|<=) >=
00207        *
00208        */
00209       int i = 2;
00210       int n = x.size();
00211 
00212       while ((i < n) && (x[i].min() == y[i].max()))
00213         // case: >=, =
00214         i++;
00215 
00216       if (i == n) { // case: $
00217         if (strict)
00218           goto rewrite_le;
00219         else
00220           return ES_FIX;
00221       }
00222 
00223       if (x[i].min() > y[i].max()) // case: >
00224         goto rewrite_le;
00225 
00226       if (x[i].max() < y[i].min()) { // case: <
00227         // Eliminate [i]...[n-1]
00228         for (int j=i; j<n; j++) {
00229           x[j].cancel(home,this,PC_INT_BND);
00230           y[j].cancel(home,this,PC_INT_BND);
00231         }
00232         x.size(i); y.size(i);
00233         strict = false;
00234       }
00235 
00236       return ES_FIX;
00237     }
00238 
00239     return ES_FIX;
00240 
00241   rewrite_le:
00242     GECODE_REWRITE(this,Le<View>::post(home,x[0],y[0]));
00243   rewrite_lq:
00244     GECODE_REWRITE(this,Lq<View>::post(home,x[0],y[0]));
00245   }
00246 
00247   template <class View>
00248   ExecStatus
00249   Lex<View>::post(Space* home, 
00250                   ViewArray<View>& x, ViewArray<View>& y, bool strict){
00251     if (x.size() == 0)
00252       return strict ? ES_FAILED : ES_OK;
00253     if (x.size() == 1) {
00254       if (strict)
00255         return Le<View>::post(home,x[0],y[0]);
00256       else
00257         return Lq<View>::post(home,x[0],y[0]);
00258     }
00259     (void) new (home) Lex<View>(home,x,y,strict);
00260     return ES_OK;
00261   }
00262 
00263   template <class View>
00264   size_t
00265   Lex<View>::dispose(Space* home) {
00266     assert(!home->failed());
00267     x.cancel(home,this,PC_INT_BND);
00268     y.cancel(home,this,PC_INT_BND);
00269     (void) Propagator::dispose(home);
00270     return sizeof(*this);
00271   }
00272 
00273 }}}
00274 
00275 // STATISTICS: int-prop