1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.sat4j.reader;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.PrintWriter;
33 import java.io.Serializable;
34
35 import org.sat4j.core.VecInt;
36 import org.sat4j.specs.ContradictionException;
37 import org.sat4j.specs.IProblem;
38 import org.sat4j.specs.ISolver;
39 import org.sat4j.specs.IVecInt;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public class DimacsReader extends Reader implements Serializable {
63
64 private static final long serialVersionUID = 1L;
65
66 protected int expectedNbOfConstr;
67
68 protected final ISolver solver;
69
70 private boolean checkConstrNb = true;
71
72 protected final String formatString;
73
74
75
76
77 protected EfficientScanner scanner;
78
79 public DimacsReader(ISolver solver) {
80 this(solver, "cnf");
81 }
82
83 public DimacsReader(ISolver solver, String format) {
84 this.solver = solver;
85 formatString = format;
86 }
87
88 public void disableNumberOfConstraintCheck() {
89 checkConstrNb = false;
90 }
91
92
93
94
95
96
97
98
99
100
101 protected void skipComments() throws IOException {
102 scanner.skipComments();
103 }
104
105
106
107
108
109
110
111
112
113
114 protected void readProblemLine() throws IOException, ParseFormatException {
115
116 String line = scanner.nextLine().trim();
117
118 if (line == null) {
119 throw new ParseFormatException(
120 "premature end of file: <p cnf ...> expected");
121 }
122 String[] tokens = line.split("\\s+");
123 if (tokens.length < 4 || !"p".equals(tokens[0])
124 || !formatString.equals(tokens[1])) {
125 throw new ParseFormatException("problem line expected (p cnf ...)");
126 }
127
128 int vars;
129
130
131 vars = Integer.parseInt(tokens[2]);
132 assert vars > 0;
133 solver.newVar(vars);
134
135 expectedNbOfConstr = Integer.parseInt(tokens[3]);
136 assert expectedNbOfConstr > 0;
137 solver.setExpectedNumberOfClauses(expectedNbOfConstr);
138 }
139
140
141
142
143 protected IVecInt literals = new VecInt();
144
145
146
147
148
149
150
151
152
153
154
155
156 protected void readConstrs() throws IOException, ParseFormatException,
157 ContradictionException {
158 int realNbOfConstr = 0;
159
160 literals.clear();
161 boolean needToContinue = true;
162
163 while (needToContinue) {
164 boolean added = false;
165 if (scanner.eof()) {
166
167 if (literals.size() > 0) {
168
169 flushConstraint();
170 added = true;
171 }
172 needToContinue = false;
173 } else {
174 if (scanner.currentChar() == 'c') {
175
176 scanner.skipRestOfLine();
177 continue;
178 }
179 if (scanner.currentChar() == '%'
180 && expectedNbOfConstr == realNbOfConstr) {
181 if (solver.isVerbose()) {
182 System.out
183 .println("Ignoring the rest of the file (SATLIB format");
184 }
185 break;
186 }
187 added = handleLine();
188 }
189 if (added) {
190 realNbOfConstr++;
191 }
192 }
193 if (checkConstrNb && expectedNbOfConstr != realNbOfConstr) {
194 throw new ParseFormatException("wrong nbclauses parameter. Found "
195 + realNbOfConstr + ", " + expectedNbOfConstr + " expected");
196 }
197 }
198
199
200
201
202
203
204 protected void flushConstraint() throws ContradictionException {
205 solver.addClause(literals);
206 }
207
208
209
210
211 protected boolean handleLine() throws ContradictionException, IOException,
212 ParseFormatException {
213 int lit;
214 boolean added = false;
215 while (!scanner.eof()) {
216 lit = scanner.nextInt();
217 if (lit == 0) {
218 if (literals.size() > 0) {
219 flushConstraint();
220 literals.clear();
221 added = true;
222 }
223 break;
224 }
225 literals.push(lit);
226 }
227 return added;
228 }
229
230 @Override
231 public IProblem parseInstance(InputStream in) throws ParseFormatException,
232 ContradictionException, IOException {
233 scanner = new EfficientScanner(in);
234 return parseInstance();
235 }
236
237 @Override
238 public final IProblem parseInstance(final java.io.Reader in)
239 throws ParseFormatException, ContradictionException, IOException {
240 throw new UnsupportedOperationException();
241
242 }
243
244
245
246
247
248
249
250
251
252 private IProblem parseInstance() throws ParseFormatException,
253 ContradictionException {
254 solver.reset();
255 try {
256 skipComments();
257 readProblemLine();
258 readConstrs();
259 scanner.close();
260 return solver;
261 } catch (IOException e) {
262 throw new ParseFormatException(e);
263 } catch (NumberFormatException e) {
264 throw new ParseFormatException("integer value expected ");
265 }
266 }
267
268 @Override
269 public String decode(int[] model) {
270 StringBuffer stb = new StringBuffer();
271 for (int i = 0; i < model.length; i++) {
272 stb.append(model[i]);
273 stb.append(" ");
274 }
275 stb.append("0");
276 return stb.toString();
277 }
278
279 @Override
280 public void decode(int[] model, PrintWriter out) {
281 for (int i = 0; i < model.length; i++) {
282 out.print(model[i]);
283 out.print(" ");
284 }
285 out.print("0");
286 }
287
288 protected ISolver getSolver() {
289 return solver;
290 }
291 }