ravensat 0.3.1 → 1.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -21
  3. data/docs/Arcteryx/CNF.html +827 -0
  4. data/docs/Arcteryx.html +309 -0
  5. data/docs/Ravensat/AndNode.html +159 -0
  6. data/docs/Ravensat/Claw.html +338 -0
  7. data/docs/Ravensat/DimacsDecoder.html +224 -0
  8. data/docs/Ravensat/DimacsEncoder.html +425 -0
  9. data/docs/Ravensat/Extension/BooleanVariable.html +229 -0
  10. data/docs/Ravensat/Extension/Domain.html +319 -0
  11. data/docs/Ravensat/Extension/IntegerVariable.html +589 -0
  12. data/docs/Ravensat/Extension/UndefinedVariable.html +236 -0
  13. data/docs/Ravensat/Extension/Variable.html +443 -0
  14. data/docs/Ravensat/Extension.html +141 -0
  15. data/docs/Ravensat/InitialNode.html +267 -0
  16. data/docs/Ravensat/Node.html +780 -0
  17. data/docs/Ravensat/NotNode.html +159 -0
  18. data/docs/Ravensat/OprNode.html +226 -0
  19. data/docs/Ravensat/OrNode.html +252 -0
  20. data/docs/Ravensat/Solver.html +373 -0
  21. data/docs/Ravensat/VarNode.html +488 -0
  22. data/docs/Ravensat.html +135 -0
  23. data/docs/_index.html +329 -0
  24. data/docs/class_list.html +51 -0
  25. data/docs/css/common.css +1 -0
  26. data/docs/css/full_list.css +58 -0
  27. data/docs/css/style.css +497 -0
  28. data/docs/file.README.html +233 -0
  29. data/docs/file_list.html +56 -0
  30. data/docs/frames.html +17 -0
  31. data/docs/index.html +233 -0
  32. data/docs/js/app.js +314 -0
  33. data/docs/js/full_list.js +216 -0
  34. data/docs/js/jquery.js +4 -0
  35. data/docs/method_list.html +523 -0
  36. data/docs/top-level-namespace.html +110 -0
  37. data/lib/ravensat/ast/and_node.rb +8 -0
  38. data/lib/ravensat/ast/node.rb +50 -15
  39. data/lib/ravensat/ast/not_node.rb +7 -0
  40. data/lib/ravensat/ast/or_node.rb +9 -0
  41. data/lib/ravensat/ast/var_node.rb +6 -1
  42. data/lib/ravensat/claw.rb +45 -0
  43. data/lib/ravensat/dimacs/dimacs_decoder.rb +6 -12
  44. data/lib/ravensat/dimacs/dimacs_encoder.rb +10 -13
  45. data/lib/ravensat/extension/variable/integer_variable.rb +3 -3
  46. data/lib/ravensat/solver.rb +1 -1
  47. data/lib/ravensat/version.rb +1 -1
  48. data/lib/ravensat.rb +1 -1
  49. metadata +37 -4
  50. data/Gemfile.lock +0 -45
  51. data/lib/ravensat/ravenclaw.rb +0 -19
@@ -7,25 +7,57 @@ module Ravensat
7
7
  @children = []
8
8
  end
9
9
 
10
- def each
11
- yield(self)
12
- @children.each do |child|
13
- child.each {|c| yield(c)}
10
+ def each_by_descriptive
11
+ node_stack = [[self, self.children.clone]] #[[parent, children], ...]
12
+
13
+ until node_stack.empty?
14
+ current_parent, current_children = node_stack.pop
15
+ current_node = current_children.shift
16
+
17
+ case current_node
18
+ when AndNode
19
+ node_stack.push [current_parent, current_children.clone]
20
+ node_stack.push [current_node, current_node.children.clone]
21
+ when OrNode
22
+ node_stack.push [current_parent, current_children.clone]
23
+ node_stack.push [current_node, current_node.children.clone]
24
+ when NotNode
25
+ yield(current_node)
26
+ yield(current_node.children.first)
27
+
28
+ if current_children.empty?
29
+ yield(node_stack.last.first)
30
+ else
31
+ yield(current_parent)
32
+ node_stack.push [current_parent, current_children.clone]
33
+ end
34
+ when VarNode, Extension::BooleanVariable
35
+ yield(current_node)
36
+
37
+ if current_children.empty?
38
+ yield(node_stack.last.first)
39
+ else
40
+ yield(current_parent)
41
+ node_stack.push [current_parent, current_children.clone]
42
+ end
43
+ end
14
44
  end
15
45
  end
16
46
 
17
- def each_with_clause
18
- case self
19
- when AndNode, OrNode
20
- @children.first.each_with_clause{|c| yield(c)}
21
- yield(self)
22
- @children.last.each_with_clause{|c| yield(c)}
23
- when NotNode
24
- yield(self)
25
- @children.first.each_with_clause{|c| yield(c)}
26
- when VarNode
27
- yield(self)
47
+ def each
48
+ return to_enum unless block_given?
49
+ node_stack = [self]
50
+
51
+ until node_stack.empty?
52
+ current_node = node_stack.shift
53
+ next unless current_node
54
+
55
+ yield current_node
56
+
57
+ node_stack = node_stack.concat(current_node.children)
28
58
  end
59
+
60
+ self if block_given?
29
61
  end
30
62
 
31
63
  def &(object)
@@ -40,6 +72,9 @@ module Ravensat
40
72
  self.class.name
41
73
  end
42
74
 
75
+ def to_dimacs
76
+ end
77
+
43
78
  def cnf?
44
79
  @children.map(&:cnf?).reduce(:&)
45
80
  end
@@ -1,4 +1,11 @@
1
1
  module Ravensat
2
2
  class NotNode < OprNode
3
+ def ~@
4
+ @children.first
5
+ end
6
+
7
+ def to_dimacs
8
+ "-"
9
+ end
3
10
  end
4
11
  end
@@ -1,8 +1,17 @@
1
1
  module Ravensat
2
2
  class OrNode < OprNode
3
+ def |(object)
4
+ @children.append object
5
+ self
6
+ end
7
+
3
8
  def cnf?
4
9
  return false if @children.any?{|node| node.is_a? AndNode}
5
10
  @children.map(&:cnf?).reduce(:&)
6
11
  end
12
+
13
+ def to_dimacs
14
+ " "
15
+ end
7
16
  end
8
17
  end
@@ -1,9 +1,10 @@
1
1
  module Ravensat
2
2
  class VarNode < Node
3
- attr_accessor :value
3
+ attr_accessor :value, :dimacs_name
4
4
  def initialize
5
5
  @value
6
6
  @children = []
7
+ @dimacs_name
7
8
  end
8
9
 
9
10
  def ~@
@@ -17,5 +18,9 @@ module Ravensat
17
18
  def result
18
19
  @value
19
20
  end
21
+
22
+ def to_dimacs
23
+ @dimacs_name
24
+ end
20
25
  end
21
26
  end
@@ -0,0 +1,45 @@
1
+ module Ravensat
2
+ module Claw
3
+ def self.alo(bool_vars)
4
+ bool_vars.reduce(:|)
5
+ end
6
+
7
+ def self.pairwise_amo(bool_vars)
8
+ bool_vars.combination(2).map do |e|
9
+ e.map(&:~@).reduce(:|)
10
+ end.reduce(:&)
11
+ end
12
+
13
+ # NOTE: Klieber, W. and Kwon, G.: Efficient CNF Encoding for Selecting 1 from N Objects (2007).
14
+ def self.commander_amo(bool_vars)
15
+ m = bool_vars.size / 2
16
+ commander_variables = []
17
+ formula = Ravensat::InitialNode.new
18
+ bool_vars.each_slice(2) do |g|
19
+ c = Ravensat::VarNode.new
20
+ subset = g << ~c
21
+ formula &= pairwise_amo(subset)
22
+ formula &= alo(subset)
23
+ commander_variables << c
24
+ end
25
+
26
+ if m < 6
27
+ formula &= pairwise_amo(commander_variables)
28
+ else
29
+ formula &= commander_amo(commander_variables)
30
+ end
31
+ end
32
+
33
+ def self.all_different(*int_vars)
34
+ int_vars.combination(2).map do |int_var|
35
+ int_var.reduce(:!=)
36
+ end.reduce(:&)
37
+ end
38
+
39
+ def self.all_only_one(*int_vars)
40
+ int_vars.map(&:only_one).reduce(:&)
41
+ end
42
+
43
+ # alias :amo :pairwise_amo
44
+ end
45
+ end
@@ -1,19 +1,13 @@
1
1
  module Ravensat
2
2
  class DimacsDecoder
3
- def decode(model, name_table)
4
- inverted_name_table = name_table.invert
3
+ def decode(model, cnf)
4
+ prop_vars = cnf.vars
5
5
  case model.first
6
6
  when "SAT"
7
- model.last.split.each do |e|
8
- if e == '0'
9
- next
10
- elsif e[0] == "-"
11
- index = e.slice(1..-1)
12
- inverted_name_table[index].value = false
13
- else
14
- index = e
15
- inverted_name_table[index].value = true
16
- end
7
+ model.last.split.each_with_index do |e,i|
8
+ break if e == '0'
9
+ var = prop_vars[i]
10
+ var.value = !(e[0] == '-')
17
11
  end
18
12
  true
19
13
  when "UNSAT"
@@ -6,26 +6,23 @@ module Ravensat
6
6
  end
7
7
 
8
8
  def to_dimacs(formula)
9
- return nil unless formula.cnf?
10
-
11
9
  dimacs_header = "p cnf #{formula.vars_size} #{formula.clauses_size}\n"
12
10
  dimacs_body = ""
13
- create_table(formula)
14
- formula.each_with_clause do |node|
15
- case node
16
- when AndNode then dimacs_body << " 0\n"
17
- when OrNode then dimacs_body << " "
18
- when NotNode then dimacs_body << "-"
19
- when VarNode then dimacs_body << @name_table[node]
20
- end
11
+ return nil unless formula.cnf?
12
+
13
+ set_dimacs_name(formula)
14
+
15
+ formula.each_by_descriptive do |node|
16
+ dimacs_body << node.to_dimacs
21
17
  end
22
- dimacs_body << " 0\n"
23
18
 
24
19
  dimacs_header + dimacs_body
25
20
  end
26
21
 
27
- def create_table(formula)
28
- @name_table = formula.vars.zip((1..formula.vars.size).map(&:to_s)).to_h
22
+ def set_dimacs_name(formula)
23
+ formula.vars.each_with_index do |node, i|
24
+ node.dimacs_name = (i+1).to_s
25
+ end
29
26
  end
30
27
  end
31
28
  end
@@ -18,7 +18,7 @@ module Ravensat
18
18
  duplicated_keys = self.var_nodes.keys & object.var_nodes.keys
19
19
 
20
20
  [self.var_nodes, object.var_nodes].repeated_permutation(duplicated_keys.size) do |var_nodes|
21
- result_formula &= Ravensat::RavenClaw.alo(var_nodes.zip(duplicated_keys).map{|arr| arr.first[arr.last]})
21
+ result_formula &= Ravensat::Claw.alo(var_nodes.zip(duplicated_keys).map{|arr| arr.first[arr.last]})
22
22
  end
23
23
  return result_formula
24
24
  else
@@ -45,8 +45,8 @@ module Ravensat
45
45
 
46
46
  def only_one
47
47
  result_formula = Ravensat::InitialNode.new
48
- result_formula &= Ravensat::RavenClaw.alo @var_nodes.values
49
- result_formula &= Ravensat::RavenClaw.amo @var_nodes.values
48
+ result_formula &= Ravensat::Claw.alo @var_nodes.values
49
+ result_formula &= Ravensat::Claw.amo @var_nodes.values
50
50
  result_formula
51
51
  end
52
52
 
@@ -24,7 +24,7 @@ module Ravensat
24
24
 
25
25
  decoder = DimacsDecoder.new
26
26
  model = @output_file.read.split("\n")
27
- decoder.decode(model, encoder.name_table)
27
+ decoder.decode(model, cnf)
28
28
  end
29
29
 
30
30
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ravensat
4
- VERSION = "0.3.1"
4
+ VERSION = "1.0.1"
5
5
  end
data/lib/ravensat.rb CHANGED
@@ -11,7 +11,7 @@ module Ravensat
11
11
  require_relative ravensat + "/dimacs.rb"
12
12
 
13
13
  autoload :Solver, ravensat + '/solver.rb'
14
- autoload :RavenClaw, ravensat + '/ravenclaw.rb'
14
+ autoload :Claw, ravensat + '/claw.rb'
15
15
  autoload :Extension, ravensat + '/extension.rb'
16
16
 
17
17
  autoload :Arcteryx, arcteryx + '/arcteryx.rb'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ravensat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rikuto matsuda
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-24 00:00:00.000000000 Z
11
+ date: 2022-07-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -23,12 +23,45 @@ files:
23
23
  - ".rspec"
24
24
  - ".ruby-version"
25
25
  - Gemfile
26
- - Gemfile.lock
27
26
  - LICENSE.txt
28
27
  - README.md
29
28
  - Rakefile
30
29
  - bin/console
31
30
  - bin/setup
31
+ - docs/Arcteryx.html
32
+ - docs/Arcteryx/CNF.html
33
+ - docs/Ravensat.html
34
+ - docs/Ravensat/AndNode.html
35
+ - docs/Ravensat/Claw.html
36
+ - docs/Ravensat/DimacsDecoder.html
37
+ - docs/Ravensat/DimacsEncoder.html
38
+ - docs/Ravensat/Extension.html
39
+ - docs/Ravensat/Extension/BooleanVariable.html
40
+ - docs/Ravensat/Extension/Domain.html
41
+ - docs/Ravensat/Extension/IntegerVariable.html
42
+ - docs/Ravensat/Extension/UndefinedVariable.html
43
+ - docs/Ravensat/Extension/Variable.html
44
+ - docs/Ravensat/InitialNode.html
45
+ - docs/Ravensat/Node.html
46
+ - docs/Ravensat/NotNode.html
47
+ - docs/Ravensat/OprNode.html
48
+ - docs/Ravensat/OrNode.html
49
+ - docs/Ravensat/Solver.html
50
+ - docs/Ravensat/VarNode.html
51
+ - docs/_index.html
52
+ - docs/class_list.html
53
+ - docs/css/common.css
54
+ - docs/css/full_list.css
55
+ - docs/css/style.css
56
+ - docs/file.README.html
57
+ - docs/file_list.html
58
+ - docs/frames.html
59
+ - docs/index.html
60
+ - docs/js/app.js
61
+ - docs/js/full_list.js
62
+ - docs/js/jquery.js
63
+ - docs/method_list.html
64
+ - docs/top-level-namespace.html
32
65
  - example/magic_square_3x3.rb
33
66
  - exe/ravensat
34
67
  - lib/arcteryx/arcteryx.rb
@@ -42,6 +75,7 @@ files:
42
75
  - lib/ravensat/ast/opr_node.rb
43
76
  - lib/ravensat/ast/or_node.rb
44
77
  - lib/ravensat/ast/var_node.rb
78
+ - lib/ravensat/claw.rb
45
79
  - lib/ravensat/dimacs.rb
46
80
  - lib/ravensat/dimacs/dimacs_decoder.rb
47
81
  - lib/ravensat/dimacs/dimacs_encoder.rb
@@ -51,7 +85,6 @@ files:
51
85
  - lib/ravensat/extension/variable/integer_variable.rb
52
86
  - lib/ravensat/extension/variable/undefined_variable.rb
53
87
  - lib/ravensat/extension/variable/variable.rb
54
- - lib/ravensat/ravenclaw.rb
55
88
  - lib/ravensat/solver.rb
56
89
  - lib/ravensat/version.rb
57
90
  - ravensat.gemspec
data/Gemfile.lock DELETED
@@ -1,45 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- ravensat (0.1.1)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- byebug (11.1.3)
10
- coderay (1.1.3)
11
- diff-lcs (1.4.4)
12
- method_source (1.0.0)
13
- pry (0.14.0)
14
- coderay (~> 1.1)
15
- method_source (~> 1.0)
16
- pry-byebug (3.8.0)
17
- byebug (~> 11.0)
18
- pry (~> 0.10)
19
- rake (13.0.3)
20
- rspec (3.10.0)
21
- rspec-core (~> 3.10.0)
22
- rspec-expectations (~> 3.10.0)
23
- rspec-mocks (~> 3.10.0)
24
- rspec-core (3.10.1)
25
- rspec-support (~> 3.10.0)
26
- rspec-expectations (3.10.1)
27
- diff-lcs (>= 1.2.0, < 2.0)
28
- rspec-support (~> 3.10.0)
29
- rspec-mocks (3.10.2)
30
- diff-lcs (>= 1.2.0, < 2.0)
31
- rspec-support (~> 3.10.0)
32
- rspec-support (3.10.2)
33
-
34
- PLATFORMS
35
- x86_64-linux
36
-
37
- DEPENDENCIES
38
- pry
39
- pry-byebug
40
- rake (~> 13.0)
41
- ravensat!
42
- rspec (~> 3.0)
43
-
44
- BUNDLED WITH
45
- 2.2.24
@@ -1,19 +0,0 @@
1
- module Ravensat
2
- module RavenClaw
3
- def self.alo(bool_vars)
4
- bool_vars.reduce(:|)
5
- end
6
-
7
- def self.amo(bool_vars)
8
- bool_vars.combination(2).map do |e|
9
- e.map(&:~@).reduce(:|)
10
- end.reduce(:&)
11
- end
12
-
13
- def self.all_different(*int_vars)
14
- int_vars.combination(2).map do |int_var|
15
- int_var.reduce(:!=)
16
- end.reduce(:&)
17
- end
18
- end
19
- end