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.minisat.constraints.cnf;
29
30 import static org.sat4j.core.LiteralsUtils.neg;
31
32 import java.io.Serializable;
33
34 import org.sat4j.minisat.core.Constr;
35 import org.sat4j.minisat.core.ILits;
36 import org.sat4j.minisat.core.UnitPropagationListener;
37 import org.sat4j.specs.IVecInt;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public abstract class HTClause implements Constr, Serializable {
53
54 private static final long serialVersionUID = 1L;
55
56 private double activity;
57
58 protected final int[] middleLits;
59
60 protected final ILits voc;
61
62 protected int head;
63
64 protected int tail;
65
66
67
68
69
70
71
72
73
74 public HTClause(IVecInt ps, ILits voc) {
75 assert ps.size() > 1;
76 head = ps.get(0);
77 tail = ps.last();
78 final int size = ps.size()-2;
79 assert size>0;
80 middleLits = new int[size];
81 System.arraycopy(ps.toArray(), 1, middleLits, 0, size);
82 ps.clear();
83 assert ps.size() == 0;
84 this.voc = voc;
85 activity = 0;
86 }
87
88
89
90
91
92
93 public void calcReason(int p, IVecInt outReason) {
94 if (voc.isFalsified(head)) {
95 outReason.push(neg(head));
96 }
97 final int[] mylits = middleLits;
98 for (int i = 0; i < mylits.length; i++) {
99 if (voc.isFalsified(mylits[i])) {
100 outReason.push(neg(mylits[i]));
101 }
102 }
103 if (voc.isFalsified(tail)) {
104 outReason.push(neg(tail));
105 }
106 }
107
108
109
110
111
112
113 public void remove() {
114 voc.attaches(neg(head)).remove(this);
115 voc.attaches(neg(tail)).remove(this);
116 }
117
118
119
120
121
122
123 public boolean simplify() {
124 if (voc.isSatisfied(head)||voc.isSatisfied(tail)) {
125 return true;
126 }
127 for (int i = 0; i < middleLits.length; i++) {
128 if (voc.isSatisfied(middleLits[i])) {
129 return true;
130 }
131 }
132 return false;
133 }
134
135 public boolean propagate(UnitPropagationListener s, int p) {
136
137 if (head == neg(p)) {
138 final int[] mylits = middleLits;
139 int temphead = 0;
140
141 while (temphead < mylits.length && voc.isFalsified(mylits[temphead])) {
142 temphead++;
143 }
144 assert temphead <= mylits.length;
145 if (temphead == mylits.length) {
146 voc.attach(p, this);
147 return s.enqueue(tail, this);
148 }
149 head = mylits[temphead];
150 mylits[temphead] = neg(p);
151 voc.attach(neg(head), this);
152 return true;
153 }
154 assert tail == neg(p);
155 final int[] mylits = middleLits;
156 int temptail = mylits.length - 1;
157
158 while (temptail>=0 && voc.isFalsified(mylits[temptail])) {
159 temptail--;
160 }
161 assert -1 <= temptail;
162 if (-1 == temptail) {
163 voc.attach(p, this);
164 return s.enqueue(head, this);
165 }
166 tail = mylits[temptail];
167 mylits[temptail] = neg(p);
168 voc.attach(neg(tail), this);
169 return true;
170 }
171
172
173
174
175 public boolean locked() {
176 return voc.getReason(head) == this
177 || voc.getReason(tail) == this;
178 }
179
180
181
182
183 public double getActivity() {
184 return activity;
185 }
186
187 @Override
188 public String toString() {
189 StringBuffer stb = new StringBuffer();
190 stb.append(Lits.toString(head));
191 stb.append("[");
192 stb.append(voc.valueToString(head));
193 stb.append("]");
194 stb.append(" ");
195 for (int i = 0; i < middleLits.length; i++) {
196 stb.append(Lits.toString(middleLits[i]));
197 stb.append("[");
198 stb.append(voc.valueToString(middleLits[i]));
199 stb.append("]");
200 stb.append(" ");
201 }
202 stb.append(Lits.toString(tail));
203 stb.append("[");
204 stb.append(voc.valueToString(tail));
205 stb.append("]");
206 return stb.toString();
207 }
208
209
210
211
212
213
214
215
216
217 public int get(int i) {
218 if (i==0) return head;
219 if (i==middleLits.length+1) return tail;
220 return middleLits[i-1];
221 }
222
223
224
225
226 public void incActivity(double claInc) {
227 activity += claInc;
228 }
229
230
231
232
233 public void rescaleBy(double d) {
234 activity *= d;
235 }
236
237 public int size() {
238 return middleLits.length+2;
239 }
240
241 public void assertConstraint(UnitPropagationListener s) {
242 boolean ret;
243 if (voc.isUnassigned(head)) {
244 ret = s.enqueue(head, this);
245 } else {
246 assert voc.isUnassigned(tail);
247 ret = s.enqueue(tail, this);
248 }
249 assert ret;
250 }
251
252 public ILits getVocabulary() {
253 return voc;
254 }
255
256 public int[] getLits() {
257 int[] tmp = new int[size()];
258 System.arraycopy(middleLits, 0, tmp, 1, middleLits.length);
259 tmp[0]=head;
260 tmp[tmp.length-1] = tail;
261 return tmp;
262 }
263
264 @Override
265 public boolean equals(Object obj) {
266 if (obj == null)
267 return false;
268 try {
269 HTClause wcl = (HTClause) obj;
270 if (wcl.head!= head || wcl.tail!=tail) {
271 return false;
272 }
273 if (middleLits.length != wcl.middleLits.length)
274 return false;
275 boolean ok;
276 for (int lit : middleLits) {
277 ok = false;
278 for (int lit2 : wcl.middleLits)
279 if (lit == lit2) {
280 ok = true;
281 break;
282 }
283 if (!ok)
284 return false;
285 }
286 return true;
287 } catch (ClassCastException e) {
288 return false;
289 }
290 }
291
292 @Override
293 public int hashCode() {
294 long sum = head+tail;;
295 for (int p : middleLits) {
296 sum += p;
297 }
298 return (int) sum / middleLits.length;
299 }
300 }