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 }