| 
 1 | 
  
 | package org.sat4j.reader; | 
| 
 2 | 
  
 |  | 
| 
 3 | 
  
 | import java.io.BufferedReader; | 
| 
 4 | 
  
 | import java.io.IOException; | 
| 
 5 | 
  
 | import java.io.LineNumberReader; | 
| 
 6 | 
  
 | import java.io.Serializable; | 
| 
 7 | 
  
 | import java.math.BigInteger; | 
| 
 8 | 
  
 |  | 
| 
 9 | 
  
 | import org.sat4j.core.Vec; | 
| 
 10 | 
  
 | import org.sat4j.core.VecInt; | 
| 
 11 | 
  
 | import org.sat4j.specs.ContradictionException; | 
| 
 12 | 
  
 | import org.sat4j.specs.IProblem; | 
| 
 13 | 
  
 | import org.sat4j.specs.ISolver; | 
| 
 14 | 
  
 | import org.sat4j.specs.IVec; | 
| 
 15 | 
  
 | import org.sat4j.specs.IVecInt; | 
| 
 16 | 
  
 |  | 
| 
 17 | 
  
 |  | 
| 
 18 | 
  
 |  | 
| 
 19 | 
  
 |  | 
| 
 20 | 
  
 |  | 
| 
 21 | 
  
 |  | 
| 
 22 | 
  
 |  | 
| 
 23 | 
  
 |  | 
| 
 24 | 
  
 | public class OPBReader2005 extends Reader implements Serializable { | 
| 
 25 | 
  
 |  | 
| 
 26 | 
  
 |      | 
| 
 27 | 
  
 |  | 
| 
 28 | 
  
 |  | 
| 
 29 | 
  
 |     private static final long serialVersionUID = 1L; | 
| 
 30 | 
  
 |  | 
| 
 31 | 
  
 |     private final ISolver solver; | 
| 
 32 | 
  
 |  | 
| 
 33 | 
  
 |     private final IVecInt lits; | 
| 
 34 | 
  
 |  | 
| 
 35 | 
  
 |     private final IVec<BigInteger> coeffs; | 
| 
 36 | 
  
 |  | 
| 
 37 | 
  
 |     private BigInteger d; | 
| 
 38 | 
  
 |  | 
| 
 39 | 
  
 |     private String operator; | 
| 
 40 | 
  
 |  | 
| 
 41 | 
  
 |     private final IVecInt objectiveVars = new VecInt(); | 
| 
 42 | 
  
 |  | 
| 
 43 | 
  
 |     private final IVec<BigInteger> objectiveCoeffs = new Vec<BigInteger>(); | 
| 
 44 | 
  
 |  | 
| 
 45 | 
  
 |      | 
| 
 46 | 
  
 |     private boolean hasObjFunc = false; | 
| 
 47 | 
  
 |  | 
| 
 48 | 
  
 |     private int nbVars, nbConstr;  | 
| 
 49 | 
  
 |      | 
| 
 50 | 
  
 |      | 
| 
 51 | 
  
 |  | 
| 
 52 | 
  
 |  | 
| 
 53 | 
  
 |  | 
| 
 54 | 
  
 |  | 
| 
 55 | 
  
 |  | 
| 
 56 | 
  
 |  | 
| 
 57 | 
 0
 |     protected void metaData(int nbvar, int nbconstr) {
 | 
| 
 58 | 
 0
 |         solver.newVar(nbvar);
 | 
| 
 59 | 
  
 |     } | 
| 
 60 | 
  
 |  | 
| 
 61 | 
  
 |      | 
| 
 62 | 
  
 |  | 
| 
 63 | 
  
 |  | 
| 
 64 | 
 0
 |     protected void beginObjective() {
 | 
| 
 65 | 
  
 |     } | 
| 
 66 | 
  
 |  | 
| 
 67 | 
  
 |      | 
| 
 68 | 
  
 |  | 
| 
 69 | 
  
 |  | 
| 
 70 | 
 0
 |     protected void endObjective() {
 | 
| 
 71 | 
  
 |         assert lits.size() == coeffs.size(); | 
| 
 72 | 
  
 |         assert lits.size() == coeffs.size(); | 
| 
 73 | 
 0
 |         for (int i = 0; i < lits.size(); i++) {
 | 
| 
 74 | 
 0
 |             objectiveVars.push(lits.get(i));
 | 
| 
 75 | 
 0
 |             objectiveCoeffs.push(coeffs.get(i));
 | 
| 
 76 | 
  
 |         } | 
| 
 77 | 
  
 |     } | 
| 
 78 | 
  
 |  | 
| 
 79 | 
  
 |      | 
| 
 80 | 
  
 |  | 
| 
 81 | 
  
 |  | 
| 
 82 | 
 0
 |     protected void beginConstraint() {
 | 
| 
 83 | 
 0
 |         lits.clear();
 | 
| 
 84 | 
 0
 |         coeffs.clear();
 | 
| 
 85 | 
  
 |         assert lits.size() == 0; | 
| 
 86 | 
  
 |         assert coeffs.size() == 0; | 
| 
 87 | 
  
 |     } | 
| 
 88 | 
  
 |  | 
| 
 89 | 
  
 |      | 
| 
 90 | 
  
 |  | 
| 
 91 | 
  
 |  | 
| 
 92 | 
  
 |      | 
| 
 93 | 
  
 |  | 
| 
 94 | 
  
 |  | 
| 
 95 | 
 0
 |     protected void endConstraint() throws ContradictionException {
 | 
| 
 96 | 
  
 |  | 
| 
 97 | 
  
 |         assert !(lits.size() == 0); | 
| 
 98 | 
  
 |         assert !(coeffs.size() == 0); | 
| 
 99 | 
  
 |         assert lits.size() == coeffs.size(); | 
| 
 100 | 
  
 |  | 
| 
 101 | 
 0
 |         if ("<=".equals(operator) || "=".equals(operator))
 | 
| 
 102 | 
 0
 |             solver.addPseudoBoolean(lits, coeffs, false, d);
 | 
| 
 103 | 
 0
 |         if (">=".equals(operator) || "=".equals(operator))
 | 
| 
 104 | 
 0
 |             solver.addPseudoBoolean(lits, coeffs, true, d);
 | 
| 
 105 | 
  
 |     } | 
| 
 106 | 
  
 |  | 
| 
 107 | 
  
 |      | 
| 
 108 | 
  
 |  | 
| 
 109 | 
  
 |  | 
| 
 110 | 
  
 |  | 
| 
 111 | 
  
 |  | 
| 
 112 | 
  
 |  | 
| 
 113 | 
 0
 |     protected void constraintTerm(BigInteger coeff, String var) {
 | 
| 
 114 | 
 0
 |         coeffs.push(coeff);
 | 
| 
 115 | 
 0
 |         int id = Integer.parseInt(var.substring(1));
 | 
| 
 116 | 
 0
 |         int lid = ((savedChar == '-') ? -1 : 1) * id;
 | 
| 
 117 | 
 0
 |         lits.push(lid);
 | 
| 
 118 | 
  
 |     } | 
| 
 119 | 
  
 |  | 
| 
 120 | 
  
 |      | 
| 
 121 | 
  
 |  | 
| 
 122 | 
  
 |  | 
| 
 123 | 
  
 |  | 
| 
 124 | 
  
 |  | 
| 
 125 | 
 0
 |     protected void constraintRelOp(String relop) {
 | 
| 
 126 | 
 0
 |         operator = relop;
 | 
| 
 127 | 
  
 |     } | 
| 
 128 | 
  
 |  | 
| 
 129 | 
  
 |      | 
| 
 130 | 
  
 |  | 
| 
 131 | 
  
 |  | 
| 
 132 | 
  
 |  | 
| 
 133 | 
  
 |  | 
| 
 134 | 
  
 |  | 
| 
 135 | 
 0
 |     protected void constraintRightTerm(BigInteger val) {
 | 
| 
 136 | 
 0
 |         d = val;
 | 
| 
 137 | 
  
 |     } | 
| 
 138 | 
  
 |  | 
| 
 139 | 
  
 |     transient BufferedReader in;  | 
| 
 140 | 
  
 |  | 
| 
 141 | 
  
 |     char savedChar;  | 
| 
 142 | 
  
 |  | 
| 
 143 | 
  
 |     boolean charAvailable = false;  | 
| 
 144 | 
  
 |  | 
| 
 145 | 
  
 |     boolean eofReached = false;  | 
| 
 146 | 
  
 |  | 
| 
 147 | 
  
 |      | 
| 
 148 | 
  
 |  | 
| 
 149 | 
  
 |  | 
| 
 150 | 
  
 |  | 
| 
 151 | 
  
 |  | 
| 
 152 | 
 0
 |     private char get() throws IOException {
 | 
| 
 153 | 
 0
 |         int c;
 | 
| 
 154 | 
  
 |  | 
| 
 155 | 
 0
 |         if (charAvailable) {
 | 
| 
 156 | 
 0
 |             charAvailable = false;
 | 
| 
 157 | 
 0
 |             return savedChar;
 | 
| 
 158 | 
  
 |         } | 
| 
 159 | 
  
 |  | 
| 
 160 | 
 0
 |         c = in.read();
 | 
| 
 161 | 
 0
 |         if (c == -1)
 | 
| 
 162 | 
 0
 |             eofReached = true;
 | 
| 
 163 | 
  
 |  | 
| 
 164 | 
 0
 |         return (char) c;
 | 
| 
 165 | 
  
 |     } | 
| 
 166 | 
  
 |  | 
| 
 167 | 
 0
 |     public IVecInt getVars() {
 | 
| 
 168 | 
 0
 |         return objectiveVars;
 | 
| 
 169 | 
  
 |     } | 
| 
 170 | 
  
 |  | 
| 
 171 | 
 0
 |     public IVec<BigInteger> getCoeffs() {
 | 
| 
 172 | 
 0
 |         return objectiveCoeffs;
 | 
| 
 173 | 
  
 |     } | 
| 
 174 | 
  
 |  | 
| 
 175 | 
  
 |      | 
| 
 176 | 
  
 |  | 
| 
 177 | 
  
 |  | 
| 
 178 | 
 0
 |     private void putback(char c) {
 | 
| 
 179 | 
 0
 |         savedChar = c;
 | 
| 
 180 | 
 0
 |         charAvailable = true;
 | 
| 
 181 | 
  
 |     } | 
| 
 182 | 
  
 |  | 
| 
 183 | 
  
 |      | 
| 
 184 | 
  
 |  | 
| 
 185 | 
  
 |  | 
| 
 186 | 
 0
 |     private boolean eof() {
 | 
| 
 187 | 
 0
 |         return eofReached;
 | 
| 
 188 | 
  
 |     } | 
| 
 189 | 
  
 |  | 
| 
 190 | 
  
 |      | 
| 
 191 | 
  
 |  | 
| 
 192 | 
  
 |  | 
| 
 193 | 
  
 |  | 
| 
 194 | 
  
 |  | 
| 
 195 | 
 0
 |     protected void skipSpaces() throws IOException {
 | 
| 
 196 | 
 0
 |         char c;
 | 
| 
 197 | 
  
 |  | 
| 
 198 | 
 0
 |         while (Character.isWhitespace(c = get()))
 | 
| 
 199 | 
  
 |             ; | 
| 
 200 | 
  
 |  | 
| 
 201 | 
 0
 |         putback(c);
 | 
| 
 202 | 
  
 |     } | 
| 
 203 | 
  
 |  | 
| 
 204 | 
  
 |      | 
| 
 205 | 
  
 |  | 
| 
 206 | 
  
 |  | 
| 
 207 | 
  
 |  | 
| 
 208 | 
  
 |  | 
| 
 209 | 
  
 |  | 
| 
 210 | 
 0
 |     public String readWord() throws IOException {
 | 
| 
 211 | 
 0
 |         StringBuffer s = new StringBuffer();
 | 
| 
 212 | 
 0
 |         char c;
 | 
| 
 213 | 
  
 |  | 
| 
 214 | 
 0
 |         skipSpaces();
 | 
| 
 215 | 
  
 |  | 
| 
 216 | 
 0
 |         while (!Character.isWhitespace(c = get()) && !eof())
 | 
| 
 217 | 
 0
 |             s.append(c);
 | 
| 
 218 | 
  
 |  | 
| 
 219 | 
 0
 |         return s.toString();
 | 
| 
 220 | 
  
 |     } | 
| 
 221 | 
  
 |  | 
| 
 222 | 
  
 |      | 
| 
 223 | 
  
 |  | 
| 
 224 | 
  
 |  | 
| 
 225 | 
  
 |  | 
| 
 226 | 
  
 |  | 
| 
 227 | 
  
 |  | 
| 
 228 | 
 0
 |     public void readInteger(StringBuffer s) throws IOException {
 | 
| 
 229 | 
 0
 |         char c;
 | 
| 
 230 | 
  
 |  | 
| 
 231 | 
 0
 |         skipSpaces();
 | 
| 
 232 | 
 0
 |         s.setLength(0);
 | 
| 
 233 | 
  
 |  | 
| 
 234 | 
 0
 |         c = get();
 | 
| 
 235 | 
 0
 |         if (c == '-' || Character.isDigit(c))
 | 
| 
 236 | 
 0
 |             s.append(c);
 | 
| 
 237 | 
  
 |          | 
| 
 238 | 
  
 |  | 
| 
 239 | 
 0
 |         while (Character.isDigit(c = get()) && !eof())
 | 
| 
 240 | 
 0
 |             s.append(c);
 | 
| 
 241 | 
  
 |  | 
| 
 242 | 
 0
 |         putback(c);
 | 
| 
 243 | 
  
 |     } | 
| 
 244 | 
  
 |  | 
| 
 245 | 
  
 |      | 
| 
 246 | 
  
 |  | 
| 
 247 | 
  
 |  | 
| 
 248 | 
  
 |  | 
| 
 249 | 
  
 |  | 
| 
 250 | 
  
 |  | 
| 
 251 | 
  
 |  | 
| 
 252 | 
 0
 |     protected boolean readIdentifier(StringBuffer s) throws IOException, ParseFormatException {
 | 
| 
 253 | 
 0
 |         char c;
 | 
| 
 254 | 
  
 |  | 
| 
 255 | 
 0
 |         s.setLength(0);
 | 
| 
 256 | 
  
 |  | 
| 
 257 | 
 0
 |         skipSpaces();
 | 
| 
 258 | 
  
 |  | 
| 
 259 | 
  
 |          | 
| 
 260 | 
 0
 |         c = get();
 | 
| 
 261 | 
 0
 |         if (eof())
 | 
| 
 262 | 
 0
 |             return false;
 | 
| 
 263 | 
  
 |  | 
| 
 264 | 
 0
 |         if (!Character.isLetter(c) && c != '_') {
 | 
| 
 265 | 
 0
 |             putback(c);
 | 
| 
 266 | 
 0
 |             return false;
 | 
| 
 267 | 
  
 |         } | 
| 
 268 | 
  
 |  | 
| 
 269 | 
 0
 |         s.append(c);
 | 
| 
 270 | 
  
 |  | 
| 
 271 | 
  
 |          | 
| 
 272 | 
 0
 |         while (true) {
 | 
| 
 273 | 
 0
 |             c = get();
 | 
| 
 274 | 
 0
 |             if (eof())
 | 
| 
 275 | 
 0
 |                 break;
 | 
| 
 276 | 
  
 |  | 
| 
 277 | 
 0
 |             if (Character.isLetter(c) || Character.isDigit(c) || c == '_')
 | 
| 
 278 | 
 0
 |                 s.append(c);
 | 
| 
 279 | 
  
 |             else { | 
| 
 280 | 
 0
 |                 putback(c);
 | 
| 
 281 | 
 0
 |                 break;
 | 
| 
 282 | 
  
 |             } | 
| 
 283 | 
  
 |         } | 
| 
 284 | 
  
 |  | 
| 
 285 | 
  
 |  | 
| 
 286 | 
 0
 |         int varID = Integer.parseInt(s.substring(1));
 | 
| 
 287 | 
 0
 |         if (varID > nbVars) {
 | 
| 
 288 | 
 0
 |             throw new ParseFormatException("Variable identifier larger than #variables in metadata.");
 | 
| 
 289 | 
  
 |         } | 
| 
 290 | 
 0
 |         return true;
 | 
| 
 291 | 
  
 |     } | 
| 
 292 | 
  
 |  | 
| 
 293 | 
  
 |      | 
| 
 294 | 
  
 |  | 
| 
 295 | 
  
 |  | 
| 
 296 | 
  
 |  | 
| 
 297 | 
  
 |  | 
| 
 298 | 
  
 |  | 
| 
 299 | 
 0
 |     private String readRelOp() throws IOException {
 | 
| 
 300 | 
 0
 |         char c;
 | 
| 
 301 | 
  
 |  | 
| 
 302 | 
 0
 |         skipSpaces();
 | 
| 
 303 | 
  
 |  | 
| 
 304 | 
 0
 |         c = get();
 | 
| 
 305 | 
 0
 |         if (eof())
 | 
| 
 306 | 
 0
 |             return null;
 | 
| 
 307 | 
  
 |  | 
| 
 308 | 
 0
 |         if (c == '=')
 | 
| 
 309 | 
 0
 |             return "=";
 | 
| 
 310 | 
  
 |  | 
| 
 311 | 
 0
 |         if (c == '>' && get() == '=')
 | 
| 
 312 | 
 0
 |             return ">=";
 | 
| 
 313 | 
  
 |  | 
| 
 314 | 
 0
 |         return null;
 | 
| 
 315 | 
  
 |     } | 
| 
 316 | 
  
 |  | 
| 
 317 | 
  
 |      | 
| 
 318 | 
  
 |  | 
| 
 319 | 
  
 |  | 
| 
 320 | 
  
 |  | 
| 
 321 | 
  
 |  | 
| 
 322 | 
  
 |  | 
| 
 323 | 
  
 |  | 
| 
 324 | 
 0
 |     private void readMetaData() throws IOException, ParseFormatException {
 | 
| 
 325 | 
 0
 |         char c;
 | 
| 
 326 | 
 0
 |         String s;
 | 
| 
 327 | 
  
 |  | 
| 
 328 | 
  
 |          | 
| 
 329 | 
 0
 |         c = get();
 | 
| 
 330 | 
 0
 |         if (c != '*')
 | 
| 
 331 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 332 | 
  
 |                     "First line of input file should be a comment"); | 
| 
 333 | 
  
 |  | 
| 
 334 | 
 0
 |         s = readWord();
 | 
| 
 335 | 
 0
 |         if (eof() || !"#variable=".equals(s))
 | 
| 
 336 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 337 | 
  
 |                     "First line should contain #variable= as first keyword"); | 
| 
 338 | 
  
 |  | 
| 
 339 | 
 0
 |         nbVars = Integer.parseInt(readWord());
 | 
| 
 340 | 
  
 |  | 
| 
 341 | 
 0
 |         s = readWord();
 | 
| 
 342 | 
 0
 |         if (eof() || !"#constraint=".equals(s))
 | 
| 
 343 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 344 | 
  
 |                     "First line should contain #constraint= as second keyword"); | 
| 
 345 | 
  
 |  | 
| 
 346 | 
 0
 |         nbConstr = Integer.parseInt(readWord());
 | 
| 
 347 | 
  
 |  | 
| 
 348 | 
  
 |          | 
| 
 349 | 
 0
 |         in.readLine();
 | 
| 
 350 | 
  
 |  | 
| 
 351 | 
  
 |          | 
| 
 352 | 
 0
 |         metaData(nbVars, nbConstr);
 | 
| 
 353 | 
  
 |     } | 
| 
 354 | 
  
 |  | 
| 
 355 | 
  
 |      | 
| 
 356 | 
  
 |  | 
| 
 357 | 
  
 |  | 
| 
 358 | 
  
 |  | 
| 
 359 | 
  
 |  | 
| 
 360 | 
 0
 |     private void skipComments() throws IOException {
 | 
| 
 361 | 
 0
 |         char c = ' ';
 | 
| 
 362 | 
  
 |  | 
| 
 363 | 
  
 |          | 
| 
 364 | 
  
 |  | 
| 
 365 | 
 0
 |         while (!eof() && (c = get()) == '*') {
 | 
| 
 366 | 
 0
 |             in.readLine();
 | 
| 
 367 | 
  
 |         } | 
| 
 368 | 
  
 |  | 
| 
 369 | 
 0
 |         putback(c);
 | 
| 
 370 | 
  
 |     } | 
| 
 371 | 
  
 |  | 
| 
 372 | 
  
 |      | 
| 
 373 | 
  
 |  | 
| 
 374 | 
  
 |  | 
| 
 375 | 
  
 |  | 
| 
 376 | 
  
 |  | 
| 
 377 | 
  
 |  | 
| 
 378 | 
  
 |  | 
| 
 379 | 
  
 |  | 
| 
 380 | 
 0
 |     protected void readTerm(StringBuffer coeff, StringBuffer var)
 | 
| 
 381 | 
  
 |             throws IOException, ParseFormatException { | 
| 
 382 | 
 0
 |         char c;
 | 
| 
 383 | 
  
 |  | 
| 
 384 | 
 0
 |         readInteger(coeff);
 | 
| 
 385 | 
  
 |  | 
| 
 386 | 
 0
 |         skipSpaces();
 | 
| 
 387 | 
 0
 |         c = get();
 | 
| 
 388 | 
 0
 |         if (c != '*')
 | 
| 
 389 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 390 | 
  
 |                     "'*' expected between a coefficient and a variable"); | 
| 
 391 | 
  
 |  | 
| 
 392 | 
 0
 |         if (!readIdentifier(var))
 | 
| 
 393 | 
 0
 |             throw new ParseFormatException("identifier expected");
 | 
| 
 394 | 
  
 |     } | 
| 
 395 | 
  
 |  | 
| 
 396 | 
  
 |      | 
| 
 397 | 
  
 |  | 
| 
 398 | 
  
 |  | 
| 
 399 | 
  
 |  | 
| 
 400 | 
  
 |  | 
| 
 401 | 
  
 |  | 
| 
 402 | 
  
 |  | 
| 
 403 | 
 0
 |     private void readObjective() throws IOException, ParseFormatException {
 | 
| 
 404 | 
 0
 |         char c;
 | 
| 
 405 | 
 0
 |         StringBuffer var = new StringBuffer();
 | 
| 
 406 | 
 0
 |         StringBuffer coeff = new StringBuffer();
 | 
| 
 407 | 
  
 |  | 
| 
 408 | 
  
 |          | 
| 
 409 | 
  
 |  | 
| 
 410 | 
 0
 |         skipSpaces();
 | 
| 
 411 | 
 0
 |         c = get();
 | 
| 
 412 | 
 0
 |         if (c != 'm') {
 | 
| 
 413 | 
  
 |              | 
| 
 414 | 
 0
 |             putback(c);
 | 
| 
 415 | 
 0
 |             return;
 | 
| 
 416 | 
  
 |         } | 
| 
 417 | 
  
 |  | 
| 
 418 | 
 0
 |         hasObjFunc = true;
 | 
| 
 419 | 
 0
 |         if (get() == 'i' && get() == 'n' && get() == ':') {
 | 
| 
 420 | 
 0
 |             beginObjective(); 
 | 
| 
 421 | 
  
 |  | 
| 
 422 | 
 0
 |             while (!eof()) {
 | 
| 
 423 | 
 0
 |                 readTerm(coeff, var);
 | 
| 
 424 | 
 0
 |                 constraintTerm(new BigInteger(coeff.toString()), var.toString()); 
 | 
| 
 425 | 
  
 |  | 
| 
 426 | 
 0
 |                 skipSpaces();
 | 
| 
 427 | 
 0
 |                 c = get();
 | 
| 
 428 | 
 0
 |                 if (c == ';')
 | 
| 
 429 | 
 0
 |                     break; 
 | 
| 
 430 | 
  
 |  | 
| 
 431 | 
 0
 |                 else if (c == '-' || c == '+' || Character.isDigit(c))
 | 
| 
 432 | 
 0
 |                     putback(c);
 | 
| 
 433 | 
  
 |                 else | 
| 
 434 | 
 0
 |                     throw new ParseFormatException(
 | 
| 
 435 | 
  
 |                             "unexpected character in objective function"); | 
| 
 436 | 
  
 |             } | 
| 
 437 | 
  
 |  | 
| 
 438 | 
 0
 |             endObjective();
 | 
| 
 439 | 
  
 |         } else | 
| 
 440 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 441 | 
  
 |                     "input format error: 'min:' expected"); | 
| 
 442 | 
  
 |     } | 
| 
 443 | 
  
 |  | 
| 
 444 | 
  
 |      | 
| 
 445 | 
  
 |  | 
| 
 446 | 
  
 |  | 
| 
 447 | 
  
 |  | 
| 
 448 | 
  
 |  | 
| 
 449 | 
  
 |  | 
| 
 450 | 
  
 |  | 
| 
 451 | 
 0
 |     private void readConstraint() throws IOException, ParseFormatException,
 | 
| 
 452 | 
  
 |             ContradictionException { | 
| 
 453 | 
 0
 |         StringBuffer var = new StringBuffer();
 | 
| 
 454 | 
 0
 |         StringBuffer coeff = new StringBuffer();
 | 
| 
 455 | 
 0
 |         char c;
 | 
| 
 456 | 
  
 |  | 
| 
 457 | 
 0
 |         beginConstraint();
 | 
| 
 458 | 
  
 |  | 
| 
 459 | 
 0
 |         while (!eof()) {
 | 
| 
 460 | 
 0
 |             readTerm(coeff, var);
 | 
| 
 461 | 
 0
 |             constraintTerm(new BigInteger(coeff.toString()), var.toString());
 | 
| 
 462 | 
  
 |  | 
| 
 463 | 
 0
 |             skipSpaces();
 | 
| 
 464 | 
 0
 |             c = get();
 | 
| 
 465 | 
 0
 |             if (c == '>' || c == '=') {
 | 
| 
 466 | 
  
 |                  | 
| 
 467 | 
 0
 |                 putback(c);
 | 
| 
 468 | 
 0
 |                 break;
 | 
| 
 469 | 
 0
 |             } else if (c == '-' || c == '+' || Character.isDigit(c))
 | 
| 
 470 | 
 0
 |                 putback(c);
 | 
| 
 471 | 
  
 |             else { | 
| 
 472 | 
 0
 |                 throw new ParseFormatException(
 | 
| 
 473 | 
  
 |                         "unexpected character in constraint"); | 
| 
 474 | 
  
 |             } | 
| 
 475 | 
  
 |         } | 
| 
 476 | 
  
 |  | 
| 
 477 | 
 0
 |         if (eof())
 | 
| 
 478 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 479 | 
  
 |                     "unexpected EOF before end of constraint"); | 
| 
 480 | 
  
 |  | 
| 
 481 | 
 0
 |         String relop;
 | 
| 
 482 | 
 0
 |         if ((relop = readRelOp()) == null) {
 | 
| 
 483 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 484 | 
  
 |                     "unexpected relational operator in constraint"); | 
| 
 485 | 
  
 |  | 
| 
 486 | 
  
 |         } | 
| 
 487 | 
 0
 |         constraintRelOp(relop);
 | 
| 
 488 | 
 0
 |         readInteger(coeff);
 | 
| 
 489 | 
 0
 |         constraintRightTerm(new BigInteger(coeff.toString()));
 | 
| 
 490 | 
  
 |  | 
| 
 491 | 
 0
 |         skipSpaces();
 | 
| 
 492 | 
 0
 |         c = get();
 | 
| 
 493 | 
 0
 |         if (eof() || c != ';')
 | 
| 
 494 | 
 0
 |             throw new ParseFormatException(
 | 
| 
 495 | 
  
 |                     "semicolon expected at end of constraint"); | 
| 
 496 | 
  
 |  | 
| 
 497 | 
 0
 |         endConstraint();
 | 
| 
 498 | 
  
 |     } | 
| 
 499 | 
  
 |  | 
| 
 500 | 
 0
 |     public OPBReader2005(ISolver solver) {
 | 
| 
 501 | 
 0
 |         this.solver = solver;
 | 
| 
 502 | 
 0
 |         lits = new VecInt();
 | 
| 
 503 | 
 0
 |         coeffs = new Vec<BigInteger>();
 | 
| 
 504 | 
  
 |     } | 
| 
 505 | 
  
 |  | 
| 
 506 | 
  
 |      | 
| 
 507 | 
  
 |  | 
| 
 508 | 
  
 |  | 
| 
 509 | 
  
 |  | 
| 
 510 | 
  
 |  | 
| 
 511 | 
  
 |  | 
| 
 512 | 
  
 |  | 
| 
 513 | 
  
 |  | 
| 
 514 | 
 0
 |     public void parse() throws IOException, ParseFormatException,
 | 
| 
 515 | 
  
 |             ContradictionException { | 
| 
 516 | 
 0
 |         readMetaData();
 | 
| 
 517 | 
  
 |  | 
| 
 518 | 
 0
 |         skipComments();
 | 
| 
 519 | 
  
 |  | 
| 
 520 | 
 0
 |         readObjective();
 | 
| 
 521 | 
  
 |  | 
| 
 522 | 
  
 |          | 
| 
 523 | 
 0
 |         int nbConstraintsRead = 0;
 | 
| 
 524 | 
 0
 |         char c;
 | 
| 
 525 | 
 0
 |         while (!eof()) {
 | 
| 
 526 | 
 0
 |             skipSpaces();
 | 
| 
 527 | 
 0
 |             if (eof())
 | 
| 
 528 | 
 0
 |                 break;
 | 
| 
 529 | 
  
 |  | 
| 
 530 | 
 0
 |             c=get();
 | 
| 
 531 | 
 0
 |             putback(c);
 | 
| 
 532 | 
 0
 |             if(c=='*')
 | 
| 
 533 | 
 0
 |               skipComments();
 | 
| 
 534 | 
  
 |  | 
| 
 535 | 
 0
 |             if (eof())
 | 
| 
 536 | 
 0
 |                 break;
 | 
| 
 537 | 
  
 |              | 
| 
 538 | 
 0
 |             readConstraint();
 | 
| 
 539 | 
 0
 |             nbConstraintsRead++;
 | 
| 
 540 | 
  
 |         } | 
| 
 541 | 
  
 |          | 
| 
 542 | 
 0
 |         if (nbConstraintsRead != nbConstr) {
 | 
| 
 543 | 
 0
 |             throw new ParseFormatException("Number of constraints read is different from metadata.");
 | 
| 
 544 | 
  
 |         } | 
| 
 545 | 
  
 |     } | 
| 
 546 | 
  
 |  | 
| 
 547 | 
 0
 |     @Override
 | 
| 
 548 | 
  
 |     public final IProblem parseInstance(final java.io.Reader in)  | 
| 
 549 | 
  
 |         throws ParseFormatException, ContradictionException { | 
| 
 550 | 
 0
 |         return parseInstance(new LineNumberReader(in));
 | 
| 
 551 | 
  
 |     } | 
| 
 552 | 
  
 |  | 
| 
 553 | 
 0
 |     private IProblem parseInstance(LineNumberReader in) 
 | 
| 
 554 | 
  
 |         throws ParseFormatException, ContradictionException { | 
| 
 555 | 
 0
 |         solver.reset();
 | 
| 
 556 | 
 0
 |         this.in = in;
 | 
| 
 557 | 
 0
 |         try {
 | 
| 
 558 | 
 0
 |             parse();
 | 
| 
 559 | 
 0
 |             return solver;
 | 
| 
 560 | 
  
 |         } catch (IOException e) { | 
| 
 561 | 
 0
 |             throw new ParseFormatException(e);
 | 
| 
 562 | 
  
 |         } | 
| 
 563 | 
  
 |     } | 
| 
 564 | 
  
 |  | 
| 
 565 | 
 0
 |     @Override
 | 
| 
 566 | 
  
 |     public String decode(int[] model) { | 
| 
 567 | 
 0
 |         StringBuffer stb = new StringBuffer();
 | 
| 
 568 | 
  
 |  | 
| 
 569 | 
 0
 |         for (int i = 0; i < model.length; i++) {
 | 
| 
 570 | 
 0
 |             if (model[i] < 0) {
 | 
| 
 571 | 
 0
 |                 stb.append("-x");
 | 
| 
 572 | 
 0
 |                 stb.append(-model[i]);
 | 
| 
 573 | 
  
 |             } else { | 
| 
 574 | 
 0
 |                 stb.append("x");
 | 
| 
 575 | 
 0
 |                 stb.append(model[i]);
 | 
| 
 576 | 
  
 |             } | 
| 
 577 | 
 0
 |             stb.append(" ");
 | 
| 
 578 | 
  
 |         } | 
| 
 579 | 
 0
 |         return stb.toString();
 | 
| 
 580 | 
  
 |     } | 
| 
 581 | 
  
 |  | 
| 
 582 | 
 0
 |     public ObjectiveFunction getObjectiveFunction() {
 | 
| 
 583 | 
 0
 |         if (hasObjFunc)
 | 
| 
 584 | 
 0
 |             return new ObjectiveFunction(getVars(), getCoeffs());
 | 
| 
 585 | 
 0
 |         return null;
 | 
| 
 586 | 
  
 |     } | 
| 
 587 | 
  
 |  | 
| 
 588 | 
  
 | } |