1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  *  Main authors:
4  *     Guido Tack <tack@gecode.org>
5  *     Christian Schulte <schulte@gecode.org>
6  *
7  *  Copyright:
8  *     Guido Tack, 2004
9  *     Christian Schulte, 2004
10  *
11  *  This file is part of Gecode, the generic constraint
12  *  development environment:
13  *     http://www.gecode.org
14  *
15  *  Permission is hereby granted, free of charge, to any person obtaining
16  *  a copy of this software and associated documentation files (the
17  *  "Software"), to deal in the Software without restriction, including
18  *  without limitation the rights to use, copy, modify, merge, publish,
19  *  distribute, sublicense, and/or sell copies of the Software, and to
20  *  permit persons to whom the Software is furnished to do so, subject to
21  *  the following conditions:
22  *
23  *  The above copyright notice and this permission notice shall be
24  *  included in all copies or substantial portions of the Software.
25  *
26  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33  *
34  */
35 
36 #include <gecode/set.hh>
37 
38 
39 namespace Gecode { namespace Set {
40 
41   /*
42    * "Standard" tell operations
43    *
44    */
45   ModEvent
cardMin_full(Space & home)46   SetVarImp::cardMin_full(Space& home) {
47     ModEvent me = ME_SET_CARD;
48     if (cardMin() == lub.size()) {
49       glb.become(home, lub);
50       me = ME_SET_VAL;
51     }
52     SetDelta d;
53     return notify(home, me, d);
54   }
55 
56   ModEvent
cardMax_full(Space & home)57   SetVarImp::cardMax_full(Space& home) {
58     ModEvent me = ME_SET_CARD;
59     if (cardMax() == glb.size()) {
60       lub.become(home, glb);
61       me = ME_SET_VAL;
62     }
63     SetDelta d;
64     return notify(home, me, d);
65   }
66 
67   ModEvent
processLubChange(Space & home,SetDelta & d)68   SetVarImp::processLubChange(Space& home, SetDelta& d) {
69     ModEvent me = ME_SET_LUB;
70     if (cardMax() > lub.size()) {
71       lub.card(lub.size());
72       if (cardMin() > cardMax()) {
73         glb.become(home, lub);
74         glb.card(glb.size());
75         lub.card(glb.size());
76         return fail(home);
77       }
78       me = ME_SET_CLUB;
79     }
80     if (cardMax() == lub.size() && cardMin() == cardMax()) {
81       glb.become(home, lub);
82       me = ME_SET_VAL;
83       assert(d.glbMin() == 1);
84       assert(d.glbMax() == 0);
85     }
86     return notify(home, me, d);
87   }
88 
89   ModEvent
processGlbChange(Space & home,SetDelta & d)90   SetVarImp::processGlbChange(Space& home, SetDelta& d) {
91     ModEvent me = ME_SET_GLB;
92     if (cardMin() < glb.size()) {
93       glb.card(glb.size());
94       if (cardMin() > cardMax()) {
95         glb.become(home, lub);
96         glb.card(glb.size());
97         lub.card(glb.size());
98         return fail(home);
99       }
100       me = ME_SET_CGLB;
101     }
102     if (cardMin() == glb.size() && cardMin() == cardMax()) {
103       lub.become(home, glb);
104       me = ME_SET_VAL;
105       assert(d.lubMin() == 1);
106       assert(d.lubMax() == 0);
107     }
108     return notify(home, me, d);
109   }
110 
111   /*
112    * Copying variables
113    *
114    */
115 
116   forceinline
SetVarImp(Space & home,SetVarImp & x)117   SetVarImp::SetVarImp(Space& home, SetVarImp& x)
118     : SetVarImpBase(home,x) {
119     lub.update(home, x.lub);
120     glb.card(x.cardMin());
121     lub.card(x.cardMax());
122     if (x.assigned()) {
123       glb.become(home,lub);
124     } else {
125       glb.update(home,x.glb);
126     }
127   }
128 
129 
130   SetVarImp*
perform_copy(Space & home)131   SetVarImp::perform_copy(Space& home) {
132     return new (home) SetVarImp(home,*this);
133   }
134 
135   /*
136    * Dependencies
137    *
138    */
139   void
subscribe(Space & home,Propagator & p,PropCond pc,bool schedule)140   SetVarImp::subscribe(Space& home, Propagator& p, PropCond pc,
141                        bool schedule) {
142     SetVarImpBase::subscribe(home,p,pc,assigned(),schedule);
143   }
144   void
subscribe(Space & home,Advisor & a,bool fail)145   SetVarImp::subscribe(Space& home, Advisor& a, bool fail) {
146     SetVarImpBase::subscribe(home,a,assigned(),fail);
147   }
148   void
reschedule(Space & home,Propagator & p,PropCond pc)149   SetVarImp::reschedule(Space& home, Propagator& p, PropCond pc) {
150     SetVarImpBase::reschedule(home,p,pc,assigned());
151   }
152 
153 
154 }}
155 
156 // STATISTICS: set-var
157 
158