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 }