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.BufferedInputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.PrintWriter;
36 import java.io.Serializable;
37
38 import org.sat4j.core.VecInt;
39 import org.sat4j.specs.ContradictionException;
40 import org.sat4j.specs.IProblem;
41 import org.sat4j.specs.ISolver;
42 import org.sat4j.specs.IVecInt;
43
44
45
46
47
48
49
50
51
52
53
54
55 public class LecteurDimacs extends Reader implements Serializable {
56
57 private static final long serialVersionUID = 1L;
58
59
60 private static final int TAILLE_BUF = 16384;
61
62 private final ISolver s;
63
64 private transient BufferedInputStream in;
65
66
67 private int nbVars = -1;
68
69 private int nbClauses = -1;
70
71 private static final char EOF = (char) -1;
72
73
74
75
76 public LecteurDimacs(ISolver s) {
77 this.s = s;
78 }
79
80 @Override
81 public final IProblem parseInstance(final InputStream input)
82 throws ParseFormatException, ContradictionException, IOException {
83
84 this.in = new BufferedInputStream(input, LecteurDimacs.TAILLE_BUF);
85 this.s.reset();
86 passerCommentaire();
87 if (this.nbVars < 0) {
88 throw new ParseFormatException(
89 "DIMACS error: wrong max number of variables");
90 }
91 this.s.newVar(this.nbVars);
92 this.s.setExpectedNumberOfClauses(this.nbClauses);
93 char car = passerEspaces();
94 if (this.nbClauses > 0) {
95 if (car == EOF) {
96 throw new ParseFormatException(
97 "DIMACS error: the clauses are missing");
98 }
99 ajouterClauses(car);
100 }
101 input.close();
102 return this.s;
103 }
104
105
106 private char passerCommentaire() throws IOException {
107 char car;
108 for (;;) {
109 car = passerEspaces();
110 if (car == 'p') {
111 car = lectureNombreLiteraux();
112 }
113 if (car != 'c' && car != 'p') {
114 break;
115 }
116 car = nextLine();
117 if (car == EOF) {
118 break;
119 }
120 }
121 return car;
122 }
123
124
125 private char lectureNombreLiteraux() throws IOException {
126 char car = nextChiffre();
127 if (car != EOF) {
128 this.nbVars = car - '0';
129 for (;;) {
130 car = (char) this.in.read();
131 if (car < '0' || car > '9') {
132 break;
133 }
134 this.nbVars = 10 * this.nbVars + car - '0';
135 }
136 car = nextChiffre();
137 this.nbClauses = car - '0';
138 for (;;) {
139 car = (char) this.in.read();
140 if (car < '0' || car > '9') {
141 break;
142 }
143 this.nbClauses = 10 * this.nbClauses + car - '0';
144 }
145 if (car != '\n' && car != EOF) {
146 nextLine();
147 }
148 }
149 return car;
150 }
151
152
153
154
155
156
157 private void ajouterClauses(char car) throws IOException,
158 ContradictionException, ParseFormatException {
159 final IVecInt lit = new VecInt();
160 int val = 0;
161 boolean neg = false;
162 for (;;) {
163
164 if (car == '-') {
165 neg = true;
166 car = (char) this.in.read();
167 } else if (car == '+') {
168 car = (char) this.in.read();
169 } else
170 if (car >= '0' && car <= '9') {
171 val = car - '0';
172 car = (char) this.in.read();
173 } else {
174 throw new ParseFormatException("Unknown character " + car);
175 }
176
177 while (car >= '0' && car <= '9') {
178 val = val * 10 + car - '0';
179 car = (char) this.in.read();
180 }
181 if (val == 0) {
182 this.s.addClause(lit);
183 lit.clear();
184 } else {
185
186
187 lit.push(neg ? -val : val);
188 neg = false;
189 val = 0;
190 }
191 if (car != EOF) {
192 car = passerEspaces();
193 }
194 if (car == EOF) {
195 if (!lit.isEmpty()) {
196 this.s.addClause(lit);
197 }
198 break;
199 }
200 }
201 }
202
203
204 private char passerEspaces() throws IOException {
205 char car;
206
207 do {
208 car = (char) this.in.read();
209 } while (car == ' ' || car == '\n');
210
211 return car;
212 }
213
214
215 private char nextLine() throws IOException {
216 char car;
217 do {
218 car = (char) this.in.read();
219 } while (car != '\n' && car != EOF);
220 return car;
221 }
222
223
224 private char nextChiffre() throws IOException {
225 char car;
226 do {
227 car = (char) this.in.read();
228 } while (car < '0' || car > '9' && car != EOF);
229 return car;
230 }
231
232 @Override
233 public String decode(int[] model) {
234 StringBuffer stb = new StringBuffer();
235 for (int element : model) {
236 stb.append(element);
237 stb.append(" ");
238 }
239 stb.append("0");
240 return stb.toString();
241 }
242
243 @Override
244 public void decode(int[] model, PrintWriter out) {
245 for (int element : model) {
246 out.print(element);
247 out.print(" ");
248 }
249 out.print("0");
250 }
251 }