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