ravensat 1.0.8 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d64d337bf293ce23f27a118bc1896ecf7c35709f3d0a0a7c217fa3bef2e495a6
4
- data.tar.gz: 38c00c661b514dff04fd0fdcc2854ae9c37104598fb6dc2f8235eac0178595dd
3
+ metadata.gz: e2be04a5683be973ab9a882393a2ac6ed25d40d19899d3222841a0727e7a9ccc
4
+ data.tar.gz: 6674ab1b25282eb389672ed0e53857272fe048a0d08c6ec0d632c56ff126bbc9
5
5
  SHA512:
6
- metadata.gz: 853077cca8f5220f9ecfbcec4c14323678b5f6d36f197892a3b49646ca6cff39a032fbcdf2199e524ab46f3d5806cf86a9f45152a71bd968d4d0388dcf0cacb7
7
- data.tar.gz: 10de270cfe07b3c1041dd0e398b8c1e8c1bd58d103917b8e116fb3f84caa8235747e5cb775ca9601a2b3be63b673efac5d0b6dade9451e0c121f8dcc9872594b
6
+ metadata.gz: fb557522b6b17eeaec4171a76169887b1392a9d321ed6e723911df41d6caddcc00dd31e376e340c78cc71dd5a29267a0c4050a6f1c91bba21dbb4d4aafcebb61
7
+ data.tar.gz: d046a5e639fdb03a2c372b96cc992ef6c8ef6b1c3a73bf0c26f460a82acfce84495bc20ce4661cef99a858e7dc5ed5b6a373bb1788d78cb737c0c8eb7e20e273
@@ -2,6 +2,8 @@ module Ravensat
2
2
  class AndNode < OprNode
3
3
  def &(object)
4
4
  raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
5
+ return self if object.is_a? NilNode
6
+
5
7
  @children.append object
6
8
  self
7
9
  end
@@ -9,5 +11,9 @@ module Ravensat
9
11
  def to_dimacs
10
12
  " 0\n"
11
13
  end
14
+
15
+ def eval
16
+ @children.map(&:eval).reduce(:&)
17
+ end
12
18
  end
13
19
  end
@@ -2,11 +2,15 @@ module Ravensat
2
2
  class InitialNode < Node
3
3
  def &(object)
4
4
  raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
5
+ return self if object.is_a? NilNode
6
+
5
7
  object
6
8
  end
7
9
 
8
10
  def |(object)
9
11
  raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
12
+ return self if object.is_a? NilNode
13
+
10
14
  object
11
15
  end
12
16
  end
@@ -0,0 +1,17 @@
1
+ module Ravensat
2
+ class NilNode < Node
3
+ def initialize
4
+ @children = []
5
+ end
6
+
7
+ def &(object)
8
+ raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
9
+ object
10
+ end
11
+
12
+ def |(object)
13
+ raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
14
+ object
15
+ end
16
+ end
17
+ end
@@ -64,11 +64,15 @@ module Ravensat
64
64
 
65
65
  def &(object)
66
66
  raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
67
+ return self if object.is_a? NilNode
68
+
67
69
  AndNode.new(self, object)
68
70
  end
69
71
 
70
72
  def |(object)
71
73
  raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
74
+ return self if object.is_a? NilNode
75
+
72
76
  OrNode.new(self, object)
73
77
  end
74
78
 
@@ -83,6 +87,9 @@ module Ravensat
83
87
  @children.map(&:cnf?).reduce(:&)
84
88
  end
85
89
 
90
+ def eval
91
+ end
92
+
86
93
  def vars
87
94
  self.select{|node| node.is_a? VarNode}.uniq
88
95
  end
@@ -7,5 +7,9 @@ module Ravensat
7
7
  def to_dimacs
8
8
  "-"
9
9
  end
10
+
11
+ def eval
12
+ @children.map(&:eval).first ^ true
13
+ end
10
14
  end
11
15
  end
@@ -2,6 +2,8 @@ module Ravensat
2
2
  class OrNode < OprNode
3
3
  def |(object)
4
4
  raise TypeError.new("#{object.class} can't be coerced into Ravensat::Node") unless object.is_a? Node
5
+ return self if object.is_a? NilNode
6
+
5
7
  @children.append object
6
8
  self
7
9
  end
@@ -14,5 +16,9 @@ module Ravensat
14
16
  def to_dimacs
15
17
  " "
16
18
  end
19
+
20
+ def eval
21
+ @children.map(&:eval).reduce(:|)
22
+ end
17
23
  end
18
24
  end
@@ -22,5 +22,9 @@ module Ravensat
22
22
  def to_dimacs
23
23
  @dimacs_name
24
24
  end
25
+
26
+ def eval
27
+ @value
28
+ end
25
29
  end
26
30
  end
data/lib/ravensat/ast.rb CHANGED
@@ -8,4 +8,5 @@ module Ravensat
8
8
  autoload :OrNode, dir + '/or_node.rb'
9
9
  autoload :NotNode, dir + '/not_node.rb'
10
10
  autoload :InitialNode, dir + '/initial_node.rb'
11
+ autoload :NilNode, dir + '/nil_node.rb'
11
12
  end
data/lib/ravensat/claw.rb CHANGED
@@ -1,34 +1,35 @@
1
1
  module Ravensat
2
2
  module Claw
3
- def self.alo(bool_vars)
4
- return bool_vars.first if bool_vars.size == 1
3
+ def self.at_most_one(bool_vars)
4
+ return Ravensat::NilNode.new if bool_vars.size == 1
5
+ bool_vars.combination(2).map do |e|
6
+ e.map(&:~@).reduce(:|)
7
+ end.reduce(:&)
8
+ end
9
+
10
+ def self.at_least_one(bool_vars)
11
+ return Ravensat::NilNode.new if bool_vars.size == 1
5
12
  bool_vars.reduce(:|)
6
13
  end
7
14
 
8
15
  def self.at_most_k(bool_vars, k)
9
- return bool_vars.first if bool_vars.size == 1
16
+ return Ravensat::NilNode.new if bool_vars.size == 1
10
17
  bool_vars.combination(k+1).map do |e|
11
18
  e.map(&:~@).reduce(:|)
12
19
  end.reduce(:&)
13
20
  end
14
21
 
15
22
  def self.at_least_k(bool_vars, k)
16
- return bool_vars.first if bool_vars.size == 1
23
+ return Ravensat::NilNode.new if bool_vars.size == 1
17
24
  bool_vars.combination(k-1).map do |e|
18
- alo(bool_vars - e)
25
+ at_least_one(bool_vars - e)
19
26
  end.reduce(:&)
20
27
  end
21
28
 
22
- def self.pairwise_amo(bool_vars)
23
- return bool_vars.first if bool_vars.size == 1
24
- bool_vars.combination(2).map do |e|
25
- e.map(&:~@).reduce(:|)
26
- end.reduce(:&)
27
- end
28
29
 
29
30
  # NOTE: Klieber, W. and Kwon, G.: Efficient CNF Encoding for Selecting 1 from N Objects (2007).
30
- def self.commander_amo(bool_vars)
31
- return bool_vars.first if bool_vars.size == 1
31
+ def self.commander_at_most_one(bool_vars)
32
+ return Ravensat::NilNode.new if bool_vars.size == 1
32
33
  # XXX: Operator unknown if bool_vars.size is very small.
33
34
  m = bool_vars.size / 2
34
35
  commander_variables = []
@@ -36,18 +37,50 @@ module Ravensat
36
37
  bool_vars.each_slice(2) do |g|
37
38
  c = Ravensat::VarNode.new
38
39
  subset = g << ~c
39
- formula &= pairwise_amo(subset)
40
- formula &= alo(subset)
40
+ formula &= at_most_one(subset)
41
+ formula &= at_least_one(subset)
41
42
  commander_variables << c
42
43
  end
43
44
 
44
45
  if m < 6
45
- formula &= pairwise_amo(commander_variables)
46
+ formula &= at_most_one(commander_variables)
46
47
  else
47
- formula &= commander_amo(commander_variables)
48
+ formula &= commander_at_most_one(commander_variables)
48
49
  end
49
50
  end
50
51
 
52
+ def self.commander_at_most_k(bool_vars, k)
53
+ return Ravensat::NilNode.new if bool_vars.size == 1
54
+ group_size = k + 2
55
+ commander_variables = []
56
+ formula = Ravensat::InitialNode.new
57
+
58
+ bool_vars.each_slice(group_size) do |g|
59
+ cmds = Array.new(k){Ravensat::VarNode.new}
60
+ subset = g + cmds.map(&:~)
61
+ formula &= at_most_k(subset, k)
62
+ formula &= at_least_k(subset, k)
63
+ cmds.each_cons(2) do |e1, e2|
64
+ formula &= ~e1 | e2
65
+ end
66
+ commander_variables += cmds
67
+ end
68
+
69
+ formula &= at_most_k(commander_variables, k)
70
+ end
71
+
72
+ def self.exactly_one(bool_vars)
73
+ formula = Ravensat::InitialNode.new
74
+ formula &= commander_at_most_one(bool_vars)
75
+ formula &= at_least_one(bool_vars)
76
+ end
77
+
78
+ def self.exactly_k(bool_vars, k)
79
+ formula = Ravensat::InitialNode.new
80
+ formula &= commander_at_most_k(bool_vars, k)
81
+ formula &= at_least_k(bool_vars, k)
82
+ end
83
+
51
84
  def self.all_different(*int_vars)
52
85
  int_vars.combination(2).map do |int_var|
53
86
  int_var.reduce(:!=)
@@ -57,7 +90,5 @@ module Ravensat
57
90
  def self.all_only_one(*int_vars)
58
91
  int_vars.map(&:only_one).reduce(:&)
59
92
  end
60
-
61
- # alias :amo :pairwise_amo
62
93
  end
63
94
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ravensat
4
- VERSION = "1.0.8"
4
+ VERSION = "1.1.0"
5
5
  end
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: 1.0.8
4
+ version: 1.1.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-08-23 00:00:00.000000000 Z
11
+ date: 2022-11-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -70,6 +70,7 @@ files:
70
70
  - lib/ravensat/ast.rb
71
71
  - lib/ravensat/ast/and_node.rb
72
72
  - lib/ravensat/ast/initial_node.rb
73
+ - lib/ravensat/ast/nil_node.rb
73
74
  - lib/ravensat/ast/node.rb
74
75
  - lib/ravensat/ast/not_node.rb
75
76
  - lib/ravensat/ast/opr_node.rb