ruby-minisat 1.14.2
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.
- data/.gitignore +24 -0
- data/LICENSE +21 -0
- data/README.rdoc +56 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/examples/compat18.rb +65 -0
- data/examples/example.rb +26 -0
- data/examples/example2.rb +60 -0
- data/examples/kakuro.rb +178 -0
- data/examples/kakuro.sample +13 -0
- data/examples/lonely7.rb +302 -0
- data/examples/nonogram.rb +254 -0
- data/examples/nonogram.sample +26 -0
- data/examples/numberlink.rb +489 -0
- data/examples/numberlink.sample +11 -0
- data/examples/shikaku.rb +190 -0
- data/examples/shikaku.sample +11 -0
- data/examples/slitherlink.rb +279 -0
- data/examples/slitherlink.sample +11 -0
- data/examples/sudoku.rb +216 -0
- data/examples/sudoku.sample +11 -0
- data/ext/minisat/extconf.rb +9 -0
- data/ext/minisat/minisat-wrap.cpp +88 -0
- data/ext/minisat/minisat.c +497 -0
- data/ext/minisat/minisat.h +53 -0
- data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
- data/minisat/MiniSat_v1.14/Global.h +274 -0
- data/minisat/MiniSat_v1.14/Heap.h +100 -0
- data/minisat/MiniSat_v1.14/LICENSE +20 -0
- data/minisat/MiniSat_v1.14/Main.C +244 -0
- data/minisat/MiniSat_v1.14/Makefile +88 -0
- data/minisat/MiniSat_v1.14/README +30 -0
- data/minisat/MiniSat_v1.14/Solver.C +781 -0
- data/minisat/MiniSat_v1.14/Solver.h +206 -0
- data/minisat/MiniSat_v1.14/Solver.o +0 -0
- data/minisat/MiniSat_v1.14/SolverTypes.h +130 -0
- data/minisat/MiniSat_v1.14/Sort.h +131 -0
- data/minisat/MiniSat_v1.14/TODO +73 -0
- data/minisat/MiniSat_v1.14/VarOrder.h +96 -0
- data/test/test_minisat.rb +143 -0
- metadata +114 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
==================================================
|
2
|
+
The 'ok' flag...
|
3
|
+
==================================================
|
4
|
+
|
5
|
+
The vector 'clauses[]' store all clauses of size >= 2, the vector
|
6
|
+
'assigns[]' store clauses of size 1, the boolean 'ok' stores clauses
|
7
|
+
of size 0 -- and there is only one such clause, the empty clause, so
|
8
|
+
in other words, 'ok' stores "is there an empty clause or not".
|
9
|
+
|
10
|
+
As Niklas S�rensson pointed out, the 'ok' flag is a bit error prone
|
11
|
+
and probably best viewed as an abstraction provided by the public
|
12
|
+
member functions for user convenience (you don't have to watch the
|
13
|
+
return value after each 'addClause()'). This is currently not
|
14
|
+
implemented, and the 'ok' flag is still present in the internal
|
15
|
+
methods. This will change in the future.
|
16
|
+
|
17
|
+
|
18
|
+
==================================================
|
19
|
+
Assumptions
|
20
|
+
==================================================
|
21
|
+
|
22
|
+
The handling of assumptions and the 'root_level' is a bit clumsy. We
|
23
|
+
will probably change so that the conflict driven backtracking can undo
|
24
|
+
beyond the 'root_level', and then let the assumptions be
|
25
|
+
remade. Currently we have to put in a hack to assure unit clauses have
|
26
|
+
a 'level' of zero, or else the 'analyzeFinal()' method will not work
|
27
|
+
properly. These unit clauses will also be forgotten before the next
|
28
|
+
incremental SAT, which is also undesirable (but doesn't seem to
|
29
|
+
degrade performance).
|
30
|
+
|
31
|
+
|
32
|
+
==================================================
|
33
|
+
Floating points
|
34
|
+
==================================================
|
35
|
+
|
36
|
+
The IEEE standard allows, in principle, floating points to behave
|
37
|
+
identical on different systems. However, the FPU can be set in different
|
38
|
+
modes, and Linux defaults to 80 bits mantissa, while most other systems,
|
39
|
+
including Free BSD, defaults to 64 bits. The latter is preferd, as
|
40
|
+
the 80 bit precision in Linux is only preserved as long as the 'double'
|
41
|
+
is kept in a register (which depends on the C-compiler -- you have
|
42
|
+
no control). With proper #ifdef's for differnt systems, the FPU can
|
43
|
+
be put into the right mode.
|
44
|
+
|
45
|
+
Of course it doesn't affect the efficiency of the solver, but since we
|
46
|
+
use floats in our activity heuristic, eventually the same solver can
|
47
|
+
behave different on different systems. The most stop-gap incarnation
|
48
|
+
of this is a statically linked Linux binary, which when ran on
|
49
|
+
identical hardware but under FreeBSD, can produce different behavior.
|
50
|
+
|
51
|
+
|
52
|
+
==================================================
|
53
|
+
Proof logging (for the '1.14p' version)
|
54
|
+
==================================================
|
55
|
+
|
56
|
+
Proof logging is still missing the implementation of the 'compress()'
|
57
|
+
method, that will pull out the "proof" from the "trace", i.e. remove
|
58
|
+
the derivation of clauses that did not participate in the final
|
59
|
+
conflict (deriving the empty clause). It's just work, and it will
|
60
|
+
happen, but currently you can only traverse the whole trace (which is
|
61
|
+
still very useful).
|
62
|
+
|
63
|
+
|
64
|
+
==================================================
|
65
|
+
Conflict clause minimization & 'trail_pos[]'
|
66
|
+
==================================================
|
67
|
+
|
68
|
+
In proof logging mode, the order of literals in 'trail[]' (the
|
69
|
+
assignment stack) must be recorded to do the logging correctly for
|
70
|
+
conflict clause minimization. However, this position could actually,
|
71
|
+
with some modification, replace the 'level[]' vector all together. It
|
72
|
+
makes a lot of sense to do this, but for the time being we record
|
73
|
+
both. This will change in the future.
|
@@ -0,0 +1,96 @@
|
|
1
|
+
/**************************************************************************************[VarOrder.h]
|
2
|
+
MiniSat -- Copyright (c) 2003-2005, Niklas Een, 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 VarOrder_h
|
21
|
+
#define VarOrder_h
|
22
|
+
|
23
|
+
#include "SolverTypes.h"
|
24
|
+
#include "Heap.h"
|
25
|
+
|
26
|
+
|
27
|
+
//=================================================================================================
|
28
|
+
|
29
|
+
|
30
|
+
struct VarOrder_lt {
|
31
|
+
const vec<double>& activity;
|
32
|
+
bool operator () (Var x, Var y) { return activity[x] > activity[y]; }
|
33
|
+
VarOrder_lt(const vec<double>& act) : activity(act) { }
|
34
|
+
};
|
35
|
+
|
36
|
+
class VarOrder {
|
37
|
+
const vec<char>& assigns; // var->val. Pointer to external assignment table.
|
38
|
+
const vec<double>& activity; // var->act. Pointer to external activity table.
|
39
|
+
Heap<VarOrder_lt> heap;
|
40
|
+
double random_seed; // For the internal random number generator
|
41
|
+
|
42
|
+
public:
|
43
|
+
VarOrder(const vec<char>& ass, const vec<double>& act) :
|
44
|
+
assigns(ass), activity(act), heap(VarOrder_lt(act)), random_seed(91648253)
|
45
|
+
{ }
|
46
|
+
|
47
|
+
inline void newVar(void);
|
48
|
+
inline void update(Var x); // Called when variable increased in activity.
|
49
|
+
inline void undo(Var x); // Called when variable is unassigned and may be selected again.
|
50
|
+
inline Var select(double random_freq =.0); // Selects a new, unassigned variable (or 'var_Undef' if none exists).
|
51
|
+
};
|
52
|
+
|
53
|
+
|
54
|
+
void VarOrder::newVar(void)
|
55
|
+
{
|
56
|
+
heap.setBounds(assigns.size());
|
57
|
+
heap.insert(assigns.size()-1);
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
void VarOrder::update(Var x)
|
62
|
+
{
|
63
|
+
if (heap.inHeap(x))
|
64
|
+
heap.increase(x);
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
void VarOrder::undo(Var x)
|
69
|
+
{
|
70
|
+
if (!heap.inHeap(x))
|
71
|
+
heap.insert(x);
|
72
|
+
}
|
73
|
+
|
74
|
+
|
75
|
+
Var VarOrder::select(double random_var_freq)
|
76
|
+
{
|
77
|
+
// Random decision:
|
78
|
+
if (drand(random_seed) < random_var_freq && !heap.empty()){
|
79
|
+
Var next = irand(random_seed,assigns.size());
|
80
|
+
if (toLbool(assigns[next]) == l_Undef)
|
81
|
+
return next;
|
82
|
+
}
|
83
|
+
|
84
|
+
// Activity based decision:
|
85
|
+
while (!heap.empty()){
|
86
|
+
Var next = heap.getmin();
|
87
|
+
if (toLbool(assigns[next]) == l_Undef)
|
88
|
+
return next;
|
89
|
+
}
|
90
|
+
|
91
|
+
return var_Undef;
|
92
|
+
}
|
93
|
+
|
94
|
+
|
95
|
+
//=================================================================================================
|
96
|
+
#endif
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "rubygems"
|
3
|
+
require "minisat"
|
4
|
+
|
5
|
+
class TestMiniSat < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@solver = MiniSat::Solver.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_variable_pos
|
11
|
+
var = @solver.new_var
|
12
|
+
assert_nothing_raised { +var }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_variable_neg
|
16
|
+
var = @solver.new_var
|
17
|
+
assert_nothing_raised { -var }
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_variable_value
|
21
|
+
var1 = @solver.new_var
|
22
|
+
var2 = @solver.new_var
|
23
|
+
assert_raise(RuntimeError) { var1.value }
|
24
|
+
@solver << var1 << -var2
|
25
|
+
@solver.solve
|
26
|
+
assert_equal(true , var1.value)
|
27
|
+
assert_equal(false, var2.value)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_solver_add_clause
|
31
|
+
var1 = @solver.new_var
|
32
|
+
var2 = @solver.new_var
|
33
|
+
@solver.add_clause(-var1, -var2)
|
34
|
+
@solver.add_clause(var1)
|
35
|
+
@solver.solve
|
36
|
+
assert_equal(true , var1.value)
|
37
|
+
assert_equal(false, var2.value)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_solver_add_clause_2
|
41
|
+
var1 = @solver.new_var
|
42
|
+
var2 = @solver.new_var
|
43
|
+
@solver << [-var1, -var2] << var1
|
44
|
+
@solver.solve
|
45
|
+
assert_equal(true , var1.value)
|
46
|
+
assert_equal(false, var2.value)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_solver_result
|
50
|
+
var1 = @solver.new_var
|
51
|
+
var2 = @solver.new_var
|
52
|
+
@solver << [-var1, -var2] << var1
|
53
|
+
@solver.solve
|
54
|
+
assert_equal(@solver[var1], var1.value)
|
55
|
+
assert_equal(@solver[var2], var2.value)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_solver_clause_size
|
59
|
+
var1 = @solver.new_var
|
60
|
+
var2 = @solver.new_var
|
61
|
+
assert_equal(0, @solver.clause_size)
|
62
|
+
@solver << [-var1, -var2]
|
63
|
+
assert_equal(1, @solver.clause_size)
|
64
|
+
@solver << var1
|
65
|
+
assert_equal(2, @solver.clause_size)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_solver_satisfied?
|
69
|
+
assert_equal(false, @solver.satisfied?)
|
70
|
+
var = @solver.new_var
|
71
|
+
@solver << var
|
72
|
+
@solver.solve
|
73
|
+
assert_equal(true, @solver.satisfied?)
|
74
|
+
@solver << -var
|
75
|
+
@solver.solve
|
76
|
+
assert_equal(false, @solver.satisfied?)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_solver_simplify_db
|
80
|
+
@solver.solve
|
81
|
+
assert_nothing_raised { @solver.simplify_db }
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_solver_solve
|
85
|
+
var1 = @solver.new_var
|
86
|
+
var2 = @solver.new_var
|
87
|
+
@solver << [var1, var2]
|
88
|
+
assert_equal(false, @solver.solve(-var1, -var2))
|
89
|
+
assert_equal(true , @solver.solve(-var1))
|
90
|
+
assert_equal(false, var1.value)
|
91
|
+
assert_equal(true , var2.value)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_solver_solved?
|
95
|
+
assert_equal(false, @solver.solved?)
|
96
|
+
var = @solver.new_var
|
97
|
+
@solver << var
|
98
|
+
@solver.solve
|
99
|
+
assert_equal(true, @solver.solved?)
|
100
|
+
@solver << -var
|
101
|
+
@solver.solve
|
102
|
+
assert_equal(true, @solver.solved?)
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_var_size
|
106
|
+
assert_equal(0, @solver.var_size)
|
107
|
+
var1 = @solver.new_var
|
108
|
+
assert_equal(1, @solver.var_size)
|
109
|
+
var2 = @solver.new_var
|
110
|
+
assert_equal(2, @solver.var_size)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_senario1
|
114
|
+
a = @solver.new_var
|
115
|
+
b = @solver.new_var
|
116
|
+
|
117
|
+
@solver << [a, b] << [-a, b] << [a, -b]
|
118
|
+
|
119
|
+
assert_equal(true, @solver.solve)
|
120
|
+
assert_equal(true, @solver[a])
|
121
|
+
assert_equal(true, @solver[b])
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_senario2
|
125
|
+
a = @solver.new_var
|
126
|
+
b = @solver.new_var
|
127
|
+
|
128
|
+
@solver << [-a, -b] << [-a, b] << [a, -b]
|
129
|
+
|
130
|
+
assert_equal(true, @solver.solve)
|
131
|
+
assert_equal(false, @solver[a])
|
132
|
+
assert_equal(false, @solver[b])
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_senario3
|
136
|
+
a = @solver.new_var
|
137
|
+
b = @solver.new_var
|
138
|
+
|
139
|
+
@solver << [a, b] << [-a, b] << [a, -b] << [-a, -b]
|
140
|
+
|
141
|
+
assert_equal(false, @solver.solve)
|
142
|
+
end
|
143
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-minisat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 14
|
8
|
+
- 2
|
9
|
+
version: 1.14.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Yusuke Endoh
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-07 00:00:00 +09:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: ruby binding for MiniSat, which is an open-source SAT solver
|
22
|
+
email: mame@tsg.ne.jp
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions:
|
26
|
+
- ext/minisat/extconf.rb
|
27
|
+
extra_rdoc_files:
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
- Rakefile
|
35
|
+
- VERSION
|
36
|
+
- examples/compat18.rb
|
37
|
+
- examples/example.rb
|
38
|
+
- examples/example2.rb
|
39
|
+
- examples/kakuro.rb
|
40
|
+
- examples/kakuro.sample
|
41
|
+
- examples/lonely7.rb
|
42
|
+
- examples/nonogram.rb
|
43
|
+
- examples/nonogram.sample
|
44
|
+
- examples/numberlink.rb
|
45
|
+
- examples/numberlink.sample
|
46
|
+
- examples/shikaku.rb
|
47
|
+
- examples/shikaku.sample
|
48
|
+
- examples/slitherlink.rb
|
49
|
+
- examples/slitherlink.sample
|
50
|
+
- examples/sudoku.rb
|
51
|
+
- examples/sudoku.sample
|
52
|
+
- ext/minisat/extconf.rb
|
53
|
+
- ext/minisat/minisat-wrap.cpp
|
54
|
+
- ext/minisat/minisat.c
|
55
|
+
- ext/minisat/minisat.h
|
56
|
+
- minisat/MiniSat_v1.14.2006-Aug-29.src.zip
|
57
|
+
- minisat/MiniSat_v1.14/Global.h
|
58
|
+
- minisat/MiniSat_v1.14/Heap.h
|
59
|
+
- minisat/MiniSat_v1.14/LICENSE
|
60
|
+
- minisat/MiniSat_v1.14/Main.C
|
61
|
+
- minisat/MiniSat_v1.14/Makefile
|
62
|
+
- minisat/MiniSat_v1.14/README
|
63
|
+
- minisat/MiniSat_v1.14/Solver.C
|
64
|
+
- minisat/MiniSat_v1.14/Solver.h
|
65
|
+
- minisat/MiniSat_v1.14/Solver.o
|
66
|
+
- minisat/MiniSat_v1.14/SolverTypes.h
|
67
|
+
- minisat/MiniSat_v1.14/Sort.h
|
68
|
+
- minisat/MiniSat_v1.14/TODO
|
69
|
+
- minisat/MiniSat_v1.14/VarOrder.h
|
70
|
+
- test/test_minisat.rb
|
71
|
+
has_rdoc: true
|
72
|
+
homepage: http://github.com/mame/ruby-minisat
|
73
|
+
licenses: []
|
74
|
+
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options:
|
77
|
+
- --charset=UTF-8
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
requirements: []
|
97
|
+
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 1.3.7
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: ruby binding for MiniSat, which is an open-source SAT solver
|
103
|
+
test_files:
|
104
|
+
- test/test_minisat.rb
|
105
|
+
- examples/compat18.rb
|
106
|
+
- examples/shikaku.rb
|
107
|
+
- examples/kakuro.rb
|
108
|
+
- examples/example2.rb
|
109
|
+
- examples/example.rb
|
110
|
+
- examples/numberlink.rb
|
111
|
+
- examples/lonely7.rb
|
112
|
+
- examples/slitherlink.rb
|
113
|
+
- examples/sudoku.rb
|
114
|
+
- examples/nonogram.rb
|