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 try {
206 solver.addClause(literals);
207 } catch (IllegalArgumentException ex) {
208 if (isVerbose()) {
209 System.err.println("c Skipping constraint " + literals);
210 }
211 }
212 }
213
214
215
216
217 protected boolean handleLine() throws ContradictionException, IOException,
218 ParseFormatException {
219 int lit;
220 boolean added = false;
221 while (!scanner.eof()) {
222 lit = scanner.nextInt();
223 if (lit == 0) {
224 if (literals.size() > 0) {
225 flushConstraint();
226 literals.clear();
227 added = true;
228 }
229 break;
230 }
231 literals.push(lit);
232 }
233 return added;
234 }
235
236 @Override
237 public IProblem parseInstance(InputStream in) throws ParseFormatException,
238 ContradictionException, IOException {
239 scanner = new EfficientScanner(in);
240 return parseInstance();
241 }
242
243
244
245
246
247
248
249
250
251 private IProblem parseInstance() throws ParseFormatException,
252 ContradictionException {
253 solver.reset();
254 try {
255 skipComments();
256 readProblemLine();
257 readConstrs();
258 scanner.close();
259 return solver;
260 } catch (IOException e) {
261 throw new ParseFormatException(e);
262 } catch (NumberFormatException e) {
263 throw new ParseFormatException("integer value expected ");
264 }
265 }
266
267 @Override
268 public String decode(int[] model) {
269 StringBuffer stb = new StringBuffer();
270 for (int i = 0; i < model.length; i++) {
271 stb.append(model[i]);
272 stb.append(" ");
273 }
274 stb.append("0");
275 return stb.toString();
276 }
277
278 @Override
279 public void decode(int[] model, PrintWriter out) {
280 for (int i = 0; i < model.length; i++) {
281 out.print(model[i]);
282 out.print(" ");
283 }
284 out.print("0");
285 }
286
287 protected ISolver getSolver() {
288 return solver;
289 }
290 }