ravensat 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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