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 final 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 IVecInt() {
71  
72  		/**
73           * 
74           */
75  		private static final long serialVersionUID = 1L;
76  
77  		public int size() {
78  			return 0;
79  		}
80  
81  		public void shrink(int nofelems) {
82  		}
83  
84  		public void shrinkTo(int newsize) {
85  		}
86  
87  		public IVecInt pop() {
88  			throw new UnsupportedOperationException();
89  		}
90  
91  		public void growTo(int newsize, int pad) {
92  		}
93  
94  		public void ensure(int nsize) {
95  		}
96  
97  		public IVecInt push(int elem) {
98  			throw new UnsupportedOperationException();
99  		}
100 
101 		public void unsafePush(int elem) {
102 			throw new UnsupportedOperationException();
103 		}
104 
105 		public void clear() {
106 		}
107 
108 		public int last() {
109 			throw new UnsupportedOperationException();
110 		}
111 
112 		public int get(int i) {
113 			throw new UnsupportedOperationException();
114 		}
115 
116 		public void set(int i, int o) {
117 			throw new UnsupportedOperationException();
118 		}
119 
120 		public boolean contains(int e) {
121 			return false;
122 		}
123 
124 		public void copyTo(IVecInt copy) {
125 		}
126 
127 		public void copyTo(int[] is) {
128 		}
129 
130 		public void moveTo(IVecInt dest) {
131 		}
132 
133 		public void moveTo2(IVecInt dest) {
134 		}
135 
136 		public void moveTo(int[] dest) {
137 		}
138 
139 		public void insertFirst(int elem) {
140 			throw new UnsupportedOperationException();
141 		}
142 
143 		public void remove(int elem) {
144 			throw new UnsupportedOperationException();
145 		}
146 
147 		public int delete(int i) {
148 			throw new UnsupportedOperationException();
149 		}
150 
151 		public void sort() {
152 		}
153 
154 		public void sortUnique() {
155 		}
156 
157 		public int unsafeGet(int eleem) {
158 			throw new UnsupportedOperationException();
159 		}
160 
161 		public int containsAt(int e) {
162 			throw new UnsupportedOperationException();
163 		}
164 
165 		public int containsAt(int e, int from) {
166 			throw new UnsupportedOperationException();
167 		}
168 
169 		public void moveTo(int dest, int source) {
170 			throw new UnsupportedOperationException();
171 		}
172 
173 		public boolean isEmpty() {
174 			return true;
175 		}
176 
177 		public IteratorInt iterator() {
178 			return new IteratorInt() {
179 
180 				public boolean hasNext() {
181 					return false;
182 				}
183 
184 				public int next() {
185 					throw new UnsupportedOperationException();
186 				}
187 			};
188 		}
189 
190 		public int[] toArray() {
191 			throw new UnsupportedOperationException();
192 		}
193 
194 		public int indexOf(int e) {
195 			return -1;
196 		}
197 
198 		@Override
199 		public String toString() {
200 			return "[]";
201 		}
202 
203 	};
204 
205 	public VecInt() {
206 		this(5);
207 	}
208 
209 	public VecInt(int size) {
210 		myarray = new int[size];
211 	}
212 
213 	/**
214 	 * Adapter method to translate an array of int into an IVecInt.
215 	 * 
216 	 * The array is used inside the VecInt, so the elements may be modified
217 	 * outside the VecInt. But it should not take much memory.The size of the
218 	 * created VecInt is the length of the array.
219 	 * 
220 	 * @param lits
221 	 *            a filled array of int.
222 	 */
223 	public VecInt(int[] lits) { // NOPMD
224 		myarray = lits;
225 		nbelem = lits.length;
226 	}
227 
228 	/**
229 	 * Build a vector of a given initial size filled with an integer.
230 	 * 
231 	 * @param size
232 	 *            the initial size of the vector
233 	 * @param pad
234 	 *            the integer to fill the vector with
235 	 */
236 	public VecInt(int size, int pad) {
237 		myarray = new int[size];
238 		for (int i = 0; i < size; i++) {
239 			myarray[i] = pad;
240 		}
241 		nbelem = size;
242 	}
243 
244 	public int size() {
245 		return nbelem;
246 	}
247 
248 	/**
249 	 * Remove the latest nofelems elements from the vector
250 	 * 
251 	 * @param nofelems
252 	 */
253 	public void shrink(int nofelems) {
254 		// assert nofelems >= 0;
255 		// assert nofelems <= size();
256 		nbelem -= nofelems;
257 	}
258 
259 	public void shrinkTo(int newsize) {
260 		// assert newsize >= 0;
261 		// assert newsize < nbelem;
262 		nbelem = newsize;
263 	}
264 
265 	/**
266 	 * depile le dernier element du vecteur. Si le vecteur est vide, ne fait
267 	 * rien.
268 	 */
269 	public IVecInt pop() {
270 		// assert size() != 0;
271 		--nbelem;
272 		return this;
273 	}
274 
275 	public void growTo(int newsize, final int pad) {
276 		// assert newsize > size();
277 		ensure(newsize);
278 		while (--newsize >= 0) {
279 			myarray[nbelem++] = pad;
280 		}
281 	}
282 
283 	public void ensure(int nsize) {
284 		if (nsize >= myarray.length) {
285 			int[] narray = new int[Math.max(nsize, nbelem * 2)];
286 			System.arraycopy(myarray, 0, narray, 0, nbelem);
287 			myarray = narray;
288 		}
289 	}
290 
291 	public IVecInt push(int elem) {
292 		ensure(nbelem + 1);
293 		myarray[nbelem++] = elem;
294 		return this;
295 	}
296 
297 	public void unsafePush(int elem) {
298 		myarray[nbelem++] = elem;
299 	}
300 
301 	public void clear() {
302 		nbelem = 0;
303 	}
304 
305 	public int last() {
306 		// assert nbelem > 0;
307 		return myarray[nbelem - 1];
308 	}
309 
310 	public int get(int i) {
311 		// assert i >= 0 && i < nbelem;
312 		return myarray[i];
313 	}
314 
315 	public int unsafeGet(int i) {
316 		return myarray[i];
317 	}
318 
319 	public void set(int i, int o) {
320 		assert i >= 0 && i < nbelem;
321 		myarray[i] = o;
322 	}
323 
324 	public boolean contains(int e) {
325 		final int[] workArray = myarray; // dvh, faster access
326 		for (int i = 0; i < nbelem; i++) {
327 			if (workArray[i] == e)
328 				return true;
329 		}
330 		return false;
331 	}
332 
333 	/**
334 	 * @since 2.2
335 	 */
336 	public int indexOf(int e) {
337 		final int[] workArray = myarray; // dvh, faster access
338 		for (int i = 0; i < nbelem; i++) {
339 			if (workArray[i] == e)
340 				return i;
341 		}
342 		return -1;
343 	}
344 
345 	public int containsAt(int e) {
346 		return containsAt(e, -1);
347 	}
348 
349 	public int containsAt(int e, int from) {
350 		final int[] workArray = myarray; // dvh, faster access
351 		for (int i = from + 1; i < nbelem; i++) {
352 			if (workArray[i] == e)
353 				return i;
354 		}
355 		return -1;
356 	}
357 
358 	/**
359 	 * Copy the content of this vector into another one. Non constant time
360 	 * operation.
361 	 * 
362 	 * @param copy
363 	 */
364 	public void copyTo(IVecInt copy) {
365 		VecInt ncopy = (VecInt) copy;
366 		int nsize = nbelem + ncopy.nbelem;
367 		ncopy.ensure(nsize);
368 		System.arraycopy(myarray, 0, ncopy.myarray, ncopy.nbelem, nbelem);
369 		ncopy.nbelem = nsize;
370 	}
371 
372 	/**
373 	 * Copy the content of this vector into an array of integer. Non constant
374 	 * time operation.
375 	 * 
376 	 * @param is
377 	 */
378 	public void copyTo(int[] is) {
379 		// assert is.length >= nbelem;
380 		System.arraycopy(myarray, 0, is, 0, nbelem);
381 	}
382 
383 	public void moveTo(IVecInt dest) {
384 		copyTo(dest);
385 		nbelem = 0;
386 	}
387 
388 	public void moveTo2(IVecInt dest) {
389 		VecInt ndest = (VecInt) dest;
390 		int s = ndest.nbelem;
391 		int tmp[] = ndest.myarray;
392 		ndest.myarray = myarray;
393 		ndest.nbelem = nbelem;
394 		myarray = tmp;
395 		nbelem = s;
396 		nbelem = 0;
397 	}
398 
399 	public void moveTo(int dest, int source) {
400 		myarray[dest] = myarray[source];
401 	}
402 
403 	public void moveTo(int[] dest) {
404 		System.arraycopy(myarray, 0, dest, 0, nbelem);
405 		nbelem = 0;
406 	}
407 
408 	/**
409 	 * Insert an element at the very begining of the vector. The former first
410 	 * element is appended to the end of the vector in order to have a constant
411 	 * time operation.
412 	 * 
413 	 * @param elem
414 	 *            the element to put first in the vector.
415 	 */
416 	public void insertFirst(final int elem) {
417 		if (nbelem > 0) {
418 			push(myarray[0]);
419 			myarray[0] = elem;
420 			return;
421 		}
422 		push(elem);
423 	}
424 
425 	/**
426 	 * Enleve un element qui se trouve dans le vecteur!!!
427 	 * 
428 	 * @param elem
429 	 *            un element du vecteur
430 	 */
431 	public void remove(int elem) {
432 		// assert size() > 0;
433 		int j = 0;
434 		for (; myarray[j] != elem; j++) {
435 			assert j < size();
436 		}
437 		System.arraycopy(myarray, j + 1, myarray, j, size() - j);
438 		pop();
439 	}
440 
441 	/**
442 	 * Delete the ith element of the vector. The latest element of the vector
443 	 * replaces the removed element at the ith indexer.
444 	 * 
445 	 * @param i
446 	 *            the indexer of the element in the vector
447 	 * @return the former ith element of the vector that is now removed from the
448 	 *         vector
449 	 */
450 	public int delete(int i) {
451 		// assert i >= 0 && i < nbelem;
452 		int ith = myarray[i];
453 		myarray[i] = myarray[--nbelem];
454 		return ith;
455 	}
456 
457 	private int nbelem;
458 
459 	private int[] myarray;
460 
461 	/*
462 	 * (non-Javadoc)
463 	 * 
464 	 * @see java.lang.int#toString()
465 	 */
466 	@Override
467 	public String toString() {
468 		StringBuffer stb = new StringBuffer();
469 		for (int i = 0; i < nbelem - 1; i++) {
470 			stb.append(myarray[i]);
471 			stb.append(","); //$NON-NLS-1$
472 		}
473 		if (nbelem > 0) {
474 			stb.append(myarray[nbelem - 1]);
475 		}
476 		return stb.toString();
477 	}
478 
479 	void selectionSort(int from, int to) {
480 		int i, j, best_i;
481 		int tmp;
482 
483 		for (i = from; i < to - 1; i++) {
484 			best_i = i;
485 			for (j = i + 1; j < to; j++) {
486 				if (myarray[j] < myarray[best_i])
487 					best_i = j;
488 			}
489 			tmp = myarray[i];
490 			myarray[i] = myarray[best_i];
491 			myarray[best_i] = tmp;
492 		}
493 	}
494 
495 	void sort(int from, int to) {
496 		int width = to - from;
497 		if (width <= 15)
498 			selectionSort(from, to);
499 
500 		else {
501 			final int[] locarray = myarray;
502 			int pivot = locarray[width / 2 + from];
503 			int tmp;
504 			int i = from - 1;
505 			int j = to;
506 
507 			for (;;) {
508 				do
509 					i++;
510 				while (locarray[i] < pivot);
511 				do
512 					j--;
513 				while (pivot < locarray[j]);
514 
515 				if (i >= j)
516 					break;
517 
518 				tmp = locarray[i];
519 				locarray[i] = locarray[j];
520 				locarray[j] = tmp;
521 			}
522 
523 			sort(from, i);
524 			sort(i, to);
525 		}
526 	}
527 
528 	/**
529 	 * sort the vector using a custom quicksort.
530 	 */
531 	public void sort() {
532 		sort(0, nbelem);
533 	}
534 
535 	public void sortUnique() {
536 		int i, j;
537 		int last;
538 		if (nbelem == 0)
539 			return;
540 
541 		sort(0, nbelem);
542 		i = 1;
543 		int[] locarray = myarray;
544 		last = locarray[0];
545 		for (j = 1; j < nbelem; j++) {
546 			if (last < locarray[j]) {
547 				last = locarray[i] = locarray[j];
548 				i++;
549 			}
550 		}
551 
552 		nbelem = i;
553 	}
554 
555 	/**
556 	 * Two vectors are equals iff they have the very same elements in the order.
557 	 * 
558 	 * @param obj
559 	 *            an object
560 	 * @return true iff obj is a VecInt and has the same elements as this vector
561 	 *         at each index.
562 	 * 
563 	 * @see java.lang.Object#equals(java.lang.Object)
564 	 */
565 	@Override
566 	public boolean equals(Object obj) {
567 		if (obj instanceof VecInt) {
568 			VecInt v = (VecInt) obj;
569 			if (v.nbelem != nbelem)
570 				return false;
571 			for (int i = 0; i < nbelem; i++) {
572 				if (v.myarray[i] != myarray[i]) {
573 					return false;
574 				}
575 			}
576 			return true;
577 		}
578 		return false;
579 	}
580 
581 	/*
582 	 * (non-Javadoc)
583 	 * 
584 	 * @see java.lang.Object#hashCode()
585 	 */
586 	@Override
587 	public int hashCode() {
588 		long sum = 0;
589 		for (int i = 0; i < nbelem; i++) {
590 			sum += myarray[i];
591 		}
592 		return (int) sum / nbelem;
593 	}
594 
595 	/*
596 	 * (non-Javadoc)
597 	 * 
598 	 * @see org.sat4j.specs.IVecInt2#pushAll(org.sat4j.specs.IVecInt2)
599 	 */
600 	public void pushAll(IVecInt vec) {
601 		VecInt nvec = (VecInt) vec;
602 		int nsize = nbelem + nvec.nbelem;
603 		ensure(nsize);
604 		System.arraycopy(nvec.myarray, 0, myarray, nbelem, nvec.nbelem);
605 		nbelem = nsize;
606 	}
607 
608 	/**
609 	 * to detect that the vector is a subset of another one. Note that the
610 	 * method assumes that the two vectors are sorted!
611 	 * 
612 	 * @param vec
613 	 *            a vector
614 	 * @return true iff the current vector is a subset of vec
615 	 */
616 	public boolean isSubsetOf(VecInt vec) {
617 		int i = 0;
618 		int j = 0;
619 		while ((i < this.nbelem) && (j < vec.nbelem)) {
620 			while ((j < vec.nbelem) && (vec.myarray[j] < this.myarray[i])) {
621 				j++;
622 			}
623 			if (j == vec.nbelem || this.myarray[i] != vec.myarray[j])
624 				return false;
625 			i++;
626 		}
627 		return true;
628 	}
629 
630 	public IteratorInt iterator() {
631 		return new IteratorInt() {
632 			private int i = 0;
633 
634 			public boolean hasNext() {
635 				return i < nbelem;
636 			}
637 
638 			public int next() {
639 				if (i == nbelem)
640 					throw new NoSuchElementException();
641 				return myarray[i++];
642 			}
643 		};
644 	}
645 
646 	public boolean isEmpty() {
647 		return nbelem == 0;
648 	}
649 
650 	/**
651 	 * @since 2.1
652 	 */
653 	public int[] toArray() {
654 		return myarray;
655 	}
656 }