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.BufferedReader;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.InputStreamReader;
36 import java.io.PrintWriter;
37 import java.io.StringWriter;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40
41 import org.sat4j.core.VecInt;
42 import org.sat4j.specs.ContradictionException;
43 import org.sat4j.specs.IProblem;
44 import org.sat4j.specs.ISolver;
45 import org.sat4j.specs.IVecInt;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class JSONReader<S extends ISolver> extends Reader {
64
65 protected final S solver;
66
67 public static final String CLAUSE = "(\\[(-?(\\d+)(,-?(\\d+))*)?\\])";
68
69 public static final String CARD = "(\\[" + CLAUSE + ",'[=<>]=?',-?\\d+\\])";
70
71 public final String constraint;
72
73 public final String formula;
74
75 private static final Pattern CLAUSE_PATTERN = Pattern.compile(CLAUSE);
76
77 private static final Pattern CARD_PATTERN = Pattern.compile(CARD);
78
79 private final Pattern constraintPattern;
80
81 public JSONReader(S solver) {
82 this.solver = solver;
83 constraint = constraintRegexp();
84 formula = "^\\[(" + constraint + "(," + constraint + ")*)?\\]$";
85 constraintPattern = Pattern.compile(constraint);
86 }
87
88 protected String constraintRegexp() {
89 return "(" + CLAUSE + "|" + CARD + ")";
90 }
91
92 private void handleConstraint(String constraint)
93 throws ParseFormatException, ContradictionException {
94 if (CARD_PATTERN.matcher(constraint).matches()) {
95 handleCard(constraint);
96 } else if (CLAUSE_PATTERN.matcher(constraint).matches()) {
97 handleClause(constraint);
98 } else {
99 handleNotHandled(constraint);
100 }
101 }
102
103 protected void handleNotHandled(String constraint)
104 throws ParseFormatException, ContradictionException {
105 throw new ParseFormatException("Unknown constraint: " + constraint);
106 }
107
108 private void handleClause(String constraint) throws ParseFormatException,
109 ContradictionException {
110 solver.addClause(getLiterals(constraint));
111 }
112
113 protected IVecInt getLiterals(String constraint)
114 throws ParseFormatException {
115 String trimmed = constraint.trim();
116 trimmed = trimmed.substring(1, trimmed.length() - 1);
117 String[] literals = trimmed.split(",");
118 IVecInt clause = new VecInt();
119 for (String literal : literals) {
120 if (literal.length() > 0)
121 clause.push(Integer.valueOf(literal.trim()));
122 }
123 return clause;
124 }
125
126 protected void handleCard(String constraint) throws ParseFormatException,
127 ContradictionException {
128 String trimmed = constraint.trim();
129 trimmed = trimmed.substring(1, trimmed.length() - 1);
130 Matcher matcher = CLAUSE_PATTERN.matcher(trimmed);
131 if (matcher.find()) {
132 IVecInt clause = getLiterals(matcher.group());
133 trimmed = matcher.replaceFirst("");
134 String[] str = trimmed.split(",");
135
136 int degree = Integer.valueOf(str[2]);
137 String comparator = str[1].substring(1, str[1].length() - 1);
138 if ("=".equals(comparator) || ("==".equals(comparator))) {
139 solver.addExactly(clause, degree);
140 } else if ("<=".equals(comparator)) {
141 solver.addAtMost(clause, degree);
142 } else if ("<".equals(comparator)) {
143 solver.addAtMost(clause, degree - 1);
144 } else if (">=".equals(comparator)) {
145 solver.addAtLeast(clause, degree);
146 } else if (">".equals(comparator)) {
147 solver.addAtLeast(clause, degree + 1);
148 }
149 }
150 }
151
152 @Override
153 public IProblem parseInstance(InputStream in) throws ParseFormatException,
154 ContradictionException, IOException {
155 StringWriter out = new StringWriter();
156 BufferedReader reader = new BufferedReader(new InputStreamReader(in));
157 String line;
158 while ((line = reader.readLine()) != null) {
159 out.append(line);
160 }
161 return parseString(out.toString());
162 }
163
164 public ISolver parseString(String json) throws ParseFormatException,
165 ContradictionException {
166 String trimmed = json.trim();
167 if (!trimmed.matches(formula)) {
168 throw new ParseFormatException("Wrong input " + json);
169 }
170 Matcher matcher = constraintPattern.matcher(trimmed);
171 while (matcher.find()) {
172 handleConstraint(matcher.group());
173 }
174 return solver;
175 }
176
177 @Override
178 @Deprecated
179 public String decode(int[] model) {
180 return "[" + new VecInt(model) + "]";
181 }
182
183 @Override
184 public void decode(int[] model, PrintWriter out) {
185 out.print("[");
186 out.print(new VecInt(model));
187 out.print("]");
188 }
189
190 }