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