ravensat 0.3.0 → 1.0.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +18 -0
  3. data/README.md +90 -13
  4. data/docs/Arcteryx/CNF.html +827 -0
  5. data/docs/Arcteryx.html +309 -0
  6. data/docs/Ravensat/AndNode.html +159 -0
  7. data/docs/Ravensat/Claw.html +338 -0
  8. data/docs/Ravensat/DimacsDecoder.html +224 -0
  9. data/docs/Ravensat/DimacsEncoder.html +425 -0
  10. data/docs/Ravensat/Extension/BooleanVariable.html +229 -0
  11. data/docs/Ravensat/Extension/Domain.html +319 -0
  12. data/docs/Ravensat/Extension/IntegerVariable.html +589 -0
  13. data/docs/Ravensat/Extension/UndefinedVariable.html +236 -0
  14. data/docs/Ravensat/Extension/Variable.html +443 -0
  15. data/docs/Ravensat/Extension.html +141 -0
  16. data/docs/Ravensat/InitialNode.html +267 -0
  17. data/docs/Ravensat/Node.html +780 -0
  18. data/docs/Ravensat/NotNode.html +159 -0
  19. data/docs/Ravensat/OprNode.html +226 -0
  20. data/docs/Ravensat/OrNode.html +252 -0
  21. data/docs/Ravensat/Solver.html +373 -0
  22. data/docs/Ravensat/VarNode.html +488 -0
  23. data/docs/Ravensat.html +135 -0
  24. data/docs/_index.html +329 -0
  25. data/docs/class_list.html +51 -0
  26. data/docs/css/common.css +1 -0
  27. data/docs/css/full_list.css +58 -0
  28. data/docs/css/style.css +497 -0
  29. data/docs/file.README.html +233 -0
  30. data/docs/file_list.html +56 -0
  31. data/docs/frames.html +17 -0
  32. data/docs/index.html +233 -0
  33. data/docs/js/app.js +314 -0
  34. data/docs/js/full_list.js +216 -0
  35. data/docs/js/jquery.js +4 -0
  36. data/docs/method_list.html +523 -0
  37. data/docs/top-level-namespace.html +110 -0
  38. data/exe/ravensat +1 -5
  39. data/lib/ravensat/ast/and_node.rb +8 -0
  40. data/lib/ravensat/ast/node.rb +84 -20
  41. data/lib/ravensat/ast/not_node.rb +7 -0
  42. data/lib/ravensat/ast/or_node.rb +9 -0
  43. data/lib/ravensat/ast/var_node.rb +10 -1
  44. data/lib/ravensat/claw.rb +44 -0
  45. data/lib/ravensat/dimacs/dimacs_decoder.rb +9 -6
  46. data/lib/ravensat/dimacs/dimacs_encoder.rb +10 -13
  47. data/lib/ravensat/extension/domain.rb +0 -1
  48. data/lib/ravensat/extension/variable/integer_variable.rb +3 -3
  49. data/lib/ravensat/solver.rb +1 -8
  50. data/lib/ravensat/version.rb +1 -1
  51. data/lib/ravensat.rb +1 -1
  52. metadata +38 -3
  53. data/lib/ravensat/ravenclaw.rb +0 -19
@@ -7,24 +7,91 @@ 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)}
14
+ # end
15
+ # end
16
+
17
+ # def each
18
+ # case self
19
+ # when AndNode, OrNode
20
+ # @children.first.each{|c| yield(c)}
21
+ # yield(self)
22
+ # @children.last.each{|c| yield(c)}
23
+ # when NotNode
24
+ # yield(self)
25
+ # @children.first.each{|c| yield(c)}
26
+ # when VarNode
27
+ # yield(self)
28
+ # end
29
+ # end
30
+
31
+ def each_DP
32
+ node_stack = [[self, self.children.clone]] #[[parent, children], ...]
33
+
34
+ until node_stack.empty?
35
+ current_parent, current_children = node_stack.pop
36
+ current_node = current_children.shift
37
+
38
+ # puts 'loop'
39
+ # puts "node_stack.size:#{node_stack.size}"
40
+ # puts "current_parent:#{current_parent.class}"
41
+ # puts "current_children.size:#{current_children.size}"
42
+ # puts "current_node:#{current_node.class}"
43
+
44
+ case current_node
45
+ when AndNode
46
+ node_stack.push [current_parent, current_children.clone]
47
+ node_stack.push [current_node, current_node.children.clone]
48
+ when OrNode
49
+ node_stack.push [current_parent, current_children.clone]
50
+ node_stack.push [current_node, current_node.children.clone]
51
+ when NotNode
52
+ yield(current_node)
53
+ yield(current_node.children.first)
54
+
55
+ if current_children.empty?
56
+ yield(node_stack.last.first)
57
+ else
58
+ yield(current_parent)
59
+ node_stack.push [current_parent, current_children.clone]
60
+ end
61
+ when VarNode, Extension::BooleanVariable
62
+ yield(current_node)
63
+
64
+ if current_children.empty?
65
+ yield(node_stack.last.first)
66
+ else
67
+ yield(current_parent)
68
+ node_stack.push [current_parent, current_children.clone]
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+
10
75
  def each
11
- yield(self)
12
- @children.each do |child|
13
- child.each {|c| yield(c)}
76
+ return to_enum unless block_given?
77
+ node_stack = [self]
78
+
79
+ until node_stack.empty?
80
+ current_node = node_stack.shift
81
+ next unless current_node
82
+
83
+ yield current_node
84
+
85
+ node_stack = node_stack.concat(current_node.children)
14
86
  end
87
+
88
+ self if block_given?
15
89
  end
16
90
 
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)
91
+ def each_naive
92
+ yield(self)
93
+ @children.each do |child|
94
+ child.each {|c| yield(c)}
28
95
  end
29
96
  end
30
97
 
@@ -36,16 +103,13 @@ module Ravensat
36
103
  OrNode.new(self, object)
37
104
  end
38
105
 
39
- # def tree_text
40
- # self.each do |child|
41
- # child.to_s
42
- # end
43
- # end
44
-
45
106
  def to_s
46
107
  self.class.name
47
108
  end
48
109
 
110
+ def to_dimacs
111
+ end
112
+
49
113
  def cnf?
50
114
  @children.map(&:cnf?).reduce(:&)
51
115
  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 ~@
@@ -13,5 +14,13 @@ module Ravensat
13
14
  def cnf?
14
15
  true
15
16
  end
17
+
18
+ def result
19
+ @value
20
+ end
21
+
22
+ def to_dimacs
23
+ @dimacs_name
24
+ end
16
25
  end
17
26
  end
@@ -0,0 +1,44 @@
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
+ def self.commander_amo(bool_vars)
14
+ m = bool_vars.size / 2
15
+ commander_variables = []
16
+ formula = Ravensat::InitialNode.new
17
+ bool_vars.each_slice(2) do |g|
18
+ c = Ravensat::VarNode.new
19
+ subset = g << ~c
20
+ formula &= pairwise_amo(subset)
21
+ formula &= alo(subset)
22
+ commander_variables << c
23
+ end
24
+
25
+ if m < 6
26
+ formula &= pairwise_amo(commander_variables)
27
+ else
28
+ formula &= commander_amo(commander_variables)
29
+ end
30
+ end
31
+
32
+ def self.all_different(*int_vars)
33
+ int_vars.combination(2).map do |int_var|
34
+ int_var.reduce(:!=)
35
+ end.reduce(:&)
36
+ end
37
+
38
+ def self.all_only_one(*int_vars)
39
+ int_vars.map(&:only_one).reduce(:&)
40
+ end
41
+
42
+ # alias :amo :pairwise_amo
43
+ end
44
+ end
@@ -1,18 +1,21 @@
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
+ # inverted_name_table = name_table.invert
5
+ prop_vars = cnf.vars
5
6
  case model.first
6
7
  when "SAT"
7
8
  model.last.split.each do |e|
8
9
  if e == '0'
9
10
  next
10
11
  elsif e[0] == "-"
11
- index = e.slice(1..-1)
12
- inverted_name_table[index].value = false
12
+ dimacs_name = e.slice(1..-1)
13
+ var = prop_vars.find{|i| i.dimacs_name == dimacs_name}
14
+ var.value = false
13
15
  else
14
- index = e
15
- inverted_name_table[index].value = true
16
+ dimacs_name = e
17
+ var = prop_vars.find{|i| i.dimacs_name == dimacs_name}
18
+ var.value = true
16
19
  end
17
20
  end
18
21
  true
@@ -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_DP 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
@@ -12,7 +12,6 @@ module Ravensat
12
12
  def bool(*vars)
13
13
  vars.each do |var|
14
14
  next if var.is_defined?
15
- # LOCAL_VARIABLE_TABLE[var.name] = Ravensat::VarNode.new
16
15
  LOCAL_VARIABLE_TABLE[var.name] = Ravensat::Extension::BooleanVariable.new(var.name, var.args)
17
16
  end
18
17
  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
 
@@ -5,15 +5,8 @@ module Ravensat
5
5
  attr_accessor :name
6
6
  def initialize( default_solver_name = "arcteryx" )
7
7
  @name = default_solver_name
8
- # @cnf = Array.new
9
- # @nr_vars
10
- # @nr_clses
11
8
  end
12
9
 
13
- # def <<( clause )
14
- # 'this is << method'
15
- # end
16
-
17
10
  def solve( cnf )
18
11
  encoder = DimacsEncoder.new
19
12
  @input_file = Tempfile.open(["ravensat",".cnf"])
@@ -31,7 +24,7 @@ module Ravensat
31
24
 
32
25
  decoder = DimacsDecoder.new
33
26
  model = @output_file.read.split("\n")
34
- decoder.decode(model, encoder.name_table)
27
+ decoder.decode(model, cnf)
35
28
  end
36
29
 
37
30
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ravensat
4
- VERSION = "0.3.0"
4
+ VERSION = "1.0.0"
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.0
4
+ version: 1.0.0
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-18 00:00:00.000000000 Z
11
+ date: 2022-07-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -18,6 +18,7 @@ executables:
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - ".github/workflows/main.yml"
21
22
  - ".gitignore"
22
23
  - ".rspec"
23
24
  - ".ruby-version"
@@ -28,6 +29,40 @@ files:
28
29
  - Rakefile
29
30
  - bin/console
30
31
  - bin/setup
32
+ - docs/Arcteryx.html
33
+ - docs/Arcteryx/CNF.html
34
+ - docs/Ravensat.html
35
+ - docs/Ravensat/AndNode.html
36
+ - docs/Ravensat/Claw.html
37
+ - docs/Ravensat/DimacsDecoder.html
38
+ - docs/Ravensat/DimacsEncoder.html
39
+ - docs/Ravensat/Extension.html
40
+ - docs/Ravensat/Extension/BooleanVariable.html
41
+ - docs/Ravensat/Extension/Domain.html
42
+ - docs/Ravensat/Extension/IntegerVariable.html
43
+ - docs/Ravensat/Extension/UndefinedVariable.html
44
+ - docs/Ravensat/Extension/Variable.html
45
+ - docs/Ravensat/InitialNode.html
46
+ - docs/Ravensat/Node.html
47
+ - docs/Ravensat/NotNode.html
48
+ - docs/Ravensat/OprNode.html
49
+ - docs/Ravensat/OrNode.html
50
+ - docs/Ravensat/Solver.html
51
+ - docs/Ravensat/VarNode.html
52
+ - docs/_index.html
53
+ - docs/class_list.html
54
+ - docs/css/common.css
55
+ - docs/css/full_list.css
56
+ - docs/css/style.css
57
+ - docs/file.README.html
58
+ - docs/file_list.html
59
+ - docs/frames.html
60
+ - docs/index.html
61
+ - docs/js/app.js
62
+ - docs/js/full_list.js
63
+ - docs/js/jquery.js
64
+ - docs/method_list.html
65
+ - docs/top-level-namespace.html
31
66
  - example/magic_square_3x3.rb
32
67
  - exe/ravensat
33
68
  - lib/arcteryx/arcteryx.rb
@@ -41,6 +76,7 @@ files:
41
76
  - lib/ravensat/ast/opr_node.rb
42
77
  - lib/ravensat/ast/or_node.rb
43
78
  - lib/ravensat/ast/var_node.rb
79
+ - lib/ravensat/claw.rb
44
80
  - lib/ravensat/dimacs.rb
45
81
  - lib/ravensat/dimacs/dimacs_decoder.rb
46
82
  - lib/ravensat/dimacs/dimacs_encoder.rb
@@ -50,7 +86,6 @@ files:
50
86
  - lib/ravensat/extension/variable/integer_variable.rb
51
87
  - lib/ravensat/extension/variable/undefined_variable.rb
52
88
  - lib/ravensat/extension/variable/variable.rb
53
- - lib/ravensat/ravenclaw.rb
54
89
  - lib/ravensat/solver.rb
55
90
  - lib/ravensat/version.rb
56
91
  - ravensat.gemspec
@@ -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