ravensat 0.2.2 → 0.3.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: 2206c8010f299d713c19b74682a2c46470d0c4cc7e27ade7e429ee0de09622de
4
- data.tar.gz: 14b05657764ab053b091da8f0ddb339201ea2cd469d2828eccc04fd0b3c4e49e
3
+ metadata.gz: 9d0f5a2e88e6b17130dc2101a9c2e85d0e401fba9bcba081299cf14ded1c683b
4
+ data.tar.gz: ee09cdeb7da7fd0cd04a80a5017ae351b836cf9a6d63ab92fddaa9181f36dff2
5
5
  SHA512:
6
- metadata.gz: ba52ce15498089d710d8e7ded3b8f35da11364a74a6f72241482ceb794cec83164423142e5b3d3feb90b0a444d8ec62327d7be830cac6d4390844fb9ce10cb6e
7
- data.tar.gz: 83509b606c6693373ce2918fe4ae9feda5aafbd241bca5510ed795cc52aae6dc0120cfc0e0294dd76a53004dbb825c1a9b0aa27664c47ff04a5e311ebf7bb167
6
+ metadata.gz: d763bab0b969a710ef42cae2e1aed39161e4b49488c1d898f8665b14a4763df09a881508875576f6505fc25c75daed694b805cb82ca081c95ac61d31bb49c12d
7
+ data.tar.gz: d5ff19dd7503194401664bba22b12bbe16a7ce8b6f1ff8cb54d19d1fcfde0d8912ad25d9762549d19f50dcc0d9d82161f020fae1c1207bd015ce530178eb8b62
data/README.md CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
22
22
  $ gem install ravensat
23
23
 
24
24
  ## Usage
25
-
25
+ ### General Usage
26
26
  ```ruby
27
27
  require 'ravensat'
28
28
 
@@ -41,6 +41,42 @@ a.value #=> true
41
41
  b.value #=> true
42
42
  ```
43
43
 
44
+ ### Extension Usage(SAT)
45
+ ```ruby
46
+ require 'ravensat'
47
+
48
+ module Ravensat
49
+ module Extension
50
+ bool a, b
51
+ logic = (a | b) & (~a | b) & (a | ~b)
52
+
53
+ solver = Ravensat::Solver.new
54
+ solver.solve logic #=> true
55
+
56
+ a.value #=> true
57
+ b.value #=> true
58
+ end
59
+ end
60
+ ```
61
+
62
+ ### Extension Usage(CSP; Constraint Satisfaction Problem)
63
+ ```ruby
64
+ require 'ravensat'
65
+
66
+ module Ravensat
67
+ module Extension
68
+ int a(1..10), b(1..10)
69
+ constraint = (a.only_one & b.only_one & (a != b))
70
+
71
+ solver = Ravensat::Solver.new
72
+ solver.solve constraint #=> true
73
+
74
+ a.result #=> 1
75
+ b.result #=> 2
76
+ end
77
+ end
78
+ ```
79
+
44
80
  ## Development
45
81
 
46
82
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/exe/ravensat ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require 'ravensat'
5
+ require 'pry'
6
+
7
+ module Ravensat
8
+ module Extension
9
+ binding.pry
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Ravensat
2
+ class InitialNode < Node
3
+ def &(object)
4
+ object
5
+ end
6
+
7
+ def |(object)
8
+ object
9
+ end
10
+ end
11
+ end
@@ -14,6 +14,20 @@ module Ravensat
14
14
  end
15
15
  end
16
16
 
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)
28
+ end
29
+ end
30
+
17
31
  def &(object)
18
32
  AndNode.new(self, object)
19
33
  end
@@ -0,0 +1,11 @@
1
+ module Ravensat
2
+ dir = File.dirname(__FILE__) + '/ast'
3
+
4
+ autoload :Node, dir + '/node.rb'
5
+ autoload :VarNode, dir + '/var_node.rb'
6
+ autoload :OprNode, dir + '/opr_node.rb'
7
+ autoload :AndNode, dir + '/and_node.rb'
8
+ autoload :OrNode, dir + '/or_node.rb'
9
+ autoload :NotNode, dir + '/not_node.rb'
10
+ autoload :InitialNode, dir + '/initial_node.rb'
11
+ end
@@ -11,18 +11,15 @@ module Ravensat
11
11
  dimacs_header = "p cnf #{formula.vars_size} #{formula.clauses_size}\n"
12
12
  dimacs_body = ""
13
13
  create_table(formula)
14
- formula.each do |node|
14
+ formula.each_with_clause do |node|
15
15
  case node
16
- when AndNode
17
- when OrNode then dimacs_body << "\n"
16
+ when AndNode then dimacs_body << " 0\n"
17
+ when OrNode then dimacs_body << " "
18
18
  when NotNode then dimacs_body << "-"
19
- when VarNode then dimacs_body << @name_table[node] << " "
19
+ when VarNode then dimacs_body << @name_table[node]
20
20
  end
21
21
  end
22
-
23
- # dimacs_body formatting
24
- dimacs_body.strip! << ' '
25
- dimacs_body.gsub!(/\n{2,}/, "\n").gsub!(/\n/, "0\n") << '0'
22
+ dimacs_body << " 0\n"
26
23
 
27
24
  dimacs_header + dimacs_body
28
25
  end
@@ -0,0 +1,6 @@
1
+ module Ravensat
2
+ dir = File.dirname(__FILE__) + '/dimacs'
3
+
4
+ autoload :DimacsEncoder, dir + '/dimacs_encoder.rb'
5
+ autoload :DimacsDecoder, dir + '/dimacs_decoder.rb'
6
+ end
@@ -0,0 +1,25 @@
1
+ module Ravensat
2
+ module Extension
3
+ module Domain
4
+ LOCAL_VARIABLE_TABLE = {}
5
+ def int(*vars)
6
+ vars.each do |var|
7
+ next if var.is_defined?
8
+ LOCAL_VARIABLE_TABLE[var.name] = Ravensat::Extension::IntegerVariable.new(var.name, var.args)
9
+ end
10
+ end
11
+
12
+ def bool(*vars)
13
+ vars.each do |var|
14
+ next if var.is_defined?
15
+ # LOCAL_VARIABLE_TABLE[var.name] = Ravensat::VarNode.new
16
+ LOCAL_VARIABLE_TABLE[var.name] = Ravensat::Extension::BooleanVariable.new(var.name, var.args)
17
+ end
18
+ end
19
+
20
+ def method_missing(name, *args)
21
+ LOCAL_VARIABLE_TABLE[name] || UndefinedVariable.new(name, args)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ require 'forwardable'
2
+
3
+ module Ravensat
4
+ module Extension
5
+ class BooleanVariable < Variable
6
+ extend Forwardable
7
+ delegate Node.public_instance_methods(false) => :@var_node
8
+ delegate OprNode.public_instance_methods(false) => :@var_node
9
+ delegate VarNode.public_instance_methods(false) => :@var_node
10
+
11
+ def initialize(name, args)
12
+ super
13
+ @var_node = VarNode.new
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,63 @@
1
+ module Ravensat
2
+ module Extension
3
+ class IntegerVariable < Variable
4
+
5
+ attr_reader :var_nodes
6
+ def initialize(name, args)
7
+ super
8
+ return unless args.first.is_a? Range
9
+ @var_nodes = args.first.zip(Array.new(args.first.size){Ravensat::VarNode.new}).to_h
10
+ end
11
+
12
+ def ==(object)
13
+ case object
14
+ when Integer
15
+ return @var_nodes[object]
16
+ when IntegerVariable
17
+ result_formula = Ravensat::InitialNode.new
18
+ duplicated_keys = self.var_nodes.keys & object.var_nodes.keys
19
+
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]})
22
+ end
23
+ return result_formula
24
+ else
25
+ raise ArgumentError
26
+ end
27
+ end
28
+
29
+ def !=(object)
30
+ case object
31
+ when Integer
32
+ return ~(@var_nodes[object])
33
+ when IntegerVariable
34
+ result_formula = Ravensat::InitialNode.new
35
+ duplicated_keys = self.var_nodes.keys & object.var_nodes.keys
36
+
37
+ duplicated_keys.each do |index|
38
+ result_formula &= ~(self.var_nodes[index]) | ~(object.var_nodes[index])
39
+ end
40
+ return result_formula
41
+ else
42
+ raise ArgumentError
43
+ end
44
+ end
45
+
46
+ def only_one
47
+ result_formula = Ravensat::InitialNode.new
48
+ result_formula &= Ravensat::RavenClaw.alo @var_nodes.values
49
+ result_formula &= Ravensat::RavenClaw.amo @var_nodes.values
50
+ result_formula
51
+ end
52
+
53
+ def result
54
+ result = @var_nodes.select{|key, var_node| var_node.value}.keys
55
+ if result.one?
56
+ result.first
57
+ else
58
+ result
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,9 @@
1
+ module Ravensat
2
+ module Extension
3
+ class UndefinedVariable < Variable
4
+ def is_defined?
5
+ false
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ module Ravensat
2
+ module Extension
3
+ class Variable
4
+
5
+ attr_reader :name, :args
6
+ def initialize(name, args)
7
+ @name = name
8
+ @args = args
9
+ end
10
+
11
+ def is_defined?
12
+ true
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Ravensat
2
+ module Extension
3
+ dir = File.dirname(__FILE__) + '/extension'
4
+
5
+ autoload :Domain, dir + '/domain.rb'
6
+ autoload :Variable, dir + '/variable/variable.rb'
7
+ autoload :BooleanVariable, dir + '/variable/boolean_variable.rb'
8
+ autoload :IntegerVariable, dir + '/variable/integer_variable.rb'
9
+ autoload :UndefinedVariable, dir + '/variable/undefined_variable.rb'
10
+
11
+ extend Domain
12
+ end
13
+ end
@@ -1,15 +1,19 @@
1
1
  module Ravensat
2
- class RavenClaw
3
- def initialize; end
4
-
5
- def self.alo(prop_vars)
6
- prop_vars.reduce(:|)
2
+ module RavenClaw
3
+ def self.alo(bool_vars)
4
+ bool_vars.reduce(:|)
7
5
  end
8
6
 
9
- def self.amo(prop_vars)
10
- prop_vars.combination(2).map do |e|
7
+ def self.amo(bool_vars)
8
+ bool_vars.combination(2).map do |e|
11
9
  e.map(&:~@).reduce(:|)
12
10
  end.reduce(:&)
13
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
14
18
  end
15
19
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ravensat
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/ravensat.rb CHANGED
@@ -7,17 +7,12 @@ module Ravensat
7
7
  ast = File.dirname(__FILE__) + '/ravensat/ast'
8
8
  arcteryx = File.dirname(__FILE__) + '/arcteryx'
9
9
 
10
+ require_relative ravensat + "/ast.rb"
11
+ require_relative ravensat + "/dimacs.rb"
12
+
10
13
  autoload :Solver, ravensat + '/solver.rb'
11
- autoload :DimacsEncoder, ravensat + '/dimacs_encoder.rb'
12
- autoload :DimacsDecoder, ravensat + '/dimacs_decoder.rb'
13
14
  autoload :RavenClaw, ravensat + '/ravenclaw.rb'
14
-
15
- autoload :Node, ast + '/node.rb'
16
- autoload :VarNode, ast + '/var_node.rb'
17
- autoload :OprNode, ast + '/opr_node.rb'
18
- autoload :AndNode, ast + '/and_node.rb'
19
- autoload :OrNode, ast + '/or_node.rb'
20
- autoload :NotNode, ast + '/not_node.rb'
15
+ autoload :Extension, ravensat + '/extension.rb'
21
16
 
22
17
  autoload :Arcteryx, arcteryx + '/arcteryx.rb'
23
18
  end
metadata CHANGED
@@ -1,19 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ravensat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.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-16 00:00:00.000000000 Z
11
+ date: 2022-05-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
15
15
  - p99y92og@s.okayama-u.ac.jp
16
- executables: []
16
+ executables:
17
+ - ravensat
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
@@ -28,17 +29,27 @@ files:
28
29
  - bin/console
29
30
  - bin/setup
30
31
  - example/magic_square_3x3.rb
32
+ - exe/ravensat
31
33
  - lib/arcteryx/arcteryx.rb
32
34
  - lib/arcteryx/cnf.rb
33
35
  - lib/ravensat.rb
36
+ - lib/ravensat/ast.rb
34
37
  - lib/ravensat/ast/and_node.rb
38
+ - lib/ravensat/ast/initial_node.rb
35
39
  - lib/ravensat/ast/node.rb
36
40
  - lib/ravensat/ast/not_node.rb
37
41
  - lib/ravensat/ast/opr_node.rb
38
42
  - lib/ravensat/ast/or_node.rb
39
43
  - lib/ravensat/ast/var_node.rb
40
- - lib/ravensat/dimacs_decoder.rb
41
- - lib/ravensat/dimacs_encoder.rb
44
+ - lib/ravensat/dimacs.rb
45
+ - lib/ravensat/dimacs/dimacs_decoder.rb
46
+ - lib/ravensat/dimacs/dimacs_encoder.rb
47
+ - lib/ravensat/extension.rb
48
+ - lib/ravensat/extension/domain.rb
49
+ - lib/ravensat/extension/variable/boolean_variable.rb
50
+ - lib/ravensat/extension/variable/integer_variable.rb
51
+ - lib/ravensat/extension/variable/undefined_variable.rb
52
+ - lib/ravensat/extension/variable/variable.rb
42
53
  - lib/ravensat/ravenclaw.rb
43
54
  - lib/ravensat/solver.rb
44
55
  - lib/ravensat/version.rb