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.IOException;
33
34 import org.sat4j.specs.ContradictionException;
35 import org.sat4j.specs.ISolver;
36 import org.sat4j.tools.xplain.HighLevelXplain;
37
38 public class GroupedCNFReader extends DimacsReader {
39
40
41
42
43 private static final long serialVersionUID = 1L;
44
45 private int numberOfComponents;
46
47 private final HighLevelXplain<ISolver> hlxplain;
48
49 private int currentComponentIndex;
50
51 public GroupedCNFReader(HighLevelXplain<ISolver> solver) {
52 super(solver, "gcnf");
53 this.hlxplain = solver;
54 }
55
56
57
58
59
60
61
62
63
64
65 @Override
66 protected void readProblemLine() throws IOException, ParseFormatException {
67
68 String line = this.scanner.nextLine();
69
70 if (line == null) {
71 throw new ParseFormatException("premature end of file: <p "
72 + this.formatString + " ...> expected");
73 }
74 line = line.trim();
75 String[] tokens = line.split("\\s+");
76 if (tokens.length < 5 || !"p".equals(tokens[0])
77 || !this.formatString.equals(tokens[1])) {
78 throw new ParseFormatException("problem line expected (p "
79 + this.formatString + " ...)");
80 }
81
82 int vars;
83
84
85 vars = Integer.parseInt(tokens[2]);
86 assert vars > 0;
87 this.solver.newVar(vars);
88
89 this.expectedNbOfConstr = Integer.parseInt(tokens[3]);
90 assert this.expectedNbOfConstr > 0;
91 this.numberOfComponents = Integer.parseInt(tokens[4]);
92 this.solver.setExpectedNumberOfClauses(this.expectedNbOfConstr);
93 }
94
95
96
97
98 @Override
99 protected boolean handleLine() throws ContradictionException, IOException,
100 ParseFormatException {
101 int lit;
102 boolean added = false;
103 String component = this.scanner.next();
104 if (!component.startsWith("{") || !component.endsWith("}")) {
105 throw new ParseFormatException(
106 "Component index required at the beginning of the clause");
107 }
108 this.currentComponentIndex = Integer.valueOf(component.substring(1,
109 component.length() - 1));
110 if (this.currentComponentIndex < 0
111 || this.currentComponentIndex > this.numberOfComponents) {
112 throw new ParseFormatException("wrong component index: "
113 + this.currentComponentIndex);
114 }
115 while (!this.scanner.eof()) {
116 lit = this.scanner.nextInt();
117 if (lit == 0) {
118 if (this.literals.size() > 0) {
119 flushConstraint();
120 this.literals.clear();
121 added = true;
122 }
123 break;
124 }
125 this.literals.push(lit);
126 }
127 return added;
128 }
129
130
131
132
133
134
135 @Override
136 protected void flushConstraint() throws ContradictionException {
137 try {
138 if (this.currentComponentIndex == 0) {
139 this.hlxplain.addClause(this.literals);
140 } else {
141 this.hlxplain.addClause(this.literals,
142 this.currentComponentIndex);
143 }
144 } catch (IllegalArgumentException ex) {
145 if (isVerbose()) {
146 System.err.println("c Skipping constraint " + this.literals);
147 }
148 }
149 }
150 }