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.pb;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.LineNumberReader;
34 import java.io.PrintWriter;
35 import java.io.Serializable;
36 import java.math.BigInteger;
37 import java.util.HashMap;
38 import java.util.Map;
39 import java.util.Scanner;
40
41 import org.sat4j.core.Vec;
42 import org.sat4j.core.VecInt;
43 import org.sat4j.reader.ParseFormatException;
44 import org.sat4j.reader.Reader;
45 import org.sat4j.specs.ContradictionException;
46 import org.sat4j.specs.IProblem;
47 import org.sat4j.specs.IVec;
48 import org.sat4j.specs.IVecInt;
49
50
51
52
53
54
55
56
57
58 public class GoodOPBReader extends Reader implements Serializable {
59
60
61
62
63 private static final long serialVersionUID = 1L;
64
65 private static final String COMMENT_SYMBOL = "*";
66
67 private final IPBSolver solver;
68
69 private final Map<String, Integer> map = new HashMap<String, Integer>();
70
71 private final IVec<String> decode = new Vec<String>();
72
73
74
75
76 public GoodOPBReader(IPBSolver solver) {
77 this.solver = solver;
78 }
79
80 @Override
81 public final IProblem parseInstance(final java.io.Reader in)
82 throws ParseFormatException, ContradictionException, IOException {
83 return parseInstance(new LineNumberReader(in));
84 }
85
86 private IProblem parseInstance(LineNumberReader in)
87 throws ContradictionException, IOException {
88 solver.reset();
89 String line;
90 while ((line = in.readLine()) != null) {
91
92 line = line.trim();
93 if (line.endsWith(";")) {
94 line = line.substring(0, line.length() - 1);
95 }
96 parseLine(line);
97 }
98 return solver;
99 }
100
101 void parseLine(String line) throws ContradictionException {
102
103 if (line.startsWith(COMMENT_SYMBOL))
104 return;
105 if (line.startsWith("p"))
106 return;
107 if (line.startsWith("min:") || line.startsWith("min :"))
108 return;
109 if (line.startsWith("max:") || line.startsWith("max :"))
110 return;
111
112
113 int index = line.indexOf(":");
114 if (index != -1) {
115 line = line.substring(index + 1);
116 }
117
118 IVecInt lits = new VecInt();
119 IVec<BigInteger> coeffs = new Vec<BigInteger>();
120 Scanner stk = new Scanner(line)
121 .useDelimiter("\\s*\\*\\s*|\\s*\\+\\s*|\\s+");
122 while (stk.hasNext()) {
123 String token = stk.next();
124 if (">=".equals(token) || "<=".equals(token) || "=".equals(token)) {
125 assert stk.hasNext();
126 String tok = stk.next();
127
128 if (tok.startsWith("+")) {
129 tok = tok.substring(1);
130 }
131 BigInteger d = new BigInteger(tok);
132
133 try {
134 if (">=".equals(token) || "=".equals(token)) {
135 solver.addPseudoBoolean(lits, coeffs, true, d);
136 }
137 if ("<=".equals(token) || "=".equals(token)) {
138 solver.addPseudoBoolean(lits, coeffs, false, d);
139 }
140 } catch (ContradictionException ce) {
141 throw ce;
142 }
143 } else {
144
145
146 if ("+".equals(token)) {
147 assert stk.hasNext();
148 token = stk.next();
149 } else if ("-".equals(token)) {
150 assert stk.hasNext();
151 token = token + stk.next();
152 }
153 BigInteger coef;
154
155 try {
156
157 if (token.startsWith("+")) {
158 token = token.substring(1);
159 }
160 coef = new BigInteger(token);
161 assert stk.hasNext();
162 token = stk.next();
163 } catch (NumberFormatException nfe) {
164
165 coef = BigInteger.ONE;
166 }
167 if ("-".equals(token) || "~".equals(token)) {
168 assert stk.hasNext();
169 token = token + stk.next();
170 }
171 boolean negative = false;
172 if (token.startsWith("+")) {
173 token = token.substring(1);
174 } else if (token.startsWith("-")) {
175 token = token.substring(1);
176 assert coef.equals(BigInteger.ONE);
177 coef = BigInteger.ONE.negate();
178 } else if (token.startsWith("~")) {
179 token = token.substring(1);
180 negative = true;
181 }
182 Integer id = map.get(token);
183 if (id == null) {
184 id = decode.size() + 1;
185 map.put(token, id);
186 decode.push(token);
187 }
188 coeffs.push(coef);
189 int lid = (negative ? -1 : 1) * id.intValue();
190 lits.push(lid);
191 assert coeffs.size() == lits.size();
192 }
193 }
194 }
195
196 @Override
197 public String decode(int[] model) {
198 StringBuffer stb = new StringBuffer();
199 for (int i = 0; i < model.length; i++) {
200 if (model[i] < 0) {
201 stb.append("-");
202 stb.append(decode.get(-model[i] - 1));
203 } else {
204 stb.append(decode.get(model[i] - 1));
205 }
206 stb.append(" ");
207 }
208 return stb.toString();
209 }
210
211 @Override
212 public void decode(int[] model, PrintWriter out) {
213 for (int i = 0; i < model.length; i++) {
214 if (model[i] < 0) {
215 out.print("-");
216 out.print(decode.get(-model[i] - 1));
217 } else {
218 out.print(decode.get(model[i] - 1));
219 }
220 out.print(" ");
221 }
222 }
223
224 @Override
225 public IProblem parseInstance(final InputStream in)
226 throws ParseFormatException, ContradictionException, IOException {
227 return parseInstance(new InputStreamReader(in));
228 }
229 }