dpll_solver 0.0.1
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 -0
- data/.rspec +2 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +9 -0
- data/dpll_solver.gemspec +35 -0
- data/lib/dpll_solver.rb +115 -0
- data/lib/dpll_solver/atomic_formula.rb +34 -0
- data/lib/dpll_solver/formulas/and.rb +54 -0
- data/lib/dpll_solver/formulas/binary_formula.rb +33 -0
- data/lib/dpll_solver/formulas/clause.rb +52 -0
- data/lib/dpll_solver/formulas/falsum.rb +18 -0
- data/lib/dpll_solver/formulas/literal.rb +25 -0
- data/lib/dpll_solver/formulas/not.rb +84 -0
- data/lib/dpll_solver/formulas/or.rb +64 -0
- data/lib/dpll_solver/formulas/variable.rb +26 -0
- data/lib/dpll_solver/formulas/verum.rb +18 -0
- data/lib/dpll_solver/heuristics/most_frequent_literal.rb +22 -0
- data/lib/dpll_solver/parsers/dimacs_parser.rb +46 -0
- data/lib/dpll_solver/parsers/parser.rb +53 -0
- data/lib/dpll_solver/version.rb +3 -0
- data/spec/dpll/dpll_solver_spec.rb +114 -0
- data/spec/formulas/and_spec.rb +75 -0
- data/spec/formulas/clause_spec.rb +55 -0
- data/spec/formulas/falsum_spec.rb +42 -0
- data/spec/formulas/formulas_spec.rb +47 -0
- data/spec/formulas/literal_spec.rb +26 -0
- data/spec/formulas/not_spec.rb +77 -0
- data/spec/formulas/or_spec.rb +74 -0
- data/spec/formulas/variable_spec.rb +44 -0
- data/spec/formulas/verum_spec.rb +42 -0
- data/spec/heuristics/most_frequent_literal_spec.rb +19 -0
- data/spec/parsers/dimacs_parser_spec.rb +23 -0
- data/spec/parsers/grammar_spec.rb +54 -0
- data/spec/parsers/parser_spec.rb +23 -0
- data/spec/parsers/transformer_spec.rb +30 -0
- data/spec/spec_helper.rb +4 -0
- metadata +183 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DpllSolver::Formulas::Verum do
|
4
|
+
let(:verum) { DpllSolver::Formulas::Verum }
|
5
|
+
it 'should be "1" as string' do
|
6
|
+
expect(verum.to_s).to eql "1"
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should test syntactic eqivalenz' do
|
10
|
+
expect(verum == DpllSolver::Formulas::Verum).to eql true
|
11
|
+
expect(verum == DpllSolver::Formulas).to eql false
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be a literal' do
|
15
|
+
expect(verum.literal?).to eql true
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should be a atomic formula' do
|
19
|
+
expect(verum.atomic_formula?).to eql true
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should be a min term' do
|
23
|
+
expect(verum.min_term?).to eql true
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should be a nnf' do
|
27
|
+
expect(verum.nnf?).to eql true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should be a cnf' do
|
31
|
+
expect(verum.cnf?).to eql true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should be a dnf' do
|
35
|
+
expect(verum.dnf?).to eql true
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should simplify verum' do
|
39
|
+
expect(verum.simplify).to eql verum
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DpllSolver::Heuristics::MostFrequentLiteral do
|
4
|
+
let(:var1) { DpllSolver::Formulas::Variable.new("x1") }
|
5
|
+
let(:var2) { DpllSolver::Formulas::Variable.new("x2") }
|
6
|
+
let(:lit1) { DpllSolver::Formulas::Literal.new(var1, true)}
|
7
|
+
let(:n_lit1) { DpllSolver::Formulas::Literal.new(var1, false)}
|
8
|
+
let(:lit2) { DpllSolver::Formulas::Literal.new(var2, true)}
|
9
|
+
let(:c1) { Set.new([DpllSolver::Formulas::Clause.new(lit1, lit2), DpllSolver::Formulas::Clause.new(lit1)])}
|
10
|
+
let(:c2) { Set.new([DpllSolver::Formulas::Clause.new(lit1, lit2), DpllSolver::Formulas::Clause.new(n_lit1)])}
|
11
|
+
let(:c3) { Set.new([DpllSolver::Formulas::Clause.new(n_lit1, lit2), DpllSolver::Formulas::Clause.new(n_lit1)])}
|
12
|
+
|
13
|
+
it 'should return the most frequent literal in clause set' do
|
14
|
+
expect{ DpllSolver::Heuristics::MostFrequentLiteral.choose_literal(Set.new)}.to raise_error
|
15
|
+
expect(DpllSolver::Heuristics::MostFrequentLiteral.choose_literal(c1)).to eql lit1
|
16
|
+
expect{ DpllSolver::Heuristics::MostFrequentLiteral.choose_literal(c2)}.not_to raise_error
|
17
|
+
expect(DpllSolver::Heuristics::MostFrequentLiteral.choose_literal(c3)).to eql n_lit1
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DpllSolver::Parsers::DimacsParser do
|
4
|
+
let(:f1) { "resources/dimacs/yes/aim-50-1_6-yes1-1.cnf" }
|
5
|
+
let(:f2) { "resources/dimacs/no/aim-50-1_6-no-1.cnf" }
|
6
|
+
let(:f3) { "resources/dimacs/yes/aim-50-6_0-yes1-4.cnf" }
|
7
|
+
|
8
|
+
it 'should parse files in DIMACS format' do
|
9
|
+
parser = DpllSolver::Parsers::DimacsParser.new(f1)
|
10
|
+
expect(parser.num_vars).to eql 50
|
11
|
+
expect(parser.num_clauses).to eql 80
|
12
|
+
expect(parser.clauseset.count).to eql 80
|
13
|
+
parser = DpllSolver::Parsers::DimacsParser.new(f2)
|
14
|
+
expect(parser.num_vars).to eql 50
|
15
|
+
expect(parser.num_clauses).to eql 80
|
16
|
+
expect(parser.clauseset.count).to eql 80
|
17
|
+
parser = DpllSolver::Parsers::DimacsParser.new(f3)
|
18
|
+
expect(parser.num_vars).to eql 50
|
19
|
+
expect(parser.num_clauses).to eql 300
|
20
|
+
expect(parser.clauseset.count).to eql 300
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parslet/rig/rspec'
|
3
|
+
|
4
|
+
describe DpllSolver::Parsers::Grammar do
|
5
|
+
let(:g){ DpllSolver::Parsers::Grammar.new }
|
6
|
+
|
7
|
+
describe '#verum' do
|
8
|
+
let(:verum){ g.verum }
|
9
|
+
it 'should parse verum' do
|
10
|
+
verum.should parse('T')
|
11
|
+
verum.should parse('1')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
describe '#falsum' do
|
15
|
+
let(:falsum){ g.falsum }
|
16
|
+
it 'should parse falsum' do
|
17
|
+
falsum.should parse('F')
|
18
|
+
falsum.should parse('0')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
describe '#variable' do
|
22
|
+
let(:var){ g.variable }
|
23
|
+
it 'should parse variable' do
|
24
|
+
var.should parse('x')
|
25
|
+
var.should parse('x1')
|
26
|
+
var.should parse('x12')
|
27
|
+
var.should_not parse('xy')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
describe '#not' do
|
31
|
+
let(:not_op){ g.not_operation }
|
32
|
+
it 'should parse not_operation' do
|
33
|
+
not_op.should parse('-x')
|
34
|
+
not_op.should parse('-(x+y)')
|
35
|
+
not_op.should parse('--x')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
describe '#or' do
|
39
|
+
let(:or_op){ g.or_operation }
|
40
|
+
it 'should parse or_operation' do
|
41
|
+
or_op.should parse('(x + y)')
|
42
|
+
or_op.should parse('(x | y)')
|
43
|
+
or_op.should parse('(x OR y)')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
describe '#and' do
|
47
|
+
let(:and_op){ g.and_operation }
|
48
|
+
it 'should parse and_operation' do
|
49
|
+
and_op.should parse('(x * y)')
|
50
|
+
and_op.should parse('(x & y)')
|
51
|
+
and_op.should parse('(x AND y)')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DpllSolver::Parsers::Parser do
|
4
|
+
let(:falsum) { DpllSolver::Formulas::Falsum }
|
5
|
+
let(:verum) { DpllSolver::Formulas::Verum }
|
6
|
+
let(:var1) { DpllSolver::Formulas::Variable.new("x1") }
|
7
|
+
let(:var2) { DpllSolver::Formulas::Variable.new("x2") }
|
8
|
+
let(:f) { DpllSolver::Formulas::Not.new(var2) }
|
9
|
+
let(:f1) { DpllSolver::Formulas::Not.new(DpllSolver::Formulas::And.new(var1, falsum)) }
|
10
|
+
let(:f2) { DpllSolver::Formulas::Not.new(DpllSolver::Formulas::Or.new(DpllSolver::Formulas::And.new(var1, var2), DpllSolver::Formulas::Not.new(DpllSolver::Formulas::Or.new(falsum, var2)))) }
|
11
|
+
let(:f3) { DpllSolver::Formulas::Or.new(DpllSolver::Formulas::Not.new(DpllSolver::Formulas::Or.new(DpllSolver::Formulas::And.new(var1, falsum), var2)), verum) }
|
12
|
+
|
13
|
+
it 'should convert a formula to a set of clauses' do
|
14
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(falsum).map(&:to_s).join).to eql "{}"
|
15
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(verum).empty?).to eql true
|
16
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(var1).map(&:to_s).join).to eql "{x1}"
|
17
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(f).map(&:to_s).join).to eql "{-x2}"
|
18
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(f1).empty?).to eql true
|
19
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(f2).map(&:to_s).join).to match "{-x1, -x2}"
|
20
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(f2).map(&:to_s).join).to match "{x2}"
|
21
|
+
expect(DpllSolver::Parsers::Parser.formula_to_clause(f3).empty?).to eql true
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DpllSolver::Parsers::Transformer do
|
4
|
+
let(:g){ DpllSolver::Parsers::Grammar.new }
|
5
|
+
let(:trans){ DpllSolver::Parsers::Transformer.new }
|
6
|
+
|
7
|
+
it 'should transform literals' do
|
8
|
+
verum = g.parse('T')
|
9
|
+
falsum = g.parse('F')
|
10
|
+
var = g.parse('x1')
|
11
|
+
expect(trans.apply(verum)).to eql DpllSolver::Formulas::Verum
|
12
|
+
expect(trans.apply(falsum)).to eql DpllSolver::Formulas::Falsum
|
13
|
+
expect(trans.apply(var)).to eql DpllSolver::Formulas::Variable.new('x1')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should transform functions' do
|
17
|
+
not_op = g.parse('-z')
|
18
|
+
or_op = g.parse('(x OR y)')
|
19
|
+
and_op = g.parse('(x AND y)')
|
20
|
+
expect(trans.apply(not_op)).to eql DpllSolver::Formulas::Not.new(DpllSolver::Formulas::Variable.new('z'))
|
21
|
+
expect(trans.apply(or_op)).to eql DpllSolver::Formulas::Or.new(DpllSolver::Formulas::Variable.new('x'), DpllSolver::Formulas::Variable.new('y'))
|
22
|
+
expect(trans.apply(and_op)).to eql DpllSolver::Formulas::And.new(DpllSolver::Formulas::Variable.new('x'), DpllSolver::Formulas::Variable.new('y'))
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should transform nested functions' do
|
26
|
+
f = g.parse('-(a OR ((b OR -c) AND d))')
|
27
|
+
parsed = DpllSolver::Formulas::Not.new(DpllSolver::Formulas::Or.new(DpllSolver::Formulas::Variable.new('a'), DpllSolver::Formulas::And.new(DpllSolver::Formulas::Or.new(DpllSolver::Formulas::Variable.new('b'), DpllSolver::Formulas::Not.new(DpllSolver::Formulas::Variable.new('c'))), DpllSolver::Formulas::Variable.new('d'))))
|
28
|
+
expect(trans.apply(f)).to eql parsed
|
29
|
+
end
|
30
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dpll_solver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- thebluber
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: binding_of_caller
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: parslet
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: This is a small SAT solving tool for either DIMACS file input (max. 20
|
98
|
+
variables, 80 lines) or boolean expressions in string format i.e. '(x1 * (x3 + x4))'.
|
99
|
+
email:
|
100
|
+
- thebluber@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- .gitignore
|
106
|
+
- .rspec
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- dpll_solver.gemspec
|
112
|
+
- lib/dpll_solver.rb
|
113
|
+
- lib/dpll_solver/atomic_formula.rb
|
114
|
+
- lib/dpll_solver/formulas/and.rb
|
115
|
+
- lib/dpll_solver/formulas/binary_formula.rb
|
116
|
+
- lib/dpll_solver/formulas/clause.rb
|
117
|
+
- lib/dpll_solver/formulas/falsum.rb
|
118
|
+
- lib/dpll_solver/formulas/literal.rb
|
119
|
+
- lib/dpll_solver/formulas/not.rb
|
120
|
+
- lib/dpll_solver/formulas/or.rb
|
121
|
+
- lib/dpll_solver/formulas/variable.rb
|
122
|
+
- lib/dpll_solver/formulas/verum.rb
|
123
|
+
- lib/dpll_solver/heuristics/most_frequent_literal.rb
|
124
|
+
- lib/dpll_solver/parsers/dimacs_parser.rb
|
125
|
+
- lib/dpll_solver/parsers/parser.rb
|
126
|
+
- lib/dpll_solver/version.rb
|
127
|
+
- spec/dpll/dpll_solver_spec.rb
|
128
|
+
- spec/formulas/and_spec.rb
|
129
|
+
- spec/formulas/clause_spec.rb
|
130
|
+
- spec/formulas/falsum_spec.rb
|
131
|
+
- spec/formulas/formulas_spec.rb
|
132
|
+
- spec/formulas/literal_spec.rb
|
133
|
+
- spec/formulas/not_spec.rb
|
134
|
+
- spec/formulas/or_spec.rb
|
135
|
+
- spec/formulas/variable_spec.rb
|
136
|
+
- spec/formulas/verum_spec.rb
|
137
|
+
- spec/heuristics/most_frequent_literal_spec.rb
|
138
|
+
- spec/parsers/dimacs_parser_spec.rb
|
139
|
+
- spec/parsers/grammar_spec.rb
|
140
|
+
- spec/parsers/parser_spec.rb
|
141
|
+
- spec/parsers/transformer_spec.rb
|
142
|
+
- spec/spec_helper.rb
|
143
|
+
homepage: https://github.com/thebluber/dpll_solver
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata: {}
|
147
|
+
post_install_message:
|
148
|
+
rdoc_options: []
|
149
|
+
require_paths:
|
150
|
+
- lib
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - '>='
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - '>='
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
requirements: []
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 2.2.2
|
164
|
+
signing_key:
|
165
|
+
specification_version: 4
|
166
|
+
summary: SAT solver using DPLL algorithm
|
167
|
+
test_files:
|
168
|
+
- spec/dpll/dpll_solver_spec.rb
|
169
|
+
- spec/formulas/and_spec.rb
|
170
|
+
- spec/formulas/clause_spec.rb
|
171
|
+
- spec/formulas/falsum_spec.rb
|
172
|
+
- spec/formulas/formulas_spec.rb
|
173
|
+
- spec/formulas/literal_spec.rb
|
174
|
+
- spec/formulas/not_spec.rb
|
175
|
+
- spec/formulas/or_spec.rb
|
176
|
+
- spec/formulas/variable_spec.rb
|
177
|
+
- spec/formulas/verum_spec.rb
|
178
|
+
- spec/heuristics/most_frequent_literal_spec.rb
|
179
|
+
- spec/parsers/dimacs_parser_spec.rb
|
180
|
+
- spec/parsers/grammar_spec.rb
|
181
|
+
- spec/parsers/parser_spec.rb
|
182
|
+
- spec/parsers/transformer_spec.rb
|
183
|
+
- spec/spec_helper.rb
|