ravensat 1.0.8 → 1.1.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
  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