ruby-minisat 1.14.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|