ruby-minisat 1.14.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -21
- data/Gemfile +4 -0
- data/LICENSE +3 -2
- data/README.md +42 -0
- data/Rakefile +1 -48
- data/examples/shikaku.rb +2 -2
- data/ext/minisat/extconf.rb +19 -4
- data/ext/minisat/minisat-wrap.cpp +11 -5
- data/ext/minisat/minisat.c +17 -3
- data/ext/minisat/minisat.h +1 -1
- data/minisat/minisat-2.2.0.tar.gz +0 -0
- data/minisat/{MiniSat_v1.14 → minisat}/LICENSE +2 -1
- data/minisat/minisat/README +24 -0
- data/minisat/minisat/core/Dimacs.h +89 -0
- data/minisat/minisat/core/Main.cc +192 -0
- data/minisat/minisat/core/Solver.cc +923 -0
- data/minisat/minisat/core/Solver.h +373 -0
- data/minisat/minisat/core/SolverTypes.h +407 -0
- data/minisat/minisat/mtl/Alg.h +84 -0
- data/minisat/minisat/mtl/Alloc.h +131 -0
- data/minisat/minisat/mtl/Heap.h +148 -0
- data/minisat/minisat/mtl/IntTypes.h +42 -0
- data/minisat/minisat/mtl/Map.h +193 -0
- data/minisat/minisat/mtl/Queue.h +69 -0
- data/minisat/{MiniSat_v1.14 → minisat/mtl}/Sort.h +14 -47
- data/minisat/minisat/mtl/Vec.h +130 -0
- data/minisat/minisat/mtl/XAlloc.h +45 -0
- data/minisat/minisat/mtl/config.mk +6 -0
- data/minisat/minisat/mtl/template.mk +107 -0
- data/minisat/minisat/simp/Main.cc +211 -0
- data/minisat/minisat/simp/SimpSolver.cc +717 -0
- data/minisat/minisat/simp/SimpSolver.h +197 -0
- data/minisat/minisat/utils/Options.cc +91 -0
- data/minisat/minisat/utils/Options.h +386 -0
- data/minisat/minisat/utils/ParseUtils.h +122 -0
- data/minisat/minisat/utils/System.cc +95 -0
- data/minisat/minisat/utils/System.h +60 -0
- data/ruby-minisat.gemspec +21 -0
- metadata +94 -75
- data/README.rdoc +0 -56
- data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
- data/minisat/MiniSat_v1.14/Global.h +0 -274
- data/minisat/MiniSat_v1.14/Heap.h +0 -100
- data/minisat/MiniSat_v1.14/Main.C +0 -244
- data/minisat/MiniSat_v1.14/Makefile +0 -88
- data/minisat/MiniSat_v1.14/README +0 -30
- data/minisat/MiniSat_v1.14/Solver.C +0 -781
- data/minisat/MiniSat_v1.14/Solver.h +0 -206
- data/minisat/MiniSat_v1.14/Solver.o +0 -0
- data/minisat/MiniSat_v1.14/SolverTypes.h +0 -130
- data/minisat/MiniSat_v1.14/TODO +0 -73
- data/minisat/MiniSat_v1.14/VarOrder.h +0 -96
@@ -0,0 +1,84 @@
|
|
1
|
+
/*******************************************************************************************[Alg.h]
|
2
|
+
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
3
|
+
Copyright (c) 2007-2010, Niklas Sorensson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
12
|
+
substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
17
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
18
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
|
+
**************************************************************************************************/
|
20
|
+
|
21
|
+
#ifndef Minisat_Alg_h
|
22
|
+
#define Minisat_Alg_h
|
23
|
+
|
24
|
+
#include "mtl/Vec.h"
|
25
|
+
|
26
|
+
namespace Minisat {
|
27
|
+
|
28
|
+
//=================================================================================================
|
29
|
+
// Useful functions on vector-like types:
|
30
|
+
|
31
|
+
//=================================================================================================
|
32
|
+
// Removing and searching for elements:
|
33
|
+
//
|
34
|
+
|
35
|
+
template<class V, class T>
|
36
|
+
static inline void remove(V& ts, const T& t)
|
37
|
+
{
|
38
|
+
int j = 0;
|
39
|
+
for (; j < ts.size() && ts[j] != t; j++);
|
40
|
+
assert(j < ts.size());
|
41
|
+
for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
|
42
|
+
ts.pop();
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
template<class V, class T>
|
47
|
+
static inline bool find(V& ts, const T& t)
|
48
|
+
{
|
49
|
+
int j = 0;
|
50
|
+
for (; j < ts.size() && ts[j] != t; j++);
|
51
|
+
return j < ts.size();
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
//=================================================================================================
|
56
|
+
// Copying vectors with support for nested vector types:
|
57
|
+
//
|
58
|
+
|
59
|
+
// Base case:
|
60
|
+
template<class T>
|
61
|
+
static inline void copy(const T& from, T& to)
|
62
|
+
{
|
63
|
+
to = from;
|
64
|
+
}
|
65
|
+
|
66
|
+
// Recursive case:
|
67
|
+
template<class T>
|
68
|
+
static inline void copy(const vec<T>& from, vec<T>& to, bool append = false)
|
69
|
+
{
|
70
|
+
if (!append)
|
71
|
+
to.clear();
|
72
|
+
for (int i = 0; i < from.size(); i++){
|
73
|
+
to.push();
|
74
|
+
copy(from[i], to.last());
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
template<class T>
|
79
|
+
static inline void append(const vec<T>& from, vec<T>& to){ copy(from, to, true); }
|
80
|
+
|
81
|
+
//=================================================================================================
|
82
|
+
}
|
83
|
+
|
84
|
+
#endif
|
@@ -0,0 +1,131 @@
|
|
1
|
+
/*****************************************************************************************[Alloc.h]
|
2
|
+
Copyright (c) 2008-2010, Niklas Sorensson
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
5
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
6
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
7
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
11
|
+
substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
14
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
16
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
17
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
**************************************************************************************************/
|
19
|
+
|
20
|
+
|
21
|
+
#ifndef Minisat_Alloc_h
|
22
|
+
#define Minisat_Alloc_h
|
23
|
+
|
24
|
+
#include "mtl/XAlloc.h"
|
25
|
+
#include "mtl/Vec.h"
|
26
|
+
|
27
|
+
namespace Minisat {
|
28
|
+
|
29
|
+
//=================================================================================================
|
30
|
+
// Simple Region-based memory allocator:
|
31
|
+
|
32
|
+
template<class T>
|
33
|
+
class RegionAllocator
|
34
|
+
{
|
35
|
+
T* memory;
|
36
|
+
uint32_t sz;
|
37
|
+
uint32_t cap;
|
38
|
+
uint32_t wasted_;
|
39
|
+
|
40
|
+
void capacity(uint32_t min_cap);
|
41
|
+
|
42
|
+
public:
|
43
|
+
// TODO: make this a class for better type-checking?
|
44
|
+
typedef uint32_t Ref;
|
45
|
+
enum { Ref_Undef = UINT32_MAX };
|
46
|
+
enum { Unit_Size = sizeof(uint32_t) };
|
47
|
+
|
48
|
+
explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); }
|
49
|
+
~RegionAllocator()
|
50
|
+
{
|
51
|
+
if (memory != NULL)
|
52
|
+
::free(memory);
|
53
|
+
}
|
54
|
+
|
55
|
+
|
56
|
+
uint32_t size () const { return sz; }
|
57
|
+
uint32_t wasted () const { return wasted_; }
|
58
|
+
|
59
|
+
Ref alloc (int size);
|
60
|
+
void free (int size) { wasted_ += size; }
|
61
|
+
|
62
|
+
// Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
|
63
|
+
T& operator[](Ref r) { assert(r >= 0 && r < sz); return memory[r]; }
|
64
|
+
const T& operator[](Ref r) const { assert(r >= 0 && r < sz); return memory[r]; }
|
65
|
+
|
66
|
+
T* lea (Ref r) { assert(r >= 0 && r < sz); return &memory[r]; }
|
67
|
+
const T* lea (Ref r) const { assert(r >= 0 && r < sz); return &memory[r]; }
|
68
|
+
Ref ael (const T* t) { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]);
|
69
|
+
return (Ref)(t - &memory[0]); }
|
70
|
+
|
71
|
+
void moveTo(RegionAllocator& to) {
|
72
|
+
if (to.memory != NULL) ::free(to.memory);
|
73
|
+
to.memory = memory;
|
74
|
+
to.sz = sz;
|
75
|
+
to.cap = cap;
|
76
|
+
to.wasted_ = wasted_;
|
77
|
+
|
78
|
+
memory = NULL;
|
79
|
+
sz = cap = wasted_ = 0;
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
};
|
84
|
+
|
85
|
+
template<class T>
|
86
|
+
void RegionAllocator<T>::capacity(uint32_t min_cap)
|
87
|
+
{
|
88
|
+
if (cap >= min_cap) return;
|
89
|
+
|
90
|
+
uint32_t prev_cap = cap;
|
91
|
+
while (cap < min_cap){
|
92
|
+
// NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the
|
93
|
+
// result even by clearing the least significant bit. The resulting sequence of capacities
|
94
|
+
// is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when
|
95
|
+
// using 'uint32_t' as indices so that as much as possible of this space can be used.
|
96
|
+
uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1;
|
97
|
+
cap += delta;
|
98
|
+
|
99
|
+
if (cap <= prev_cap)
|
100
|
+
throw OutOfMemoryException();
|
101
|
+
}
|
102
|
+
// printf(" .. (%p) cap = %u\n", this, cap);
|
103
|
+
|
104
|
+
assert(cap > 0);
|
105
|
+
memory = (T*)xrealloc(memory, sizeof(T)*cap);
|
106
|
+
}
|
107
|
+
|
108
|
+
|
109
|
+
template<class T>
|
110
|
+
typename RegionAllocator<T>::Ref
|
111
|
+
RegionAllocator<T>::alloc(int size)
|
112
|
+
{
|
113
|
+
// printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout);
|
114
|
+
assert(size > 0);
|
115
|
+
capacity(sz + size);
|
116
|
+
|
117
|
+
uint32_t prev_sz = sz;
|
118
|
+
sz += size;
|
119
|
+
|
120
|
+
// Handle overflow:
|
121
|
+
if (sz < prev_sz)
|
122
|
+
throw OutOfMemoryException();
|
123
|
+
|
124
|
+
return prev_sz;
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
//=================================================================================================
|
129
|
+
}
|
130
|
+
|
131
|
+
#endif
|
@@ -0,0 +1,148 @@
|
|
1
|
+
/******************************************************************************************[Heap.h]
|
2
|
+
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
3
|
+
Copyright (c) 2007-2010, Niklas Sorensson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
12
|
+
substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
17
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
18
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
|
+
**************************************************************************************************/
|
20
|
+
|
21
|
+
#ifndef Minisat_Heap_h
|
22
|
+
#define Minisat_Heap_h
|
23
|
+
|
24
|
+
#include "mtl/Vec.h"
|
25
|
+
|
26
|
+
namespace Minisat {
|
27
|
+
|
28
|
+
//=================================================================================================
|
29
|
+
// A heap implementation with support for decrease/increase key.
|
30
|
+
|
31
|
+
|
32
|
+
template<class Comp>
|
33
|
+
class Heap {
|
34
|
+
Comp lt; // The heap is a minimum-heap with respect to this comparator
|
35
|
+
vec<int> heap; // Heap of integers
|
36
|
+
vec<int> indices; // Each integers position (index) in the Heap
|
37
|
+
|
38
|
+
// Index "traversal" functions
|
39
|
+
static inline int left (int i) { return i*2+1; }
|
40
|
+
static inline int right (int i) { return (i+1)*2; }
|
41
|
+
static inline int parent(int i) { return (i-1) >> 1; }
|
42
|
+
|
43
|
+
|
44
|
+
void percolateUp(int i)
|
45
|
+
{
|
46
|
+
int x = heap[i];
|
47
|
+
int p = parent(i);
|
48
|
+
|
49
|
+
while (i != 0 && lt(x, heap[p])){
|
50
|
+
heap[i] = heap[p];
|
51
|
+
indices[heap[p]] = i;
|
52
|
+
i = p;
|
53
|
+
p = parent(p);
|
54
|
+
}
|
55
|
+
heap [i] = x;
|
56
|
+
indices[x] = i;
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
void percolateDown(int i)
|
61
|
+
{
|
62
|
+
int x = heap[i];
|
63
|
+
while (left(i) < heap.size()){
|
64
|
+
int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
|
65
|
+
if (!lt(heap[child], x)) break;
|
66
|
+
heap[i] = heap[child];
|
67
|
+
indices[heap[i]] = i;
|
68
|
+
i = child;
|
69
|
+
}
|
70
|
+
heap [i] = x;
|
71
|
+
indices[x] = i;
|
72
|
+
}
|
73
|
+
|
74
|
+
|
75
|
+
public:
|
76
|
+
Heap(const Comp& c) : lt(c) { }
|
77
|
+
|
78
|
+
int size () const { return heap.size(); }
|
79
|
+
bool empty () const { return heap.size() == 0; }
|
80
|
+
bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
|
81
|
+
int operator[](int index) const { assert(index < heap.size()); return heap[index]; }
|
82
|
+
|
83
|
+
|
84
|
+
void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
|
85
|
+
void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
|
86
|
+
|
87
|
+
|
88
|
+
// Safe variant of insert/decrease/increase:
|
89
|
+
void update(int n)
|
90
|
+
{
|
91
|
+
if (!inHeap(n))
|
92
|
+
insert(n);
|
93
|
+
else {
|
94
|
+
percolateUp(indices[n]);
|
95
|
+
percolateDown(indices[n]); }
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
void insert(int n)
|
100
|
+
{
|
101
|
+
indices.growTo(n+1, -1);
|
102
|
+
assert(!inHeap(n));
|
103
|
+
|
104
|
+
indices[n] = heap.size();
|
105
|
+
heap.push(n);
|
106
|
+
percolateUp(indices[n]);
|
107
|
+
}
|
108
|
+
|
109
|
+
|
110
|
+
int removeMin()
|
111
|
+
{
|
112
|
+
int x = heap[0];
|
113
|
+
heap[0] = heap.last();
|
114
|
+
indices[heap[0]] = 0;
|
115
|
+
indices[x] = -1;
|
116
|
+
heap.pop();
|
117
|
+
if (heap.size() > 1) percolateDown(0);
|
118
|
+
return x;
|
119
|
+
}
|
120
|
+
|
121
|
+
|
122
|
+
// Rebuild the heap from scratch, using the elements in 'ns':
|
123
|
+
void build(vec<int>& ns) {
|
124
|
+
for (int i = 0; i < heap.size(); i++)
|
125
|
+
indices[heap[i]] = -1;
|
126
|
+
heap.clear();
|
127
|
+
|
128
|
+
for (int i = 0; i < ns.size(); i++){
|
129
|
+
indices[ns[i]] = i;
|
130
|
+
heap.push(ns[i]); }
|
131
|
+
|
132
|
+
for (int i = heap.size() / 2 - 1; i >= 0; i--)
|
133
|
+
percolateDown(i);
|
134
|
+
}
|
135
|
+
|
136
|
+
void clear(bool dealloc = false)
|
137
|
+
{
|
138
|
+
for (int i = 0; i < heap.size(); i++)
|
139
|
+
indices[heap[i]] = -1;
|
140
|
+
heap.clear(dealloc);
|
141
|
+
}
|
142
|
+
};
|
143
|
+
|
144
|
+
|
145
|
+
//=================================================================================================
|
146
|
+
}
|
147
|
+
|
148
|
+
#endif
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/**************************************************************************************[IntTypes.h]
|
2
|
+
Copyright (c) 2009-2010, Niklas Sorensson
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
5
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
6
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
7
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
11
|
+
substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
14
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
16
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
17
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
**************************************************************************************************/
|
19
|
+
|
20
|
+
#ifndef Minisat_IntTypes_h
|
21
|
+
#define Minisat_IntTypes_h
|
22
|
+
|
23
|
+
#ifdef __sun
|
24
|
+
// Not sure if there are newer versions that support C99 headers. The
|
25
|
+
// needed features are implemented in the headers below though:
|
26
|
+
|
27
|
+
# include <sys/int_types.h>
|
28
|
+
# include <sys/int_fmtio.h>
|
29
|
+
# include <sys/int_limits.h>
|
30
|
+
|
31
|
+
#else
|
32
|
+
|
33
|
+
# include <stdint.h>
|
34
|
+
# include <inttypes.h>
|
35
|
+
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#include <limits.h>
|
39
|
+
|
40
|
+
//=================================================================================================
|
41
|
+
|
42
|
+
#endif
|
@@ -0,0 +1,193 @@
|
|
1
|
+
/*******************************************************************************************[Map.h]
|
2
|
+
Copyright (c) 2006-2010, Niklas Sorensson
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
5
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
6
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
7
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
11
|
+
substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
14
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
16
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
17
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
**************************************************************************************************/
|
19
|
+
|
20
|
+
#ifndef Minisat_Map_h
|
21
|
+
#define Minisat_Map_h
|
22
|
+
|
23
|
+
#include "mtl/IntTypes.h"
|
24
|
+
#include "mtl/Vec.h"
|
25
|
+
|
26
|
+
namespace Minisat {
|
27
|
+
|
28
|
+
//=================================================================================================
|
29
|
+
// Default hash/equals functions
|
30
|
+
//
|
31
|
+
|
32
|
+
template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
|
33
|
+
template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
|
34
|
+
|
35
|
+
template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
|
36
|
+
template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
|
37
|
+
|
38
|
+
static inline uint32_t hash(uint32_t x){ return x; }
|
39
|
+
static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
|
40
|
+
static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
|
41
|
+
static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
|
42
|
+
|
43
|
+
|
44
|
+
//=================================================================================================
|
45
|
+
// Some primes
|
46
|
+
//
|
47
|
+
|
48
|
+
static const int nprimes = 25;
|
49
|
+
static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 };
|
50
|
+
|
51
|
+
//=================================================================================================
|
52
|
+
// Hash table implementation of Maps
|
53
|
+
//
|
54
|
+
|
55
|
+
template<class K, class D, class H = Hash<K>, class E = Equal<K> >
|
56
|
+
class Map {
|
57
|
+
public:
|
58
|
+
struct Pair { K key; D data; };
|
59
|
+
|
60
|
+
private:
|
61
|
+
H hash;
|
62
|
+
E equals;
|
63
|
+
|
64
|
+
vec<Pair>* table;
|
65
|
+
int cap;
|
66
|
+
int size;
|
67
|
+
|
68
|
+
// Don't allow copying (error prone):
|
69
|
+
Map<K,D,H,E>& operator = (Map<K,D,H,E>& other) { assert(0); }
|
70
|
+
Map (Map<K,D,H,E>& other) { assert(0); }
|
71
|
+
|
72
|
+
bool checkCap(int new_size) const { return new_size > cap; }
|
73
|
+
|
74
|
+
int32_t index (const K& k) const { return hash(k) % cap; }
|
75
|
+
void _insert (const K& k, const D& d) {
|
76
|
+
vec<Pair>& ps = table[index(k)];
|
77
|
+
ps.push(); ps.last().key = k; ps.last().data = d; }
|
78
|
+
|
79
|
+
void rehash () {
|
80
|
+
const vec<Pair>* old = table;
|
81
|
+
|
82
|
+
int old_cap = cap;
|
83
|
+
int newsize = primes[0];
|
84
|
+
for (int i = 1; newsize <= cap && i < nprimes; i++)
|
85
|
+
newsize = primes[i];
|
86
|
+
|
87
|
+
table = new vec<Pair>[newsize];
|
88
|
+
cap = newsize;
|
89
|
+
|
90
|
+
for (int i = 0; i < old_cap; i++){
|
91
|
+
for (int j = 0; j < old[i].size(); j++){
|
92
|
+
_insert(old[i][j].key, old[i][j].data); }}
|
93
|
+
|
94
|
+
delete [] old;
|
95
|
+
|
96
|
+
// printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
public:
|
101
|
+
|
102
|
+
Map () : table(NULL), cap(0), size(0) {}
|
103
|
+
Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){}
|
104
|
+
~Map () { delete [] table; }
|
105
|
+
|
106
|
+
// PRECONDITION: the key must already exist in the map.
|
107
|
+
const D& operator [] (const K& k) const
|
108
|
+
{
|
109
|
+
assert(size != 0);
|
110
|
+
const D* res = NULL;
|
111
|
+
const vec<Pair>& ps = table[index(k)];
|
112
|
+
for (int i = 0; i < ps.size(); i++)
|
113
|
+
if (equals(ps[i].key, k))
|
114
|
+
res = &ps[i].data;
|
115
|
+
assert(res != NULL);
|
116
|
+
return *res;
|
117
|
+
}
|
118
|
+
|
119
|
+
// PRECONDITION: the key must already exist in the map.
|
120
|
+
D& operator [] (const K& k)
|
121
|
+
{
|
122
|
+
assert(size != 0);
|
123
|
+
D* res = NULL;
|
124
|
+
vec<Pair>& ps = table[index(k)];
|
125
|
+
for (int i = 0; i < ps.size(); i++)
|
126
|
+
if (equals(ps[i].key, k))
|
127
|
+
res = &ps[i].data;
|
128
|
+
assert(res != NULL);
|
129
|
+
return *res;
|
130
|
+
}
|
131
|
+
|
132
|
+
// PRECONDITION: the key must *NOT* exist in the map.
|
133
|
+
void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
|
134
|
+
bool peek (const K& k, D& d) const {
|
135
|
+
if (size == 0) return false;
|
136
|
+
const vec<Pair>& ps = table[index(k)];
|
137
|
+
for (int i = 0; i < ps.size(); i++)
|
138
|
+
if (equals(ps[i].key, k)){
|
139
|
+
d = ps[i].data;
|
140
|
+
return true; }
|
141
|
+
return false;
|
142
|
+
}
|
143
|
+
|
144
|
+
bool has (const K& k) const {
|
145
|
+
if (size == 0) return false;
|
146
|
+
const vec<Pair>& ps = table[index(k)];
|
147
|
+
for (int i = 0; i < ps.size(); i++)
|
148
|
+
if (equals(ps[i].key, k))
|
149
|
+
return true;
|
150
|
+
return false;
|
151
|
+
}
|
152
|
+
|
153
|
+
// PRECONDITION: the key must exist in the map.
|
154
|
+
void remove(const K& k) {
|
155
|
+
assert(table != NULL);
|
156
|
+
vec<Pair>& ps = table[index(k)];
|
157
|
+
int j = 0;
|
158
|
+
for (; j < ps.size() && !equals(ps[j].key, k); j++);
|
159
|
+
assert(j < ps.size());
|
160
|
+
ps[j] = ps.last();
|
161
|
+
ps.pop();
|
162
|
+
size--;
|
163
|
+
}
|
164
|
+
|
165
|
+
void clear () {
|
166
|
+
cap = size = 0;
|
167
|
+
delete [] table;
|
168
|
+
table = NULL;
|
169
|
+
}
|
170
|
+
|
171
|
+
int elems() const { return size; }
|
172
|
+
int bucket_count() const { return cap; }
|
173
|
+
|
174
|
+
// NOTE: the hash and equality objects are not moved by this method:
|
175
|
+
void moveTo(Map& other){
|
176
|
+
delete [] other.table;
|
177
|
+
|
178
|
+
other.table = table;
|
179
|
+
other.cap = cap;
|
180
|
+
other.size = size;
|
181
|
+
|
182
|
+
table = NULL;
|
183
|
+
size = cap = 0;
|
184
|
+
}
|
185
|
+
|
186
|
+
// NOTE: given a bit more time, I could make a more C++-style iterator out of this:
|
187
|
+
const vec<Pair>& bucket(int i) const { return table[i]; }
|
188
|
+
};
|
189
|
+
|
190
|
+
//=================================================================================================
|
191
|
+
}
|
192
|
+
|
193
|
+
#endif
|