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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 296d98a29864044819a0e0dd556a152e1aff8a96
|
4
|
+
data.tar.gz: 10a28e85eca2fc741a4dd4f43adaabe248dc1146
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3990d7912879f13d48445fe48a4435b9c4a8d94245b55de68bdfea4142ec4e434a0a0560eb111b6f228f9280637524f2d7230c1edec94cd1c58d92a0c990cf5
|
7
|
+
data.tar.gz: abf39822777fff19785d307d1c1acd6e016fd48b8f0afb03643daaa38e369a491aaff833cdefed6784b06a231aeab0c8822ab4fcaf931b014e12223065acf9d5
|
data/.gitignore
CHANGED
@@ -1,24 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
*~
|
10
|
-
\#*
|
11
|
-
.\#*
|
12
|
-
|
13
|
-
## VIM
|
14
|
-
*.swp
|
15
|
-
|
16
|
-
## PROJECT::GENERAL
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
17
9
|
coverage
|
18
|
-
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
19
12
|
pkg
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
24
17
|
tmp
|
18
|
+
*.o
|
19
|
+
*.so
|
20
|
+
Makefile
|
21
|
+
.*.sw*
|
data/Gemfile
ADDED
data/LICENSE
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
MiniSat -- Copyright (c) 2003-
|
2
|
-
|
1
|
+
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
2
|
+
Copyright (c) 2007-2010 Niklas Sorensson
|
3
|
+
ruby-minisat -- Copyright (c) 2007,2010,2013 Yusuke Endoh
|
3
4
|
|
4
5
|
Permission is hereby granted, free of charge, to any person obtaining a
|
5
6
|
copy of this software and associated documentation files (the
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Minisat
|
2
|
+
|
3
|
+
ruby-minisat is ruby binding for MiniSat, an open-source SAT solver.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install ruby-minisat
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
A brief example that solves a simple SAT problem:
|
12
|
+
|
13
|
+
# solve (a or b) and (not a or b) and (a or not b)
|
14
|
+
|
15
|
+
require "minisat"
|
16
|
+
solver = MiniSat::Solver.new
|
17
|
+
|
18
|
+
a = solver.new_var
|
19
|
+
b = solver.new_var
|
20
|
+
|
21
|
+
solver << [a, b] << [-a, b] << [a, -b]
|
22
|
+
|
23
|
+
p solver.solve #=> true (satisfiable)
|
24
|
+
|
25
|
+
p solver[a] #=> true
|
26
|
+
p solver[b] #=> true
|
27
|
+
|
28
|
+
For more examples, see the examples directory in the distribution.
|
29
|
+
|
30
|
+
## Copyright
|
31
|
+
|
32
|
+
ruby-minisat is covered under the MIT License.
|
33
|
+
This package includes MiniSat in the directory `minisat` which is also
|
34
|
+
distributed under the MIT License. See `minisat/minisat/LICENSE`.
|
35
|
+
|
36
|
+
## Contributing
|
37
|
+
|
38
|
+
1. Fork it
|
39
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
40
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
41
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
42
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1,48 +1 @@
|
|
1
|
-
require
|
2
|
-
require 'rake'
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'jeweler'
|
6
|
-
jeweler_tasks = Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name = "ruby-minisat"
|
8
|
-
gem.summary = %Q{ruby binding for MiniSat, which is an open-source SAT solver}
|
9
|
-
gem.description = gem.summary
|
10
|
-
gem.email = "mame@tsg.ne.jp"
|
11
|
-
gem.homepage = "http://github.com/mame/ruby-minisat"
|
12
|
-
gem.authors = ["Yusuke Endoh"]
|
13
|
-
gem.extensions = FileList['ext/**/extconf.rb']
|
14
|
-
gem.files.include FileList['ext/**/*', 'minisat/**/*/**']
|
15
|
-
end
|
16
|
-
Jeweler::GemcutterTasks.new
|
17
|
-
rescue LoadError
|
18
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
-
end
|
20
|
-
|
21
|
-
require 'rake/testtask'
|
22
|
-
Rake::TestTask.new(:test) do |test|
|
23
|
-
test.libs << 'lib' << 'test'
|
24
|
-
test.pattern = 'test/**/test_*.rb'
|
25
|
-
test.verbose = true
|
26
|
-
end
|
27
|
-
|
28
|
-
task :test => :check_dependencies
|
29
|
-
|
30
|
-
task :default => :test
|
31
|
-
|
32
|
-
require 'rake/rdoctask'
|
33
|
-
Rake::RDocTask.new do |rdoc|
|
34
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
35
|
-
|
36
|
-
rdoc.rdoc_dir = 'rdoc'
|
37
|
-
rdoc.title = "ruby-minisat #{version}"
|
38
|
-
rdoc.rdoc_files.include('README*')
|
39
|
-
rdoc.rdoc_files.include('ext/**/*.c')
|
40
|
-
end
|
41
|
-
|
42
|
-
begin
|
43
|
-
require 'rake/extensiontask'
|
44
|
-
require 'rake/extensiontesttask'
|
45
|
-
|
46
|
-
Rake::ExtensionTask.new('minisat', jeweler_tasks.gemspec)
|
47
|
-
rescue LoadError
|
48
|
-
end
|
1
|
+
require "bundler/gem_tasks"
|
data/examples/shikaku.rb
CHANGED
@@ -122,11 +122,11 @@ def output_field(solution, field)
|
|
122
122
|
line.each_with_index do |c, x|
|
123
123
|
ary[y * 2 + 1][x * 2 + 1] = c ? c.to_s.rjust(2) : " ."
|
124
124
|
|
125
|
-
if x == 0 || solution[x - 1]
|
125
|
+
if x == 0 || solution[y][x - 1] != solution[y][x]
|
126
126
|
ary[y * 2 + 1][x * 2] = " |"
|
127
127
|
end
|
128
128
|
ary[y * 2 + 1][x * 2 + 2] = " |" if x == w - 1
|
129
|
-
if y == 0 || solution[
|
129
|
+
if y == 0 || solution[y - 1][x] != solution[y][x]
|
130
130
|
ary[y * 2][x * 2 + 1] = "--"
|
131
131
|
end
|
132
132
|
ary[y * 2 + 2][x * 2 + 1] = "--" if y == h - 1
|
data/ext/minisat/extconf.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
3
|
CONFIG["CXX"] ||= "g++"
|
4
|
-
MINISAT_DIR = File.join(File.dirname(__FILE__), "../../minisat/MiniSat_v1.14")
|
5
4
|
|
6
|
-
|
7
|
-
|
5
|
+
system_minisat = have_library("minisat")
|
6
|
+
if system_minisat
|
7
|
+
# dirty hack for mkmf
|
8
|
+
with_cflags("-x c++") do
|
9
|
+
system_minisat &&= have_header("minisat/core/Solver.h")
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
$defs << "-D __STDC_LIMIT_MACROS" << "-D __STDC_FORMAT_MACROS"
|
8
14
|
|
9
|
-
|
15
|
+
unless system_minisat
|
16
|
+
# use bundled minisat
|
17
|
+
MINISAT_DIR = File.join(File.dirname(__FILE__), "../../minisat/minisat/")
|
18
|
+
|
19
|
+
minisat_include, _ = dir_config("minisat", MINISAT_DIR, "")
|
20
|
+
$objs = ["minisat.o", "minisat-wrap.o", minisat_include + "core/Solver.o"]
|
21
|
+
end
|
22
|
+
|
23
|
+
raise unless have_library("stdc++")
|
24
|
+
create_makefile("minisat")
|
@@ -29,17 +29,23 @@ THE SOFTWARE.
|
|
29
29
|
******************************************************************************/
|
30
30
|
|
31
31
|
|
32
|
-
#
|
32
|
+
#ifdef HAVE_MINISAT_CORE_SOLVER_H
|
33
|
+
#include "minisat/core/Solver.h"
|
34
|
+
#else
|
35
|
+
#include "core/Solver.h"
|
36
|
+
#endif
|
33
37
|
#include "minisat.h"
|
34
38
|
|
39
|
+
using namespace Minisat;
|
40
|
+
|
35
41
|
/***** variable **************************************************************/
|
36
42
|
|
37
43
|
extern "C" int wrap_lit_pos_var(int v) {
|
38
|
-
return
|
44
|
+
return toInt(mkLit(v, false));
|
39
45
|
}
|
40
46
|
|
41
47
|
extern "C" int wrap_lit_neg_var(int v) {
|
42
|
-
return
|
48
|
+
return toInt(mkLit(v, true));
|
43
49
|
}
|
44
50
|
|
45
51
|
/***** solver ****************************************************************/
|
@@ -74,8 +80,8 @@ extern "C" int wrap_solver_solve(wrap_solver slv, int *lits, int len) {
|
|
74
80
|
return ((Solver*) slv)->solve(lit_vec) ? 1 : 0;
|
75
81
|
}
|
76
82
|
|
77
|
-
extern "C" int
|
78
|
-
((Solver*) slv)->
|
83
|
+
extern "C" int wrap_solver_simplify(wrap_solver slv) {
|
84
|
+
((Solver*) slv)->simplify();
|
79
85
|
return ((Solver*) slv)->okay() ? 1 : 0;
|
80
86
|
}
|
81
87
|
|
data/ext/minisat/minisat.c
CHANGED
@@ -339,20 +339,21 @@ static VALUE solver_solve(int argc, VALUE *argv, VALUE rslv)
|
|
339
339
|
|
340
340
|
/*
|
341
341
|
* call-seq:
|
342
|
-
* solver.
|
342
|
+
* solver.simplify -> true or false
|
343
343
|
*
|
344
344
|
* Detects conflicts independent of the assumptions. This is useful when the
|
345
345
|
* same SAT is solved many times under some different assumptions.
|
346
|
+
* Solver#simplify_db is deprecated.
|
346
347
|
*
|
347
348
|
*/
|
348
|
-
static VALUE
|
349
|
+
static VALUE solver_simplify(VALUE rslv)
|
349
350
|
{
|
350
351
|
csolver *cslv;
|
351
352
|
|
352
353
|
Data_Get_Struct(rslv, csolver, cslv);
|
353
354
|
|
354
355
|
check_model_available(cslv->result, 0);
|
355
|
-
if(!
|
356
|
+
if(!wrap_solver_simplify(cslv->solver)) {
|
356
357
|
cslv->result = UNSATISFIABLE;
|
357
358
|
return Qfalse;
|
358
359
|
}
|
@@ -360,6 +361,18 @@ static VALUE solver_simplify_db(VALUE rslv)
|
|
360
361
|
return Qtrue;
|
361
362
|
}
|
362
363
|
|
364
|
+
/*
|
365
|
+
* call-seq:
|
366
|
+
* solver.simplify_db -> true or false
|
367
|
+
*
|
368
|
+
* Deprecated. The same as Solver#simplify.
|
369
|
+
*
|
370
|
+
*/
|
371
|
+
static VALUE solver_simplify_db(VALUE rslv)
|
372
|
+
{
|
373
|
+
return solver_simplify(rslv);
|
374
|
+
}
|
375
|
+
|
363
376
|
/*
|
364
377
|
* call-seq:
|
365
378
|
* solver.var_size -> integer
|
@@ -479,6 +492,7 @@ void Init_minisat()
|
|
479
492
|
rb_define_method(rb_cSolver, "<<", solver_add_clause_2, 1);
|
480
493
|
rb_define_method(rb_cSolver, "[]", solver_ref_var, 1);
|
481
494
|
rb_define_method(rb_cSolver, "solve", solver_solve, -1);
|
495
|
+
rb_define_method(rb_cSolver, "simplify", solver_simplify, 0);
|
482
496
|
rb_define_method(rb_cSolver, "simplify_db", solver_simplify_db, 0);
|
483
497
|
rb_define_method(rb_cSolver, "var_size", solver_var_size, 0);
|
484
498
|
rb_define_method(rb_cSolver, "clause_size", solver_clause_size, 0);
|
data/ext/minisat/minisat.h
CHANGED
@@ -44,7 +44,7 @@ extern int wrap_solver_new_var(wrap_solver slv);
|
|
44
44
|
extern int wrap_solver_add_clause(wrap_solver slv, int *lits, int len);
|
45
45
|
extern int wrap_solver_ref_var(wrap_solver slv, int var);
|
46
46
|
extern int wrap_solver_solve(wrap_solver slv, int *lits, int len);
|
47
|
-
extern int
|
47
|
+
extern int wrap_solver_simplify(wrap_solver slv);
|
48
48
|
extern int wrap_solver_var_size(wrap_solver slv);
|
49
49
|
extern int wrap_solver_clause_size(wrap_solver slv);
|
50
50
|
|
Binary file
|
@@ -1,4 +1,5 @@
|
|
1
|
-
MiniSat -- Copyright (c) 2003-
|
1
|
+
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
2
|
+
Copyright (c) 2007-2010 Niklas Sorensson
|
2
3
|
|
3
4
|
Permission is hereby granted, free of charge, to any person obtaining a
|
4
5
|
copy of this software and associated documentation files (the
|
@@ -0,0 +1,24 @@
|
|
1
|
+
================================================================================
|
2
|
+
DIRECTORY OVERVIEW:
|
3
|
+
|
4
|
+
mtl/ Mini Template Library
|
5
|
+
utils/ Generic helper code (I/O, Parsing, CPU-time, etc)
|
6
|
+
core/ A core version of the solver
|
7
|
+
simp/ An extended solver with simplification capabilities
|
8
|
+
README
|
9
|
+
LICENSE
|
10
|
+
|
11
|
+
================================================================================
|
12
|
+
BUILDING: (release version: without assertions, statically linked, etc)
|
13
|
+
|
14
|
+
export MROOT=<minisat-dir> (or setenv in cshell)
|
15
|
+
cd { core | simp }
|
16
|
+
gmake rs
|
17
|
+
cp minisat_static <install-dir>/minisat
|
18
|
+
|
19
|
+
================================================================================
|
20
|
+
EXAMPLES:
|
21
|
+
|
22
|
+
Run minisat with same heuristics as version 2.0:
|
23
|
+
|
24
|
+
> minisat <cnf-file> -no-luby -rinc=1.5 -phase-saving=0 -rnd-freq=0.02
|
@@ -0,0 +1,89 @@
|
|
1
|
+
/****************************************************************************************[Dimacs.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_Dimacs_h
|
22
|
+
#define Minisat_Dimacs_h
|
23
|
+
|
24
|
+
#include <stdio.h>
|
25
|
+
|
26
|
+
#include "utils/ParseUtils.h"
|
27
|
+
#include "core/SolverTypes.h"
|
28
|
+
|
29
|
+
namespace Minisat {
|
30
|
+
|
31
|
+
//=================================================================================================
|
32
|
+
// DIMACS Parser:
|
33
|
+
|
34
|
+
template<class B, class Solver>
|
35
|
+
static void readClause(B& in, Solver& S, vec<Lit>& lits) {
|
36
|
+
int parsed_lit, var;
|
37
|
+
lits.clear();
|
38
|
+
for (;;){
|
39
|
+
parsed_lit = parseInt(in);
|
40
|
+
if (parsed_lit == 0) break;
|
41
|
+
var = abs(parsed_lit)-1;
|
42
|
+
while (var >= S.nVars()) S.newVar();
|
43
|
+
lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) );
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
template<class B, class Solver>
|
48
|
+
static void parse_DIMACS_main(B& in, Solver& S) {
|
49
|
+
vec<Lit> lits;
|
50
|
+
int vars = 0;
|
51
|
+
int clauses = 0;
|
52
|
+
int cnt = 0;
|
53
|
+
for (;;){
|
54
|
+
skipWhitespace(in);
|
55
|
+
if (*in == EOF) break;
|
56
|
+
else if (*in == 'p'){
|
57
|
+
if (eagerMatch(in, "p cnf")){
|
58
|
+
vars = parseInt(in);
|
59
|
+
clauses = parseInt(in);
|
60
|
+
// SATRACE'06 hack
|
61
|
+
// if (clauses > 4000000)
|
62
|
+
// S.eliminate(true);
|
63
|
+
}else{
|
64
|
+
printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
|
65
|
+
}
|
66
|
+
} else if (*in == 'c' || *in == 'p')
|
67
|
+
skipLine(in);
|
68
|
+
else{
|
69
|
+
cnt++;
|
70
|
+
readClause(in, S, lits);
|
71
|
+
S.addClause_(lits); }
|
72
|
+
}
|
73
|
+
if (vars != S.nVars())
|
74
|
+
fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of variables.\n");
|
75
|
+
if (cnt != clauses)
|
76
|
+
fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of clauses.\n");
|
77
|
+
}
|
78
|
+
|
79
|
+
// Inserts problem into solver.
|
80
|
+
//
|
81
|
+
template<class Solver>
|
82
|
+
static void parse_DIMACS(gzFile input_stream, Solver& S) {
|
83
|
+
StreamBuffer in(input_stream);
|
84
|
+
parse_DIMACS_main(in, S); }
|
85
|
+
|
86
|
+
//=================================================================================================
|
87
|
+
}
|
88
|
+
|
89
|
+
#endif
|
@@ -0,0 +1,192 @@
|
|
1
|
+
/*****************************************************************************************[Main.cc]
|
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
|
+
#include <errno.h>
|
22
|
+
|
23
|
+
#include <signal.h>
|
24
|
+
#include <zlib.h>
|
25
|
+
|
26
|
+
#include "utils/System.h"
|
27
|
+
#include "utils/ParseUtils.h"
|
28
|
+
#include "utils/Options.h"
|
29
|
+
#include "core/Dimacs.h"
|
30
|
+
#include "core/Solver.h"
|
31
|
+
|
32
|
+
using namespace Minisat;
|
33
|
+
|
34
|
+
//=================================================================================================
|
35
|
+
|
36
|
+
|
37
|
+
void printStats(Solver& solver)
|
38
|
+
{
|
39
|
+
double cpu_time = cpuTime();
|
40
|
+
double mem_used = memUsedPeak();
|
41
|
+
printf("restarts : %"PRIu64"\n", solver.starts);
|
42
|
+
printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time);
|
43
|
+
printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time);
|
44
|
+
printf("propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time);
|
45
|
+
printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals);
|
46
|
+
if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used);
|
47
|
+
printf("CPU time : %g s\n", cpu_time);
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
static Solver* solver;
|
52
|
+
// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case
|
53
|
+
// for this feature of the Solver as it may take longer than an immediate call to '_exit()'.
|
54
|
+
static void SIGINT_interrupt(int signum) { solver->interrupt(); }
|
55
|
+
|
56
|
+
// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls
|
57
|
+
// destructors and may cause deadlocks if a malloc/free function happens to be running (these
|
58
|
+
// functions are guarded by locks for multithreaded use).
|
59
|
+
static void SIGINT_exit(int signum) {
|
60
|
+
printf("\n"); printf("*** INTERRUPTED ***\n");
|
61
|
+
if (solver->verbosity > 0){
|
62
|
+
printStats(*solver);
|
63
|
+
printf("\n"); printf("*** INTERRUPTED ***\n"); }
|
64
|
+
_exit(1); }
|
65
|
+
|
66
|
+
|
67
|
+
//=================================================================================================
|
68
|
+
// Main:
|
69
|
+
|
70
|
+
|
71
|
+
int main(int argc, char** argv)
|
72
|
+
{
|
73
|
+
try {
|
74
|
+
setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n where input may be either in plain or gzipped DIMACS.\n");
|
75
|
+
// printf("This is MiniSat 2.0 beta\n");
|
76
|
+
|
77
|
+
#if defined(__linux__)
|
78
|
+
fpu_control_t oldcw, newcw;
|
79
|
+
_FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
|
80
|
+
printf("WARNING: for repeatability, setting FPU to use double precision\n");
|
81
|
+
#endif
|
82
|
+
// Extra options:
|
83
|
+
//
|
84
|
+
IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2));
|
85
|
+
IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
86
|
+
IntOption mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
87
|
+
|
88
|
+
parseOptions(argc, argv, true);
|
89
|
+
|
90
|
+
Solver S;
|
91
|
+
double initial_time = cpuTime();
|
92
|
+
|
93
|
+
S.verbosity = verb;
|
94
|
+
|
95
|
+
solver = &S;
|
96
|
+
// Use signal handlers that forcibly quit until the solver will be able to respond to
|
97
|
+
// interrupts:
|
98
|
+
signal(SIGINT, SIGINT_exit);
|
99
|
+
signal(SIGXCPU,SIGINT_exit);
|
100
|
+
|
101
|
+
// Set limit on CPU-time:
|
102
|
+
if (cpu_lim != INT32_MAX){
|
103
|
+
rlimit rl;
|
104
|
+
getrlimit(RLIMIT_CPU, &rl);
|
105
|
+
if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){
|
106
|
+
rl.rlim_cur = cpu_lim;
|
107
|
+
if (setrlimit(RLIMIT_CPU, &rl) == -1)
|
108
|
+
printf("WARNING! Could not set resource limit: CPU-time.\n");
|
109
|
+
} }
|
110
|
+
|
111
|
+
// Set limit on virtual memory:
|
112
|
+
if (mem_lim != INT32_MAX){
|
113
|
+
rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024;
|
114
|
+
rlimit rl;
|
115
|
+
getrlimit(RLIMIT_AS, &rl);
|
116
|
+
if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){
|
117
|
+
rl.rlim_cur = new_mem_lim;
|
118
|
+
if (setrlimit(RLIMIT_AS, &rl) == -1)
|
119
|
+
printf("WARNING! Could not set resource limit: Virtual memory.\n");
|
120
|
+
} }
|
121
|
+
|
122
|
+
if (argc == 1)
|
123
|
+
printf("Reading from standard input... Use '--help' for help.\n");
|
124
|
+
|
125
|
+
gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
|
126
|
+
if (in == NULL)
|
127
|
+
printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]), exit(1);
|
128
|
+
|
129
|
+
if (S.verbosity > 0){
|
130
|
+
printf("============================[ Problem Statistics ]=============================\n");
|
131
|
+
printf("| |\n"); }
|
132
|
+
|
133
|
+
parse_DIMACS(in, S);
|
134
|
+
gzclose(in);
|
135
|
+
FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;
|
136
|
+
|
137
|
+
if (S.verbosity > 0){
|
138
|
+
printf("| Number of variables: %12d |\n", S.nVars());
|
139
|
+
printf("| Number of clauses: %12d |\n", S.nClauses()); }
|
140
|
+
|
141
|
+
double parsed_time = cpuTime();
|
142
|
+
if (S.verbosity > 0){
|
143
|
+
printf("| Parse time: %12.2f s |\n", parsed_time - initial_time);
|
144
|
+
printf("| |\n"); }
|
145
|
+
|
146
|
+
// Change to signal-handlers that will only notify the solver and allow it to terminate
|
147
|
+
// voluntarily:
|
148
|
+
signal(SIGINT, SIGINT_interrupt);
|
149
|
+
signal(SIGXCPU,SIGINT_interrupt);
|
150
|
+
|
151
|
+
if (!S.simplify()){
|
152
|
+
if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res);
|
153
|
+
if (S.verbosity > 0){
|
154
|
+
printf("===============================================================================\n");
|
155
|
+
printf("Solved by unit propagation\n");
|
156
|
+
printStats(S);
|
157
|
+
printf("\n"); }
|
158
|
+
printf("UNSATISFIABLE\n");
|
159
|
+
exit(20);
|
160
|
+
}
|
161
|
+
|
162
|
+
vec<Lit> dummy;
|
163
|
+
lbool ret = S.solveLimited(dummy);
|
164
|
+
if (S.verbosity > 0){
|
165
|
+
printStats(S);
|
166
|
+
printf("\n"); }
|
167
|
+
printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n");
|
168
|
+
if (res != NULL){
|
169
|
+
if (ret == l_True){
|
170
|
+
fprintf(res, "SAT\n");
|
171
|
+
for (int i = 0; i < S.nVars(); i++)
|
172
|
+
if (S.model[i] != l_Undef)
|
173
|
+
fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
|
174
|
+
fprintf(res, " 0\n");
|
175
|
+
}else if (ret == l_False)
|
176
|
+
fprintf(res, "UNSAT\n");
|
177
|
+
else
|
178
|
+
fprintf(res, "INDET\n");
|
179
|
+
fclose(res);
|
180
|
+
}
|
181
|
+
|
182
|
+
#ifdef NDEBUG
|
183
|
+
exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver')
|
184
|
+
#else
|
185
|
+
return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
|
186
|
+
#endif
|
187
|
+
} catch (OutOfMemoryException&){
|
188
|
+
printf("===============================================================================\n");
|
189
|
+
printf("INDETERMINATE\n");
|
190
|
+
exit(0);
|
191
|
+
}
|
192
|
+
}
|