1 /* 2 * CardAeqX.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.api.SatisfiedPresent; 34 import org.jacop.constraints.Constraint; 35 import org.jacop.core.IntDomain; 36 import org.jacop.core.IntVar; 37 import org.jacop.core.Store; 38 import org.jacop.core.Var; 39 import org.jacop.set.core.SetDomain; 40 import org.jacop.set.core.SetVar; 41 42 import java.util.concurrent.atomic.AtomicInteger; 43 44 /** 45 * The set cardinality constraint. 46 * 47 * @author Radoslaw Szymanek and Krzysztof Kuchcinski 48 * @version 3.1 49 */ 50 51 public class CardAeqX extends Constraint implements SatisfiedPresent { 52 53 static AtomicInteger idNumber = new AtomicInteger(0); 54 55 /** 56 * It specifies set variable a which is being restricted. 57 */ 58 public SetVar a; 59 60 /** 61 * It specifies integer variable c specifying the possible cardinality of set variable a. 62 */ 63 public IntVar cardinality; 64 65 /** 66 * It constructs a cardinality constraint to restrict the number of elements 67 * in the set assigned to set variable a. 68 * 69 * @param a variable that is restricted to have the cardinality c. 70 * @param cardinality the variable specifying the possible values for cardinality of set variable a. 71 */ CardAeqX(SetVar a, IntVar cardinality)72 public CardAeqX(SetVar a, IntVar cardinality) { 73 74 checkInputForNullness(new String[] {"a", "cardinality"}, new Object[] {a, cardinality}); 75 76 this.numberId = idNumber.incrementAndGet(); 77 this.a = a; 78 this.cardinality = cardinality; 79 80 setScope(a, cardinality); 81 82 } 83 consistency(Store store)84 @Override public void consistency(Store store) { 85 86 /** 87 * It computes the consistency of the constraint. 88 * 89 * #A = B 90 * 91 * Cardinality of set variable A is equal to int variable B. 92 * 93 * B.in(#glbA, #lubA). 94 * 95 * If #glbA is already equal to maximum allowed cardinality then set is specified by glbA. 96 * if (#glbA == B.max()) then A = glbA 97 * If #lubA is already equal to minimum allowed cardinality then set is specified by lubA. 98 * if (#lubA == B.min()) then A = lubA 99 * 100 * 101 */ 102 103 SetDomain aDom = a.domain; 104 IntDomain card = cardinality.domain; 105 106 //T12 107 int min = Math.max(aDom.glb().getSize(), card.min()); 108 int max = Math.min(aDom.lub().getSize(), card.max()); 109 110 if (min > max) 111 throw Store.failException; 112 113 cardinality.domain.in(store.level, cardinality, min, max); 114 115 //T13 else //T14 116 if (aDom.glb().getSize() == card.max()) 117 a.domain.inLUB(store.level, a, aDom.glb()); 118 else if (aDom.lub().getSize() == card.min()) 119 a.domain.inGLB(store.level, a, aDom.lub()); 120 121 } 122 getConsistencyPruningEvent(Var var)123 @Override public int getConsistencyPruningEvent(Var var) { 124 125 // If consistency function mode 126 if (consistencyPruningEvents != null) { 127 Integer possibleEvent = consistencyPruningEvents.get(var); 128 if (possibleEvent != null) 129 return possibleEvent; 130 } 131 132 if (var == cardinality) 133 return IntDomain.ANY; 134 else 135 return SetDomain.ANY; 136 } 137 getDefaultConsistencyPruningEvent()138 @Override public int getDefaultConsistencyPruningEvent() { 139 throw new IllegalStateException("Not implemented as more precise variant exists."); 140 } 141 satisfied()142 @Override public boolean satisfied() { 143 return (grounded() && a.domain.card().eq(cardinality.dom())); 144 } 145 toString()146 @Override public String toString() { 147 return id() + " : card(" + a + ", " + cardinality + " )"; 148 } 149 150 } 151