Generated on Wed Nov 1 15:04:39 2006 for Gecode by doxygen 1.4.5

lex.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2003
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:03:26 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3512 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 namespace Gecode { namespace Int { namespace Rel {
00023 
00024   template <class View>
00025   inline
00026   Lex<View>::Lex(Space* home,
00027                  ViewArray<ViewTuple<View,2> >& xy, bool s)
00028     : NaryPropagator<ViewTuple<View,2>,PC_INT_BND>(home,xy), strict(s) {}
00029 
00030   template <class View>
00031   forceinline
00032   Lex<View>::Lex(Space* home, bool share, Lex<View>& p)
00033     : NaryPropagator<ViewTuple<View,2>,PC_INT_BND>(home,share,p),
00034       strict(p.strict) {}
00035 
00036   template <class View>
00037   Actor*
00038   Lex<View>::copy(Space* home, bool share) {
00039     return new (home) Lex<View>(home,share,*this);
00040   }
00041 
00042   template <class View>
00043   ExecStatus
00044   Lex<View>::propagate(Space* home) {
00045     /*
00046      * State 1
00047      *
00048      */
00049     {
00050       int i = 0;
00051       int n = x.size();
00052 
00053       while ((i < n) && (x[i][0].min() == x[i][1].max())) {
00054         // case: =, >=
00055         GECODE_ME_CHECK(x[i][0].lq(home,x[i][1].max()));
00056         GECODE_ME_CHECK(x[i][1].gq(home,x[i][0].min()));
00057         i++;
00058       }
00059 
00060       if (i == n) // case: $
00061         return strict ? ES_FAILED : ES_SUBSUMED;
00062 
00063       // Possible cases left: <, <=, > (yields failure), ?
00064       GECODE_ME_CHECK(x[i][0].lq(home,x[i][1].max()));
00065       GECODE_ME_CHECK(x[i][1].gq(home,x[i][0].min()));
00066 
00067       if (x[i][0].max() < x[i][1].min()) // case: < (after tell)
00068         return ES_SUBSUMED;
00069 
00070       // x[i][0] can never be equal to x[i][1] (otherwise: >=)
00071       assert(!(x[i][0].assigned() && x[i][1].assigned() &&
00072                x[i][0].val() == x[i][1].val()));
00073       // Remove all elements between 0...i-1 as they are assigned and equal
00074       x.drop_fst(i);
00075       // After this, execution continues at [1]
00076     }
00077 
00078     /*
00079      * State 2
00080      *   prefix: (?|<=)
00081      *
00082      */
00083     {
00084       int i = 1;
00085       int n = x.size();
00086 
00087       while ((i < n) &&
00088              (x[i][0].min() == x[i][1].max()) &&
00089              (x[i][0].max() == x[i][1].min())) { // case: =
00090         assert(x[i][0].assigned() && x[i][1].assigned() &&
00091                (x[i][0].val() == x[i][1].val()));
00092         i++;
00093       }
00094 
00095       if (i == n) { // case: $
00096         if (strict)
00097           goto rewrite_le;
00098         else
00099           goto rewrite_lq;
00100       }
00101 
00102       if (x[i][0].max() < x[i][1].min()) // case: <
00103         goto rewrite_lq;
00104 
00105       if (x[i][0].min() > x[i][1].max()) // case: >
00106         goto rewrite_le;
00107 
00108       if (i > 1) {
00109         // Remove equal elements [1...i-1], keep element [0]
00110         x[i-1]=x[0]; x.drop_fst(i-1);
00111       }
00112     }
00113 
00114     if (x[1][0].max() <= x[1][1].min()) {
00115       // case: <= (invariant: not =, <)
00116       /*
00117        * State 3
00118        *   prefix: (?|<=),<=
00119        *
00120        */
00121       int i = 2;
00122       int n = x.size();
00123 
00124       while ((i < n) && (x[i][0].max() == x[i][1].min())) // case: <=, =
00125         i++;
00126 
00127       if (i == n) { // case: $
00128         if (strict)
00129           return ES_FIX;
00130         else
00131           goto rewrite_lq;
00132       }
00133 
00134       if (x[i][0].max() < x[i][1].min()) // case: <
00135         goto rewrite_lq;
00136 
00137       if (x[i][0].min() > x[i][1].max()) { // case: >
00138         // Eliminate [i]...[n-1]
00139         for (int j=i; j<n; j++)
00140           x[j].cancel(home,this,PC_INT_BND);
00141         x.size(i);
00142         strict = true;
00143       }
00144 
00145       return ES_FIX;
00146     }
00147 
00148     if (x[1][0].min() >= x[1][1].max()) {
00149       // case: >= (invariant: not =, >)
00150       /*
00151        * State 4
00152        *   prefix: (?|<=) >=
00153        *
00154        */
00155       int i = 2;
00156       int n = x.size();
00157 
00158       while ((i < n) && (x[i][0].min() == x[i][1].max()))
00159         // case: >=, =
00160         i++;
00161 
00162       if (i == n) { // case: $
00163         if (strict)
00164           goto rewrite_le;
00165         else
00166           return ES_FIX;
00167       }
00168 
00169       if (x[i][0].min() > x[i][1].max()) // case: >
00170         goto rewrite_le;
00171 
00172       if (x[i][0].max() < x[i][1].min()) { // case: <
00173         // Eliminate [i]...[n-1]
00174         for (int j=i; j<n; j++)
00175           x[j].cancel(home,this,PC_INT_BND);
00176         x.size(i);
00177         strict = false;
00178       }
00179 
00180       return ES_FIX;
00181     }
00182 
00183     return ES_FIX;
00184 
00185   rewrite_le:
00186     GECODE_ES_CHECK(Le<View>::post(home,x[0][0],x[0][1]));
00187     return ES_SUBSUMED;
00188 
00189   rewrite_lq:
00190     GECODE_ES_CHECK(Lq<View>::post(home,x[0][0],x[0][1]));
00191     return ES_SUBSUMED;
00192   }
00193 
00194   template <class View>
00195   ExecStatus
00196   Lex<View>::post(Space* home,
00197                   ViewArray<ViewTuple<View,2> >& xy, bool strict){
00198     if (xy.size() == 0)
00199       return strict ? ES_FAILED : ES_OK;
00200     if (xy.size() == 1)
00201       if (strict)
00202         return Le<View>::post(home,xy[0][0],xy[0][1]);
00203       else
00204         return Lq<View>::post(home,xy[0][0],xy[0][1]);
00205     (void) new (home) Lex<View>(home,xy,strict);
00206     return ES_OK;
00207   }
00208 
00209 }}}
00210 
00211 // STATISTICS: int-prop
00212