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