View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004, 2012 Artois University and CNRS
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    *  http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   *
19   * Based on the original MiniSat specification from:
20   *
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   *
27   * Contributors:
28   *   CRIL - initial API and implementation
29   *******************************************************************************/
30  package org.sat4j.reader;
31  
32  import java.io.IOException;
33  
34  import org.sat4j.specs.ContradictionException;
35  import org.sat4j.specs.ISolver;
36  import org.sat4j.tools.xplain.HighLevelXplain;
37  
38  public class GroupedCNFReader extends DimacsReader {
39  
40      /**
41  	 * 
42  	 */
43      private static final long serialVersionUID = 1L;
44  
45      private int numberOfComponents;
46  
47      private final HighLevelXplain<ISolver> hlxplain;
48  
49      private int currentComponentIndex;
50  
51      public GroupedCNFReader(HighLevelXplain<ISolver> solver) {
52          super(solver, "gcnf");
53          this.hlxplain = solver;
54      }
55  
56      /**
57       * @param in
58       *            the input stream
59       * @throws IOException
60       *             iff an IO occurs
61       * @throws ParseFormatException
62       *             if the input stream does not comply with the DIMACS format.
63       * @since 2.1
64       */
65      @Override
66      protected void readProblemLine() throws IOException, ParseFormatException {
67  
68          String line = this.scanner.nextLine();
69  
70          if (line == null) {
71              throw new ParseFormatException("premature end of file: <p "
72                      + this.formatString + " ...> expected");
73          }
74          line = line.trim();
75          String[] tokens = line.split("\\s+");
76          if (tokens.length < 5 || !"p".equals(tokens[0])
77                  || !this.formatString.equals(tokens[1])) {
78              throw new ParseFormatException("problem line expected (p "
79                      + this.formatString + " ...)");
80          }
81  
82          int vars;
83  
84          // reads the max var id
85          vars = Integer.parseInt(tokens[2]);
86          assert vars > 0;
87          this.solver.newVar(vars);
88          // reads the number of clauses
89          this.expectedNbOfConstr = Integer.parseInt(tokens[3]);
90          assert this.expectedNbOfConstr > 0;
91          this.numberOfComponents = Integer.parseInt(tokens[4]);
92          this.solver.setExpectedNumberOfClauses(this.expectedNbOfConstr);
93      }
94  
95      /**
96       * @since 2.1
97       */
98      @Override
99      protected boolean handleLine() throws ContradictionException, IOException,
100             ParseFormatException {
101         int lit;
102         boolean added = false;
103         String component = this.scanner.next();
104         if (!component.startsWith("{") || !component.endsWith("}")) {
105             throw new ParseFormatException(
106                     "Component index required at the beginning of the clause");
107         }
108         this.currentComponentIndex = Integer.valueOf(component.substring(1,
109                 component.length() - 1));
110         if (this.currentComponentIndex < 0
111                 || this.currentComponentIndex > this.numberOfComponents) {
112             throw new ParseFormatException("wrong component index: "
113                     + this.currentComponentIndex);
114         }
115         while (!this.scanner.eof()) {
116             lit = this.scanner.nextInt();
117             if (lit == 0) {
118                 if (this.literals.size() > 0) {
119                     flushConstraint();
120                     this.literals.clear();
121                     added = true;
122                 }
123                 break;
124             }
125             this.literals.push(lit);
126         }
127         return added;
128     }
129 
130     /**
131      * 
132      * @throws ContradictionException
133      * @since 2.1
134      */
135     @Override
136     protected void flushConstraint() throws ContradictionException {
137         try {
138             if (this.currentComponentIndex == 0) {
139                 this.hlxplain.addClause(this.literals);
140             } else {
141                 this.hlxplain.addClause(this.literals,
142                         this.currentComponentIndex);
143             }
144         } catch (IllegalArgumentException ex) {
145             if (isVerbose()) {
146                 System.err.println("c Skipping constraint " + this.literals);
147             }
148         }
149     }
150 }