ruby-minisat 1.14.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|