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 System.out
182 .println("Ignoring the rest of the file (SATLIB format");
183 break;
184 }
185 added = handleLine();
186 }
187 if (added) {
188 realNbOfConstr++;
189 }
190 }
191 if (checkConstrNb && expectedNbOfConstr != realNbOfConstr) {
192 throw new ParseFormatException("wrong nbclauses parameter. Found "
193 + realNbOfConstr + ", " + expectedNbOfConstr + " expected");
194 }
195 }
196
197
198
199
200
201
202 protected void flushConstraint() throws ContradictionException {
203 solver.addClause(literals);
204 }
205
206
207
208
209 protected boolean handleLine() throws ContradictionException, IOException,
210 ParseFormatException {
211 int lit;
212 boolean added = false;
213 while (!scanner.eof()) {
214 lit = scanner.nextInt();
215 if (lit == 0) {
216 if (literals.size() > 0) {
217 flushConstraint();
218 literals.clear();
219 added = true;
220 }
221 break;
222 }
223 literals.push(lit);
224 }
225 return added;
226 }
227
228 @Override
229 public IProblem parseInstance(InputStream in) throws ParseFormatException,
230 ContradictionException, IOException {
231 scanner = new EfficientScanner(in);
232 return parseInstance();
233 }
234
235 @Override
236 public final IProblem parseInstance(final java.io.Reader in)
237 throws ParseFormatException, ContradictionException, IOException {
238 throw new UnsupportedOperationException();
239
240 }
241
242
243
244
245
246
247
248
249
250 private IProblem parseInstance() throws ParseFormatException,
251 ContradictionException {
252 solver.reset();
253 try {
254 skipComments();
255 readProblemLine();
256 readConstrs();
257 scanner.close();
258 return solver;
259 } catch (IOException e) {
260 throw new ParseFormatException(e);
261 } catch (NumberFormatException e) {
262 throw new ParseFormatException("integer value expected ");
263 }
264 }
265
266 @Override
267 public String decode(int[] model) {
268 StringBuffer stb = new StringBuffer();
269 for (int i = 0; i < model.length; i++) {
270 stb.append(model[i]);
271 stb.append(" ");
272 }
273 stb.append("0");
274 return stb.toString();
275 }
276
277 @Override
278 public void decode(int[] model, PrintWriter out) {
279 for (int i = 0; i < model.length; i++) {
280 out.print(model[i]);
281 out.print(" ");
282 }
283 out.print("0");
284 }
285
286 protected ISolver getSolver() {
287 return solver;
288 }
289 }