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