1 /* 2 * And.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.constraints; 32 33 import org.jacop.api.UsesQueueVariable; 34 import org.jacop.core.Store; 35 import org.jacop.core.Var; 36 import org.jacop.util.QueueForward; 37 38 import java.util.Arrays; 39 import java.util.List; 40 import java.util.concurrent.atomic.AtomicInteger; 41 42 /** 43 * Constraint c1 /\ c2 ... /\ cn 44 * 45 * @author Krzysztof Kuchcinski and Radoslaw Szymanek 46 * @version 4.8 47 */ 48 public class And extends PrimitiveConstraint implements UsesQueueVariable { 49 50 final static AtomicInteger idNumber = new AtomicInteger(0); 51 52 /** 53 * It specifies a list of constraints which must be satisfied to keep And constraint satisfied. 54 */ 55 protected final PrimitiveConstraint listOfC[]; 56 57 private final QueueForward<PrimitiveConstraint> queueForward; 58 59 /** 60 * It constructs an And constraint based on primitive constraints. The 61 * constraint is satisfied if all constraints are satisfied. 62 * 63 * @param listOfC arraylist of constraints 64 */ And(List<PrimitiveConstraint> listOfC)65 public And(List<PrimitiveConstraint> listOfC) { 66 this(listOfC.toArray(new PrimitiveConstraint[listOfC.size()])); 67 } 68 69 /** 70 * It constructs a simple And constraint based on two primitive constraints. 71 * 72 * @param c1 the first primitive constraint 73 * @param c2 the second primitive constraint 74 */ And(PrimitiveConstraint c1, PrimitiveConstraint c2)75 public And(PrimitiveConstraint c1, PrimitiveConstraint c2) { 76 this(new PrimitiveConstraint[] {c1, c2}); 77 } 78 79 /** 80 * It constructs an And constraint over an array of primitive constraints. 81 * 82 * @param c an array of primitive constraints constituting the And constraint. 83 */ And(PrimitiveConstraint[] c)84 public And(PrimitiveConstraint[] c) { 85 86 checkInputForNullness("c", c); 87 this.queueIndex = 1; 88 this.numberId = idNumber.incrementAndGet(); 89 this.listOfC = Arrays.copyOf(c, c.length); 90 setScope(listOfC); 91 setConstraintScope(listOfC); 92 queueForward = new QueueForward<>(listOfC, arguments()); 93 // KKU, 2019-01-30; next line is wrong! it will always give queueIndex = 0 since primitive constraints have queueIndex = 0 94 // Then... if this constraint is reified, the reified will get queueIndex = 0 as well. 95 //this.queueIndex = Arrays.stream(c).max((a, b) -> Integer.max(a.queueIndex, b.queueIndex)).map(a -> a.queueIndex).orElse(0); 96 97 } 98 99 private boolean propagation; 100 consistency(Store store)101 @Override public void consistency(Store store) { 102 103 propagation = true; 104 105 do { 106 107 // Variable propagation can be set to true again if queueVariable function is being called. 108 propagation = false; 109 110 for (Constraint cc : listOfC) 111 cc.consistency(store); 112 113 } while (propagation); 114 115 } 116 getNestedPruningEvent(Var var, boolean mode)117 @Override public int getNestedPruningEvent(Var var, boolean mode) { 118 return getConsistencyPruningEvent(var); 119 } 120 getDefaultNotConsistencyPruningEvent()121 @Override protected int getDefaultNotConsistencyPruningEvent() { 122 throw new IllegalStateException("Not implemented as more precise version exists."); 123 } 124 getDefaultConsistencyPruningEvent()125 @Override public int getDefaultConsistencyPruningEvent() { 126 throw new IllegalStateException("Not implemented as more precise version exists."); 127 } 128 notConsistency(Store store)129 @Override public void notConsistency(Store store) { 130 131 int numberCertainNotSat = 0; 132 int numberCertainSat = 0; 133 int j = 0; 134 int i = 0; 135 136 while (numberCertainNotSat == 0 && i < listOfC.length) { 137 if (listOfC[i].notSatisfied()) { 138 numberCertainNotSat++; 139 removeConstraint(); 140 } 141 else { 142 if (listOfC[i].satisfied()) 143 numberCertainSat++; 144 else 145 j = i; 146 } 147 i++; 148 } 149 150 if (numberCertainNotSat == 0) { 151 if (numberCertainSat == listOfC.length - 1) { 152 listOfC[j].notConsistency(store); 153 } else if (numberCertainSat == listOfC.length) 154 throw Store.failException; 155 } 156 } 157 queueVariable(int level, Var variable)158 @Override public void queueVariable(int level, Var variable) { 159 160 propagation = true; 161 queueForward.queueForward(level, variable); 162 163 } 164 notSatisfied()165 @Override public boolean notSatisfied() { 166 boolean notSat = false; 167 168 int i = 0; 169 while (!notSat && i < listOfC.length) { 170 notSat = listOfC[i].notSatisfied(); 171 i++; 172 } 173 return notSat; 174 } 175 satisfied()176 @Override public boolean satisfied() { 177 178 for (PrimitiveConstraint c : listOfC) 179 if (!c.satisfied()) 180 return false; 181 182 return true; 183 184 } 185 toString()186 @Override public String toString() { 187 188 StringBuilder result = new StringBuilder(id()); 189 190 result.append(" : And("); 191 192 for (int i = 0; i < listOfC.length; i++) { 193 result.append(listOfC[i]); 194 if (i != listOfC.length - 1) 195 result.append(", "); 196 } 197 result.append(")"); 198 return result.toString(); 199 } 200 201 } 202