1 /*
2  * AeqB.java
3  * This file is part of JaCoP.
4  * <p>
5  * JaCoP is a Java Constraint Programming solver.
6  * <p>
7  * Copyright (C) 2000-2008 Krzysztof Kuchcinski and Radoslaw Szymanek
8  * <p>
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  * <p>
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  * <p>
19  * Notwithstanding any other provision of this License, the copyright
20  * owners of this work supplement the terms of this License with terms
21  * prohibiting misrepresentation of the origin of this work and requiring
22  * that modified versions of this work be marked in reasonable ways as
23  * different from the original version. This supplement of the license
24  * terms is in accordance with Section 7 of GNU Affero General Public
25  * License version 3.
26  * <p>
27  * You should have received a copy of the GNU Affero General Public License
28  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 package org.jacop.set.constraints;
32 
33 import org.jacop.constraints.PrimitiveConstraint;
34 import org.jacop.core.Store;
35 import org.jacop.set.core.SetDomain;
36 import org.jacop.set.core.SetVar;
37 
38 import java.util.concurrent.atomic.AtomicInteger;
39 
40 /**
41  * It creates an equality constraint to make sure that two set variables
42  * have the same value.
43  *
44  * @author Radoslaw Szymanek and Krzysztof Kuchcinski
45  * @version 4.8
46  */
47 
48 public class AeqB extends PrimitiveConstraint {
49 
50     static AtomicInteger idNumber = new AtomicInteger(0);
51 
52     /**
53      * It specifies set variable a, which must be equal to set variable b.
54      */
55     public SetVar a;
56 
57     /**
58      * It specifies set variable b, which must be equal to set variable a.
59      */
60     public SetVar b;
61 
62     // private boolean aHasChanged = true;
63     // private boolean bHasChanged = true;
64 
65     /**
66      * It constructs an AeqB constraint to restrict the domain of the variables.
67      *
68      * @param a variable a restricted to be equal to b.
69      * @param b variable b restricted to be equal to a.
70      */
AeqB(SetVar a, SetVar b)71     public AeqB(SetVar a, SetVar b) {
72 
73         checkInputForNullness(new String[] {"a", "b"}, new Object[] {a, b});
74 
75         numberId = idNumber.incrementAndGet();
76 
77         this.a = a;
78         this.b = b;
79         setScope(a, b);
80 
81     }
82 
consistency(Store store)83     @Override public void consistency(Store store) {
84 
85         /**
86          * It computes the consistency of the constraint.
87          *
88          * If two set variables are to be equal then they
89          * are always reduced to the intersection of their domains.
90          *
91          * glbA = glbA \/ glbB
92          * glbB = glbA \/ glbB
93          *
94          * lubA = lubA /\ lubB
95          * lubB = lubA /\ lubB
96          *
97          *
98          */
99 
100         // if (bHasChanged)
101         a.domain.in(store.level, a, b.dom());
102 
103         // if (aHasChanged)
104         b.domain.in(store.level, b, a.dom());
105 
106         a.domain.inCardinality(store.level, a, b.domain.card().min(), b.domain.card().max());
107         b.domain.inCardinality(store.level, b, a.domain.card().min(), a.domain.card().max());
108 
109         // aHasChanged = false;
110         // bHasChanged = false;
111 
112     }
113 
notConsistency(Store store)114     @Override public void notConsistency(Store store) {
115 
116         if (a.singleton() && b.singleton() && a.dom().glb().eq(b.dom().glb()))
117             throw Store.failException;
118 
119     }
120 
notSatisfied()121     @Override public boolean notSatisfied() {
122 
123         if (!a.domain.lub().contains(b.domain.glb()) || !b.domain.lub().contains(a.domain.glb()))
124             return true;
125 
126         if (a.singleton() && b.singleton() && !a.domain.glb().eq(b.domain.glb()))
127             return true;
128 
129         return false;
130     }
131 
satisfied()132     @Override public boolean satisfied() {
133 
134         if (grounded() && a.domain.glb().eq(b.domain.glb()))
135             return true;
136 
137         return false;
138     }
139 
getDefaultNestedNotConsistencyPruningEvent()140     @Override protected int getDefaultNestedNotConsistencyPruningEvent() {
141         return SetDomain.ANY;
142     }
143 
getDefaultNestedConsistencyPruningEvent()144     @Override protected int getDefaultNestedConsistencyPruningEvent() {
145         return SetDomain.ANY;
146     }
147 
getDefaultNotConsistencyPruningEvent()148     @Override protected int getDefaultNotConsistencyPruningEvent() {
149         return SetDomain.GROUND;
150     }
151 
getDefaultConsistencyPruningEvent()152     @Override public int getDefaultConsistencyPruningEvent() {
153         return SetDomain.ANY;
154     }
155 
toString()156     @Override public String toString() {
157         return id() + " : AeqB(" + a + ", " + b + " )";
158     }
159 
160 }
161