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

projector.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Guido Tack, 2006
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-17 16:23:29 +0200 (Thu, 17 Aug 2006) $ by $Author: tack $
00010  *     $Revision: 3547 $
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 #include "gecode/set/projectors.hh"
00023 
00024 namespace Gecode {
00025 
00026   int
00027   Projector::arity(void) const {
00028     return _arity;
00029   }
00030 
00031   void codeScope(Support::DynamicArray<int>& s, const SetExprCode& c,
00032                  bool monotone) {
00033     int tmp = 0;
00034     for (int i=0; i<c.size(); i++) {
00035       switch (c[i]) {
00036       case SetExprCode::COMPLEMENT:
00037       case SetExprCode::INTER:
00038       case SetExprCode::UNION:
00039       case SetExprCode::EMPTY:
00040       case SetExprCode::UNIVERSE:
00041         break;
00042       case SetExprCode::GLB:
00043         if (s[tmp] == Set::PC_SET_ANY+1)
00044           s[tmp] = monotone ? Set::PC_SET_CGLB : Set::PC_SET_CLUB;
00045         else if (monotone && s[tmp] != Set::PC_SET_CGLB)
00046           s[tmp] = Set::PC_SET_ANY;
00047         else if (!monotone && s[tmp] != Set::PC_SET_CLUB)
00048           s[tmp] = Set::PC_SET_ANY;
00049         break;
00050       case SetExprCode::LUB:
00051         if (s[tmp] == Set::PC_SET_ANY+1)
00052           s[tmp] = monotone ? Set::PC_SET_CLUB : Set::PC_SET_CGLB;
00053         else if (monotone && s[tmp] != Set::PC_SET_CLUB)
00054           s[tmp] = Set::PC_SET_ANY;
00055         else if (!monotone && s[tmp] != Set::PC_SET_CGLB)
00056           s[tmp] = Set::PC_SET_ANY;
00057         break;
00058       default:
00059         tmp = c[i]-SetExprCode::LAST;
00060         break;
00061       }
00062     }
00063   }
00064 
00065   void
00066   Projector::scope(Support::DynamicArray<int>& s) const {
00067     codeScope(s, glb, false);
00068     codeScope(s, lub, true);
00069   }
00070 
00071   ExecStatus
00072   Projector::check(Space* home, ViewArray<Set::SetView>& x) {
00073     {
00074       // Check if glb violates current upper bound of x[i]
00075       SetExprRanges glbranges(x,glb,false);
00076       Iter::Ranges::Size<SetExprRanges> g(glbranges);
00077       Set::LubRanges<Set::SetView> xir(x[i]);
00078       if (!Iter::Ranges::subset(g, xir))
00079         return ES_FAILED;
00080       while (g()) ++g;
00081       if (g.size() > x[i].cardMax()) {
00082         return ES_FAILED;
00083       } 
00084     }
00085     {
00086       // Check if lub violates current lower bound of x[i]
00087       SetExprRanges lubranges(x,lub,true);
00088       Iter::Ranges::Size<SetExprRanges> l(lubranges);
00089       Set::GlbRanges<Set::SetView> xir(x[i]);
00090       if (!Iter::Ranges::subset(xir, l))
00091         return ES_FAILED;
00092       while (l()) ++l;
00093       if (l.size() < x[i].cardMin()) {
00094         return ES_FAILED;
00095       }
00096     }
00097     {
00098       // Check if monotone interpretation of lower bound is
00099       // contained in current lower bound of x[i]. If not, the constraint
00100       // is not subsumed.
00101       SetExprRanges glbranges(x,glb,true);
00102       Set::GlbRanges<Set::SetView> xir(x[i]);
00103       if (!Iter::Ranges::subset(glbranges, xir)) {
00104         return ES_FIX;
00105       }
00106     }
00107     {
00108       // Check if current upper bound of x[i] if contained in
00109       // anti-monotone interpretation of upper bound. If not, the constraint
00110       // is not subsumed.
00111       SetExprRanges lubranges(x,lub,false);
00112       Set::LubRanges<Set::SetView> xir(x[i]);
00113       if (!Iter::Ranges::subset(xir, lubranges)) {
00114         return ES_FIX;
00115       }
00116     }
00117     // Both bounds, interpreted monotonically (glb) and anti-monotonically
00118     // (lub) are contained in the respective bounds of x[i]. This means
00119     // that the bounds are entailed.
00120     return ES_SUBSUMED;
00121   }
00122 
00123 }
00124 
00125 // STATISTICS: set-prop