View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    * http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   * 
19   * Based on the original MiniSat specification from:
20   * 
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   * 
27   *******************************************************************************/
28  package org.sat4j.core;
29  
30  import java.util.NoSuchElementException;
31  
32  import org.sat4j.specs.IVecInt;
33  import org.sat4j.specs.IteratorInt;
34  
35  /*
36   * Created on 9 oct. 2003
37   */
38  
39  /**
40   * A vector specific for primitive integers, widely used in the solver. Note
41   * that if the vector has a sort method, the operations on the vector DO NOT
42   * preserve sorting.
43   * 
44   * @author leberre
45   */
46  public class VecInt implements IVecInt {
47  	// MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
48  	//
49  	// Permission is hereby granted, free of charge, to any person obtaining a
50  	// copy of this software and associated documentation files (the
51  	// "Software"), to deal in the Software without restriction, including
52  	// without limitation the rights to use, copy, modify, merge, publish,
53  	// distribute, sublicense, and/or sell copies of the Software, and to
54  	// permit persons to whom the Software is furnished to do so, subject to
55  	// the following conditions:
56  	//
57  	// The above copyright notice and this permission notice shall be included
58  	// in all copies or substantial portions of the Software.
59  	//
60  	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
61  	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
62  	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
63  	// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
64  	// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
65  	// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
66  	// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
67  
68  	private static final long serialVersionUID = 1L;
69  
70  	public static final IVecInt EMPTY = new VecInt() {
71  
72  		/**
73           * 
74           */
75  		private static final long serialVersionUID = 1L;
76  
77  		@Override
78  		public int size() {
79  			return 0;
80  		}
81  
82  		@Override
83  		public void shrink(int nofelems) {
84  		}
85  
86  		@Override
87  		public void shrinkTo(int newsize) {
88  		}
89  
90  		@Override
91  		public IVecInt pop() {
92  			throw new UnsupportedOperationException();
93  		}
94  
95  		@Override
96  		public void growTo(int newsize, int pad) {
97  		}
98  
99  		@Override
100 		public void ensure(int nsize) {
101 		}
102 
103 		@Override
104 		public IVecInt push(int elem) {
105 			throw new UnsupportedOperationException();
106 		}
107 
108 		@Override
109 		public void unsafePush(int elem) {
110 			throw new UnsupportedOperationException();
111 		}
112 
113 		@Override
114 		public void clear() {
115 		}
116 
117 		@Override
118 		public int last() {
119 			throw new UnsupportedOperationException();
120 		}
121 
122 		@Override
123 		public int get(int i) {
124 			throw new UnsupportedOperationException();
125 		}
126 
127 		@Override
128 		public void set(int i, int o) {
129 			throw new UnsupportedOperationException();
130 		}
131 
132 		@Override
133 		public boolean contains(int e) {
134 			return false;
135 		}
136 
137 		@Override
138 		public void copyTo(IVecInt copy) {
139 		}
140 
141 		@Override
142 		public void copyTo(int[] is) {
143 		}
144 
145 		@Override
146 		public void moveTo(IVecInt dest) {
147 		}
148 
149 		@Override
150 		public void moveTo2(IVecInt dest) {
151 		}
152 
153 		@Override
154 		public void moveTo(int[] dest) {
155 		}
156 
157 		@Override
158 		public void insertFirst(int elem) {
159 			throw new UnsupportedOperationException();
160 		}
161 
162 		@Override
163 		public void remove(int elem) {
164 			throw new UnsupportedOperationException();
165 		}
166 
167 		@Override
168 		public int delete(int i) {
169 			throw new UnsupportedOperationException();
170 		}
171 
172 		@Override
173 		public void sort() {
174 		}
175 
176 		@Override
177 		public void sortUnique() {
178 		}
179 	};
180 
181 	public VecInt() {
182 		this(5);
183 	}
184 
185 	public VecInt(int size) {
186 		myarray = new int[size];
187 	}
188 
189 	/**
190 	 * Adapter method to translate an array of int into an IVecInt.
191 	 * 
192 	 * The array is used inside the VecInt, so the elements may be modified
193 	 * outside the VecInt. But it should not take much memory.The size of the
194 	 * created VecInt is the length of the array.
195 	 * 
196 	 * @param lits
197 	 *            a filled array of int.
198 	 */
199 	public VecInt(int[] lits) {
200 		myarray = lits;
201 		nbelem = lits.length;
202 	}
203 
204 	/**
205 	 * Build a vector of a given initial size filled with an integer.
206 	 * 
207 	 * @param size
208 	 *            the initial size of the vector
209 	 * @param pad
210 	 *            the integer to fill the vector with
211 	 */
212 	public VecInt(int size, int pad) {
213 		myarray = new int[size];
214 		for (int i = 0; i < size; i++) {
215 			myarray[i] = pad;
216 		}
217 		nbelem = size;
218 	}
219 
220 	public int size() {
221 		return nbelem;
222 	}
223 
224 	/**
225 	 * Remove the latest nofelems elements from the vector
226 	 * 
227 	 * @param nofelems
228 	 */
229 	public void shrink(int nofelems) {
230 		// assert nofelems >= 0;
231 		// assert nofelems <= size();
232 		nbelem -= nofelems;
233 	}
234 
235 	public void shrinkTo(int newsize) {
236 		// assert newsize >= 0;
237 		// assert newsize < nbelem;
238 		nbelem = newsize;
239 	}
240 
241 	/**
242 	 * depile le dernier element du vecteur. Si le vecteur est vide, ne fait
243 	 * rien.
244 	 */
245 	public IVecInt pop() {
246 		// assert size() != 0;
247 		--nbelem;
248 		return this;
249 	}
250 
251 	public void growTo(int newsize, final int pad) {
252 		// assert newsize > size();
253 		ensure(newsize);
254 		while (--newsize >= 0) {
255 			myarray[nbelem++] = pad;
256 		}
257 	}
258 
259 	public void ensure(int nsize) {
260 		if (nsize >= myarray.length) {
261 			int[] narray = new int[Math.max(nsize, nbelem * 2)];
262 			System.arraycopy(myarray, 0, narray, 0, nbelem);
263 			myarray = narray;
264 		}
265 	}
266 
267 	public IVecInt push(int elem) {
268 		ensure(nbelem + 1);
269 		myarray[nbelem++] = elem;
270 		return this;
271 	}
272 
273 	public void unsafePush(int elem) {
274 		myarray[nbelem++] = elem;
275 	}
276 
277 	public void clear() {
278 		nbelem = 0;
279 	}
280 
281 	public int last() {
282 		// assert nbelem > 0;
283 		return myarray[nbelem - 1];
284 	}
285 
286 	public int get(int i) {
287 		// assert i >= 0 && i < nbelem;
288 		return myarray[i];
289 	}
290 
291 	public int unsafeGet(int i) {
292 		return myarray[i];
293 	}
294 
295 	public void set(int i, int o) {
296 		assert i >= 0 && i < nbelem;
297 		myarray[i] = o;
298 	}
299 
300 	public boolean contains(int e) {
301 		final int[] workArray = myarray; // dvh, faster access
302 		for (int i = 0; i < nbelem; i++) {
303 			if (workArray[i] == e)
304 				return true;
305 		}
306 		return false;
307 	}
308 
309 	public int containsAt(int e) {
310 		return containsAt(e, -1);
311 	}
312 
313 	public int containsAt(int e, int from) {
314 		final int[] workArray = myarray; // dvh, faster access
315 		for (int i = from + 1; i < nbelem; i++) {
316 			if (workArray[i] == e)
317 				return i;
318 		}
319 		return -1;
320 	}
321 
322 	/**
323 	 * Copy the content of this vector into another one. Non constant time
324 	 * operation.
325 	 * 
326 	 * @param copy
327 	 */
328 	public void copyTo(IVecInt copy) {
329 		VecInt ncopy = (VecInt) copy;
330 		int nsize = nbelem + ncopy.nbelem;
331 		ncopy.ensure(nsize);
332 		System.arraycopy(myarray, 0, ncopy.myarray, ncopy.nbelem, nbelem);
333 		ncopy.nbelem = nsize;
334 	}
335 
336 	/**
337 	 * Copy the content of this vector into an array of integer. Non constant
338 	 * time operation.
339 	 * 
340 	 * @param is
341 	 */
342 	public void copyTo(int[] is) {
343 		// assert is.length >= nbelem;
344 		System.arraycopy(myarray, 0, is, 0, nbelem);
345 	}
346 
347 	public void moveTo(IVecInt dest) {
348 		copyTo(dest);
349 		nbelem = 0;
350 	}
351 
352 	public void moveTo2(IVecInt dest) {
353 		VecInt ndest = (VecInt) dest;
354 		int s = ndest.nbelem;
355 		int tmp[] = ndest.myarray;
356 		ndest.myarray = myarray;
357 		ndest.nbelem = nbelem;
358 		myarray = tmp;
359 		nbelem = s;
360 		nbelem = 0;
361 	}
362 
363 	public void moveTo(int dest, int source) {
364 		myarray[dest] = myarray[source];
365 	}
366 
367 	public void moveTo(int[] dest) {
368 		System.arraycopy(myarray, 0, dest, 0, nbelem);
369 		nbelem = 0;
370 	}
371 
372 	/**
373 	 * Insert an element at the very begining of the vector. The former first
374 	 * element is appended to the end of the vector in order to have a constant
375 	 * time operation.
376 	 * 
377 	 * @param elem
378 	 *            the element to put first in the vector.
379 	 */
380 	public void insertFirst(final int elem) {
381 		if (nbelem > 0) {
382 			push(myarray[0]);
383 			myarray[0] = elem;
384 			return;
385 		}
386 		push(elem);
387 	}
388 
389 	/**
390 	 * Enleve un element qui se trouve dans le vecteur!!!
391 	 * 
392 	 * @param elem
393 	 *            un element du vecteur
394 	 */
395 	public void remove(int elem) {
396 		// assert size() > 0;
397 		int j = 0;
398 		for (; myarray[j] != elem; j++) {
399 			assert j < size();
400 		}
401 		System.arraycopy(myarray, j + 1, myarray, j, size() - j);
402 		pop();
403 	}
404 
405 	/**
406 	 * Delete the ith element of the vector. The latest element of the vector
407 	 * replaces the removed element at the ith indexer.
408 	 * 
409 	 * @param i
410 	 *            the indexer of the element in the vector
411 	 * @return the former ith element of the vector that is now removed from the
412 	 *         vector
413 	 */
414 	public int delete(int i) {
415 		// assert i >= 0 && i < nbelem;
416 		int ith = myarray[i];
417 		myarray[i] = myarray[--nbelem];
418 		return ith;
419 	}
420 
421 	private int nbelem;
422 
423 	private int[] myarray;
424 
425 	/*
426 	 * (non-Javadoc)
427 	 * 
428 	 * @see java.lang.int#toString()
429 	 */
430 	@Override
431 	public String toString() {
432 		StringBuffer stb = new StringBuffer();
433 		for (int i = 0; i < nbelem - 1; i++) {
434 			stb.append(myarray[i]);
435 			stb.append(","); //$NON-NLS-1$
436 		}
437 		if (nbelem > 0) {
438 			stb.append(myarray[nbelem - 1]);
439 		}
440 		return stb.toString();
441 	}
442 
443 	void selectionSort(int from, int to) {
444 		int i, j, best_i;
445 		int tmp;
446 
447 		for (i = from; i < to - 1; i++) {
448 			best_i = i;
449 			for (j = i + 1; j < to; j++) {
450 				if (myarray[j] < myarray[best_i])
451 					best_i = j;
452 			}
453 			tmp = myarray[i];
454 			myarray[i] = myarray[best_i];
455 			myarray[best_i] = tmp;
456 		}
457 	}
458 
459 	void sort(int from, int to) {
460 		int width = to - from;
461 		if (width <= 15)
462 			selectionSort(from, to);
463 
464 		else {
465 			final int[] locarray = myarray;
466 			int pivot = locarray[width / 2 + from];
467 			int tmp;
468 			int i = from - 1;
469 			int j = to;
470 
471 			for (;;) {
472 				do
473 					i++;
474 				while (locarray[i] < pivot);
475 				do
476 					j--;
477 				while (pivot < locarray[j]);
478 
479 				if (i >= j)
480 					break;
481 
482 				tmp = locarray[i];
483 				locarray[i] = locarray[j];
484 				locarray[j] = tmp;
485 			}
486 
487 			sort(from, i);
488 			sort(i, to);
489 		}
490 	}
491 
492 	/**
493 	 * sort the vector using a custom quicksort.
494 	 */
495 	public void sort() {
496 		sort(0, nbelem);
497 	}
498 
499 	public void sortUnique() {
500 		int i, j;
501 		int last;
502 		if (nbelem == 0)
503 			return;
504 
505 		sort(0, nbelem);
506 		i = 1;
507 		int[] locarray = myarray;
508 		last = locarray[0];
509 		for (j = 1; j < nbelem; j++) {
510 			if (last < locarray[j]) {
511 				last = locarray[i] = locarray[j];
512 				i++;
513 			}
514 		}
515 
516 		nbelem = i;
517 	}
518 
519 	/**
520 	 * Two vectors are equals iff they have the very same elements in the order.
521 	 * 
522 	 * @param obj
523 	 *            an object
524 	 * @return true iff obj is a VecInt and has the same elements as this vector
525 	 *         at each index.
526 	 * 
527 	 * @see java.lang.Object#equals(java.lang.Object)
528 	 */
529 	@Override
530 	public boolean equals(Object obj) {
531 		if (obj instanceof VecInt) {
532 			VecInt v = (VecInt) obj;
533 			if (v.nbelem != nbelem)
534 				return false;
535 			for (int i = 0; i < nbelem; i++) {
536 				if (v.myarray[i] != myarray[i]) {
537 					return false;
538 				}
539 			}
540 			return true;
541 		}
542 		return false;
543 	}
544 
545 	/*
546 	 * (non-Javadoc)
547 	 * 
548 	 * @see java.lang.Object#hashCode()
549 	 */
550 	@Override
551 	public int hashCode() {
552 		long sum = 0;
553 		for (int i = 0; i < nbelem; i++) {
554 			sum += myarray[i];
555 		}
556 		return (int) sum / nbelem;
557 	}
558 
559 	/*
560 	 * (non-Javadoc)
561 	 * 
562 	 * @see org.sat4j.specs.IVecInt2#pushAll(org.sat4j.specs.IVecInt2)
563 	 */
564 	public void pushAll(IVecInt vec) {
565 		VecInt nvec = (VecInt) vec;
566 		int nsize = nbelem + nvec.nbelem;
567 		ensure(nsize);
568 		System.arraycopy(nvec.myarray, 0, myarray, nbelem, nvec.nbelem);
569 		nbelem = nsize;
570 	}
571 
572 	/**
573 	 * to detect that the vector is a subset of another one. Note that the
574 	 * method assumes that the two vectors are sorted!
575 	 * 
576 	 * @param vec
577 	 *            a vector
578 	 * @return true iff the current vector is a subset of vec
579 	 */
580 	public boolean isSubsetOf(VecInt vec) {
581 		int i = 0;
582 		int j = 0;
583 		while ((i < this.nbelem) && (j < vec.nbelem)) {
584 			while ((j < vec.nbelem) && (vec.myarray[j] < this.myarray[i])) {
585 				j++;
586 			}
587 			if (j == vec.nbelem || this.myarray[i] != vec.myarray[j])
588 				return false;
589 			i++;
590 		}
591 		return true;
592 	}
593 
594 	public IteratorInt iterator() {
595 		return new IteratorInt() {
596 			private int i = 0;
597 
598 			public boolean hasNext() {
599 				return i < nbelem;
600 			}
601 
602 			public int next() {
603 				if (i == nbelem)
604 					throw new NoSuchElementException();
605 				return myarray[i++];
606 			}
607 		};
608 	}
609 
610 	public boolean isEmpty() {
611 		return nbelem == 0;
612 	}
613 
614 	/**
615 	 * @since 2.1
616 	 */
617 	public int[] toArray() {
618 		return myarray;
619 	}
620 }