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 }