prop_logic-minisat 0.1.0 → 0.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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -0
- data/lib/prop_logic/minisat.rb +5 -51
- data/lib/prop_logic/minisat/incremental_solver.rb +100 -0
- data/lib/prop_logic/minisat/version.rb +1 -1
- data/prop_logic-minisat.gemspec +1 -1
- metadata +17 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df49bc6a7fe99cd4e8044c5144f665d70e9603bc
|
4
|
+
data.tar.gz: 2b5e486b052007bf599bce2d9ace0e16b4e75276
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09c64b2a20fa00c62e29090d5c25fb005b956839b64733986ecd0544d97d7f21b3a16ccf791a45bcf0da774e0465cc132147cd191bd672be4aab850121915bff
|
7
|
+
data.tar.gz: d945b3604d337a4a8f39a99c1fd88f98ce66cdd3a97ee6ac1b3fd21c15e6ecfb631dbd3f742fc1adbdeae6abe25119e137b3f2020ec2e7d9735989685a46ff0b
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
data/lib/prop_logic/minisat.rb
CHANGED
@@ -1,62 +1,16 @@
|
|
1
1
|
require 'prop_logic'
|
2
2
|
require 'minisat'
|
3
|
-
require
|
3
|
+
require 'prop_logic/minisat/version'
|
4
|
+
require 'prop_logic/minisat/incremental_solver'
|
4
5
|
|
5
6
|
module PropLogic
|
6
7
|
module Minisat
|
7
|
-
|
8
|
+
module Solver
|
8
9
|
def self.call(term)
|
9
|
-
new.sat?
|
10
|
+
IncrementalSolver.new(term).sat?
|
10
11
|
end
|
11
|
-
|
12
|
-
private_class_method :new
|
13
|
-
|
14
|
-
def initialize
|
15
|
-
@solver = ::MiniSat::Solver.new
|
16
|
-
end
|
17
|
-
|
18
|
-
def parse_variable_or_not(term)
|
19
|
-
if term.is_a?(Variable)
|
20
|
-
@variable_map[term]
|
21
|
-
else
|
22
|
-
-(@variable_map[term.terms[0]])
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def parse_or_term(term)
|
27
|
-
if term.is_a?(OrTerm)
|
28
|
-
@solver << term.terms.map{ |t| parse_variable_or_not(t) }
|
29
|
-
else
|
30
|
-
@solver << parse_variable_or_not(term)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def sat?(term)
|
35
|
-
cnf = term.to_cnf
|
36
|
-
orig_variables = term.variables
|
37
|
-
# no need to use SAT solver
|
38
|
-
return false if cnf == False
|
39
|
-
if cnf == True
|
40
|
-
return True if orig_variables.length == 0
|
41
|
-
return PropLogic.all_and(*orig_variables)
|
42
|
-
end
|
43
|
-
#prepare for solver
|
44
|
-
using_variables = cnf.variables
|
45
|
-
@variable_map = {}
|
46
|
-
using_variables.each{ |v| @variable_map[v] = @solver.new_var }
|
47
|
-
if cnf.is_a?(AndTerm)
|
48
|
-
cnf.terms.each{ |t| parse_or_term t}
|
49
|
-
else
|
50
|
-
parse_or_term term
|
51
|
-
end
|
52
|
-
return false unless @solver.solve
|
53
|
-
# return value generation
|
54
|
-
assign_variables = using_variables & orig_variables
|
55
|
-
extra_variables = orig_variables - assign_variables
|
56
|
-
PropLogic.all_and(*assign_variables.map{ |v| @solver[@variable_map[v]] ? v : -v }, *extra_variables)
|
57
|
-
end
|
58
|
-
|
59
12
|
end
|
60
13
|
end
|
61
14
|
PropLogic.sat_solver = Minisat::Solver
|
15
|
+
PropLogic.incremental_solver = Minisat::IncrementalSolver
|
62
16
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'prop_logic'
|
2
|
+
require 'minisat'
|
3
|
+
|
4
|
+
module PropLogic
|
5
|
+
module Minisat
|
6
|
+
#
|
7
|
+
# Incremental solver using minisat.
|
8
|
+
# @note currently only Ruby part is incremental.
|
9
|
+
#
|
10
|
+
class IncrementalSolver
|
11
|
+
# constructor.
|
12
|
+
# @param [Term] initial term for starting SAT solver.
|
13
|
+
def initialize(initial_term)
|
14
|
+
@solver = ::MiniSat::Solver.new
|
15
|
+
# automagically add variable in Hash
|
16
|
+
@variables_map = Hash.new { |h, k| h[k] = @solver.new_var }
|
17
|
+
@terms = []
|
18
|
+
@variables = []
|
19
|
+
# true if False was added
|
20
|
+
@contradicted = false
|
21
|
+
add initial_term
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Array] containing variables
|
25
|
+
def variables
|
26
|
+
@variables.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
def term
|
30
|
+
return False if @contradicted
|
31
|
+
return True if @terms.empty?
|
32
|
+
PropLogic.all_and(*@terms)
|
33
|
+
end
|
34
|
+
|
35
|
+
# add terms to this solver.
|
36
|
+
# @return [IncrementalSolver] returns self
|
37
|
+
def add(*terms)
|
38
|
+
terms.each { |term| add_one_term term }
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :<<, :add
|
43
|
+
|
44
|
+
# check if terms are satisfiable.
|
45
|
+
# @return [Term] term satisfying conditions.
|
46
|
+
# @return [false] if unsatisfied.
|
47
|
+
def sat?
|
48
|
+
return false if @contradicted
|
49
|
+
return True if variables.empty?
|
50
|
+
vars = []
|
51
|
+
unless @terms.empty?
|
52
|
+
return false unless @solver.solve
|
53
|
+
ret_vars = variables & @variables_map.keys
|
54
|
+
vars = ret_vars.map { |k| @solver[@variables_map[k]] ? k : ~k }
|
55
|
+
end
|
56
|
+
extra_vars = variables - @variables_map.keys
|
57
|
+
PropLogic.all_and(*vars, *extra_vars)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def sat_variable(maybe_inversed_variable)
|
63
|
+
case maybe_inversed_variable
|
64
|
+
when Variable
|
65
|
+
@variables_map[maybe_inversed_variable]
|
66
|
+
when NotTerm
|
67
|
+
-@variables_map[maybe_inversed_variable.terms[0]]
|
68
|
+
else
|
69
|
+
raise TypeError
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_or_term(term)
|
74
|
+
vars = if term.is_a?(OrTerm)
|
75
|
+
term.terms.map { |v| sat_variable v }
|
76
|
+
else
|
77
|
+
[sat_variable(term)]
|
78
|
+
end
|
79
|
+
@solver << vars
|
80
|
+
@terms << term
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_one_term(term)
|
84
|
+
@variables |= term.variables
|
85
|
+
term = term.to_cnf
|
86
|
+
return if term == True
|
87
|
+
if term == False
|
88
|
+
@contradicted = true
|
89
|
+
return
|
90
|
+
end
|
91
|
+
if term.is_a?(AndTerm)
|
92
|
+
term.terms.each { |t| add_or_term t }
|
93
|
+
else
|
94
|
+
add_or_term term
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/prop_logic-minisat.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "prop_logic", '>= 0.
|
21
|
+
spec.add_dependency "prop_logic", '>= 0.2.0'
|
22
22
|
spec.add_dependency "ruby-minisat", '>= 2.2.0'
|
23
23
|
spec.required_ruby_version = '>= 2.0.0'
|
24
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prop_logic-minisat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jkr2255
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prop_logic
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
20
22
|
version_requirements: !ruby/object:Gem::Requirement
|
21
23
|
requirements:
|
22
24
|
- - ">="
|
23
25
|
- !ruby/object:Gem::Version
|
24
|
-
version: 0.
|
25
|
-
prerelease: false
|
26
|
-
type: :runtime
|
26
|
+
version: 0.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ruby-minisat
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -31,13 +31,13 @@ dependencies:
|
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 2.2.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
34
36
|
version_requirements: !ruby/object:Gem::Requirement
|
35
37
|
requirements:
|
36
38
|
- - ">="
|
37
39
|
- !ruby/object:Gem::Version
|
38
40
|
version: 2.2.0
|
39
|
-
prerelease: false
|
40
|
-
type: :runtime
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,13 +45,13 @@ dependencies:
|
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.11'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
48
50
|
version_requirements: !ruby/object:Gem::Requirement
|
49
51
|
requirements:
|
50
52
|
- - "~>"
|
51
53
|
- !ruby/object:Gem::Version
|
52
54
|
version: '1.11'
|
53
|
-
prerelease: false
|
54
|
-
type: :development
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,13 +59,13 @@ dependencies:
|
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
62
64
|
version_requirements: !ruby/object:Gem::Requirement
|
63
65
|
requirements:
|
64
66
|
- - "~>"
|
65
67
|
- !ruby/object:Gem::Version
|
66
68
|
version: '10.0'
|
67
|
-
prerelease: false
|
68
|
-
type: :development
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,13 +73,13 @@ dependencies:
|
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
76
78
|
version_requirements: !ruby/object:Gem::Requirement
|
77
79
|
requirements:
|
78
80
|
- - "~>"
|
79
81
|
- !ruby/object:Gem::Version
|
80
82
|
version: '3.0'
|
81
|
-
prerelease: false
|
82
|
-
type: :development
|
83
83
|
description:
|
84
84
|
email:
|
85
85
|
- magnesium.oxide.play@gmail.com
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- ".gitignore"
|
91
91
|
- ".rspec"
|
92
92
|
- ".travis.yml"
|
93
|
+
- CHANGELOG.md
|
93
94
|
- Gemfile
|
94
95
|
- LICENSE.txt
|
95
96
|
- README.md
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- bin/console
|
98
99
|
- bin/setup
|
99
100
|
- lib/prop_logic/minisat.rb
|
101
|
+
- lib/prop_logic/minisat/incremental_solver.rb
|
100
102
|
- lib/prop_logic/minisat/version.rb
|
101
103
|
- prop_logic-minisat.gemspec
|
102
104
|
homepage: https://github.com/jkr2255/prop_logic-minisat
|
@@ -119,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
121
|
version: '0'
|
120
122
|
requirements: []
|
121
123
|
rubyforge_project:
|
122
|
-
rubygems_version: 2.5.1
|
124
|
+
rubygems_version: 2.4.5.1
|
123
125
|
signing_key:
|
124
126
|
specification_version: 4
|
125
127
|
summary: Minisat binding for PropLogic
|