prop_logic 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ed096886dc984eabcd875c578b78a074b5c8b90
4
- data.tar.gz: e449635063d3c36226d7efae7db50d0aaddc26be
3
+ metadata.gz: 4bf3b6daa1a3ae0949907abf3a4ea6e5410c214f
4
+ data.tar.gz: 851df2ca76ce16d822389c1e6d6842c6f36863fe
5
5
  SHA512:
6
- metadata.gz: 8635b171e757d2e5bde2f2e16cf37baae110780dedaec0d76b703ae5c5c7189ca3095e45d8d4f31db3d4feb957c6bb990c38a782ad633544623b7f2e4e8067f6
7
- data.tar.gz: 66febccd6887ec890e1e56aca6d6929c13381843d2953fc32b30233f0ac528ac9940482cb7eb08dfba5108c01016963d8198fb42a340de31476c40f31ccefa94
6
+ metadata.gz: 8c2079a701b5827e330b06c662a2a12a3620f68da7519604bc90db2448ac78ac8772df48b4671c83eb98273be3be5f8e1aeeb890dadce449f285026db31bd754
7
+ data.tar.gz: 1cd28c2060c5898327889adfb6cf28a268cd6101f60f5030c5abdc37aff699579b7f87977278c7bb70951b94b6261db79a4fe9e866a2cb52758ae2b4699beae5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # Ver. 0.2.0 (2016/03/13)
2
+ - Add interface for incremental solver
3
+ - add `Term#each_sat`
4
+
1
5
  # Ver. 0.1.3 (2016/03/11)
2
6
  - Code cleanup
3
7
  - save `PropLogic.sat_solver` to module instance variable (no interface change)
data/README.md CHANGED
@@ -112,6 +112,9 @@ CNF is one of these:
112
112
 
113
113
  `#unsat?` returns `true` if unsatisfiable, `false` otherwise.
114
114
 
115
+ #### SAT enumrator
116
+ `#each_sat` is an enumerator for all satifiabilities. Returns `Enumerator` if calling without block.
117
+
115
118
  ### `PropLogic` module methods
116
119
  #### `PropLogic.new_variable(name = nil)`
117
120
  declare new variable with name `name`. if `name` is not supplied, unique name is set.
@@ -124,6 +127,10 @@ calculate all and/or of `terms`. Use this when and/or calculation for many varia
124
127
  #### `PropLogic.sat_solver`/ PropLogic.sat_solver=`
125
128
  set/get SAT solver object. It shoud have `#call(term)` method and return value is described in `Term#sat?`.
126
129
 
130
+ #### `PropLogic.incremental_solver`/ PropLogic.incremental_solver=`
131
+ set/get incremental SAT solver object. It shoud be class with `#add` and `#sat?` methods.
132
+ (see `DefaultIncrementalSolver` for its interface)
133
+
127
134
  ### Information
128
135
  `PropLogic::Term` has some subclasses, but these classes are subject to change.
129
136
  Using subclasses of `PropLogic::Term` directly is not recommended.
@@ -0,0 +1,33 @@
1
+ module PropLogic
2
+ #
3
+ # Default implementation of incremental SAT solver.
4
+ # Provided for reference implementation and avoiding non-existent error.
5
+ # (Using normal solver, not incrementally)
6
+ #
7
+ class DefaultIncrementalSolver
8
+ # @param [Term] initial term
9
+ def initialize(term)
10
+ @term = term
11
+ end
12
+
13
+ # Current term
14
+ attr_reader :term
15
+
16
+ # Adding new terms to this solver.
17
+ # @param [Term] terms to add.
18
+ # @return [DefaultIncrementalSolver] self
19
+ def add(*terms)
20
+ @term = @term.and(*terms)
21
+ self
22
+ end
23
+
24
+ alias_method :<<, :add
25
+
26
+ # Check satisfiability of terms.
27
+ # @return [Term] if satisfied
28
+ # @return [false] if unsatisfied
29
+ def sat?
30
+ @term.sat?
31
+ end
32
+ end
33
+ end
@@ -1,16 +1,40 @@
1
1
  module PropLogic
2
+ #
3
+ # Utility methods for PropLogic.
4
+ #
2
5
  module Functions
6
+
3
7
  module_function
8
+
9
+ # Combine all terms with or.
10
+ # @param [Term] terms to combine
11
+ # @return [Term] combined term
4
12
  def all_or(*args)
5
13
  Term.get OrTerm, *args
6
14
  end
7
15
 
16
+ # Combine all terms with and.
17
+ # @param [Term] terms to combine
18
+ # @return [Term] combined term
8
19
  def all_and(*args)
9
20
  Term.get AndTerm, *args
10
21
  end
11
22
 
23
+ # Create new variable.
12
24
  def new_variable(*args)
13
- Variable.new *args
25
+ Variable.new(*args)
26
+ end
27
+
28
+ # loop while satisfiable.
29
+ # Note: Loop continues infinitely if no addition was given inside the loop.
30
+ # @yield [Term, IncrementalSolver] yield for each term.
31
+ def sat_loop(initial_term)
32
+ incremental = PropLogic.incremental_solver.new initial_term
33
+ loop do
34
+ sat = incremental.sat?
35
+ break unless sat
36
+ yield sat, incremental
37
+ end
14
38
  end
15
39
  end
16
40
 
@@ -20,7 +44,7 @@ module PropLogic
20
44
 
21
45
  def all_combination(arr)
22
46
  0.upto(arr.length) do |num|
23
- arr.combination(num){|c| yield c}
47
+ arr.combination(num) { |c| yield c }
24
48
  end
25
49
  end
26
50
 
@@ -3,6 +3,7 @@ module PropLogic
3
3
  # default SAT solver.
4
4
  # only intended for test use.
5
5
  @sat_solver = PropLogic::BruteForceSatSolver
6
+ @incremental_solver = PropLogic::DefaultIncrementalSolver
6
7
 
7
8
  class << self
8
9
  # @return [Object] current SAT solver
@@ -14,5 +15,9 @@ module PropLogic
14
15
  raise TypeError unless engine.respond_to?(:call)
15
16
  @sat_solver = engine
16
17
  end
18
+
19
+ # curreent incremental solver
20
+ attr_accessor :incremental_solver
21
+
17
22
  end
18
23
  end
@@ -2,13 +2,19 @@ require 'ref'
2
2
  require 'prop_logic/functions'
3
3
 
4
4
  module PropLogic
5
+ #
6
+ # Abstract base class for terms of PropLogic.
7
+ # Actual terms are subclasses of Term.
8
+ #
5
9
  class Term
6
10
  include Functions
7
11
 
12
+ # @raise NotImplementedError Term is abstract class.
8
13
  def initialize
9
14
  raise NotImplementedError, 'Term cannot be initialized'
10
15
  end
11
16
 
17
+ # disallow duplication
12
18
  def initialize_copy(*)
13
19
  raise TypeError, 'Term cannot be duplicated (immutable, not necessary)'
14
20
  end
@@ -112,10 +118,13 @@ module PropLogic
112
118
  ret.freeze
113
119
  end
114
120
 
121
+ # check if this term is a cnf term.
122
+ # @return [Boolean] false unless overridden.
115
123
  def cnf?
116
124
  false
117
125
  end
118
126
 
127
+ # @return [Array] variables used by this term.
119
128
  def variables
120
129
  @variables ||= @terms.map(&:variables).flatten.uniq
121
130
  end
@@ -146,6 +155,17 @@ module PropLogic
146
155
  PropLogic.sat_solver.call(self)
147
156
  end
148
157
 
158
+ # loop with each satisfied terms.
159
+ # @return [Enumerator] if block is not given.
160
+ # @return [nil] if block is given.
161
+ def each_sat
162
+ return to_enum(:each_sat) unless block_given?
163
+ sat_loop(self) do |sat, solver|
164
+ yield sat
165
+ solver << ~sat
166
+ end
167
+ end
168
+
149
169
  def unsat?
150
170
  sat? == false
151
171
  end
@@ -1,3 +1,3 @@
1
1
  module PropLogic
2
- VERSION = "0.1.3"
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/prop_logic.rb CHANGED
@@ -1,11 +1,12 @@
1
- require "prop_logic/version"
2
- require "prop_logic/term"
1
+ require 'prop_logic/version'
2
+ require 'prop_logic/term'
3
3
  require 'prop_logic/functions'
4
- require "prop_logic/and_term"
5
- require "prop_logic/or_term"
6
- require "prop_logic/not_term"
7
- require "prop_logic/then_term"
4
+ require 'prop_logic/and_term'
5
+ require 'prop_logic/or_term'
6
+ require 'prop_logic/not_term'
7
+ require 'prop_logic/then_term'
8
8
  require 'prop_logic/variable'
9
9
  require 'prop_logic/constants'
10
10
  require 'prop_logic/brute_force_sat_solver'
11
+ require 'prop_logic/default_incremental_solver'
11
12
  require 'prop_logic/sat_solver'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prop_logic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
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-03-11 00:00:00.000000000 Z
11
+ date: 2016-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ref
@@ -87,6 +87,7 @@ files:
87
87
  - lib/prop_logic/and_term.rb
88
88
  - lib/prop_logic/brute_force_sat_solver.rb
89
89
  - lib/prop_logic/constants.rb
90
+ - lib/prop_logic/default_incremental_solver.rb
90
91
  - lib/prop_logic/functions.rb
91
92
  - lib/prop_logic/not_term.rb
92
93
  - lib/prop_logic/or_term.rb