ada_truthy 1.0.0 → 1.2.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: 5f60c11c32eb2f78bf12f596577d76cf7800f9f4a555c0bd68ab9ea2d9f5ddea
4
- data.tar.gz: 86a813a004e5c51817a5bd7ab31d96bc8cfbed92e081d418b80f30d2dd06329a
3
+ metadata.gz: 9410ea5b7b775f817f02da291cfc63c9af895d2b2599c42eed5f5eb7100fcfaa
4
+ data.tar.gz: a10674f3776820c10bd7dd4e1d5002bb78006db2ef52a072f7df888b44b158c5
5
5
  SHA512:
6
- metadata.gz: 1e3f39e7f20a550147c303383d4c4f1f6ab7c2066c53cfa914ec168acd5e0ff466e77f218e0b947a5f2a6a6a9b1e687abc550d645062dbd8bbbffe651a3b6245
7
- data.tar.gz: 30065c106ffe083fa2e8f285d831a8bb97eaa586a57aa5e63fce4848ad8f32b61b8132a8534b565b765e09b0e3b81c83a1591bc21906496f4b9e482f476ffc39
6
+ metadata.gz: 911ec53c15825ca5821f229e8f86813a0437dcf390d3c3a0dad80f2003b934baddff5787ff66d80b234833db2741e449077542d43687dc3a2c4b6061a7c8eefa
7
+ data.tar.gz: ca1a86932ee59d704a64eae301504df72680dd104daea056fe1ec7824e642696f95e66f29607e7ee73be1cc52471a2c0105b9db09275eec869cbc661039e480d
data/.idea/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
data/.idea/modules.xml ADDED
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/truthy.iml" filepath="$PROJECT_DIR$/.idea/truthy.iml" />
6
+ <module fileurl="file://$PROJECT_DIR$/../.idea/truthy_gem.iml" filepath="$PROJECT_DIR$/../.idea/truthy_gem.iml" />
7
+ </modules>
8
+ </component>
9
+ </project>
data/.idea/truthy.iml ADDED
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
6
+ <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
7
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
8
+ </content>
9
+ <orderEntry type="jdk" jdkName="rbenv: 2.7.7" jdkType="RUBY_SDK" />
10
+ <orderEntry type="sourceFolder" forTests="false" />
11
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.18.0, rbenv: 2.7.7) [gem]" level="application" />
12
+ <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.1, rbenv: 2.7.7) [gem]" level="application" />
13
+ </component>
14
+ <component name="RakeTasksCache">
15
+ <option name="myRootTask">
16
+ <RakeTaskImpl id="rake">
17
+ <subtasks>
18
+ <RakeTaskImpl description="Run tests" fullCommand="default" id="default" />
19
+ <RakeTaskImpl description="Run tests" fullCommand="test" id="test" />
20
+ </subtasks>
21
+ </RakeTaskImpl>
22
+ </option>
23
+ </component>
24
+ </module>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
5
+ </component>
6
+ </project>
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ada_numbers.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "minitest", "~> 5.0"
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ #t.pattern = "test/*_test.rb"
9
+ end
10
+
11
+ desc "Run tests"
12
+ task :default => :test
@@ -0,0 +1,26 @@
1
+ require_relative 'lib/ada_truthy/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "ada_truthy"
5
+ spec.version = AdaTruthy::VERSION
6
+ spec.summary = "Create truth tables and operate with logical gates."
7
+ spec.description = "Create truth tables and let truthy handle the annoying part. Also, operate with logical gates like AND and OR."
8
+ spec.authors = ["Roberto W. P. Ribeiro"]
9
+ spec.email = ["rober.will@hotmail.com"]
10
+
11
+ # Specify which files should be added to the gem when it is released.
12
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
13
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
14
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
+ end
16
+
17
+ spec.homepage = "https://github.com/roberwil/truthy_gem"
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/roberwil/truthy_gem"
20
+ spec.metadata["changelog_uri"] = "https://github.com/roberwil/truthy_gem/blob/main/CHANGELOG.md"
21
+ spec.licenses = ["MIT"]
22
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.7")
23
+
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ada_truthy"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,62 @@
1
+ module AdaTruthy
2
+ class LogicalGate
3
+ def self.not(a)
4
+ return inot(a) if a.is_a? Integer
5
+ return !a
6
+ end
7
+
8
+ def self.and(a, b, *others)
9
+ return self.iand(a, b, others) if a.is_a? Integer
10
+ return false if (others.include?(false) || !a || !b)
11
+ return true
12
+ end
13
+
14
+ def self.nand(a, b, *others)
15
+ self.not self.and(a, b, others)
16
+ end
17
+
18
+ def self.or(a, b, *others)
19
+ return self.ior(a, b, others) if a.is_a? Integer
20
+ return true if others.include?(true) || a || b
21
+ return false
22
+ end
23
+
24
+ def self.nor(a, b, *others)
25
+ self.not self.or(a, b, others)
26
+ end
27
+
28
+ def self.xor(a, b, *others)
29
+ result = self.base_xor a, b
30
+
31
+ others.each do |term|
32
+ result = base_xor(result, term)
33
+ end
34
+
35
+ return result
36
+ end
37
+
38
+ def self.xnor(a, b, *others)
39
+ return !self.xor(a, b, others)
40
+ end
41
+
42
+ private
43
+
44
+ def self.base_xor(a, b)
45
+ a != b
46
+ end
47
+
48
+ def self.inot(a)
49
+ a == 1 ? 0 : 1
50
+ end
51
+
52
+ def self.iand(a, b, *others)
53
+ return 0 if others.include?(0) || a == 0 || b == 0
54
+ return 1
55
+ end
56
+
57
+ def self.ior(a, b, *others)
58
+ return 1 if others.include?(1) || a == 1 || b == 1
59
+ return 0
60
+ end
61
+ end
62
+ end
@@ -1,6 +1,7 @@
1
1
  require_relative 'logical_gate'
2
2
 
3
3
  class TrueClass
4
+ LogicalGate = AdaTruthy::LogicalGate
4
5
  def not
5
6
  LogicalGate.not self
6
7
  end
@@ -31,6 +32,7 @@ class TrueClass
31
32
  end
32
33
 
33
34
  class FalseClass
35
+ LogicalGate = AdaTruthy::LogicalGate
34
36
  def not
35
37
  LogicalGate.not self
36
38
  end
@@ -0,0 +1,219 @@
1
+ require_relative 'truthy_exception'
2
+ require_relative '../logical_gates/logical_gate_extension'
3
+
4
+ module AdaTruthy
5
+ class TruthTable
6
+ @@letters = %w[A B C D E F G H I J]
7
+
8
+ @@combinations = {
9
+ 2 => 04, 3 => 8, 4 => 16,
10
+ 5 => 32, 6 => 64, 7 => 128,
11
+ 8 => 256, 9 => 512, 10 => 1024
12
+ }
13
+
14
+ MAX_LIMIT = 6
15
+ MIN_LIMIT = 2
16
+ SELF = 'S'
17
+ COMPLEMENT = 'C'
18
+ TRUE_VALUE = 'T'
19
+ FALSE_VALUE = 'F'
20
+
21
+ def initialize(number_of_terms)
22
+ case number_of_terms
23
+ when number_of_terms > MAX_LIMIT
24
+ raise TruthyException, "The maximum number of terms is #{MAX_LIMIT}"
25
+ when number_of_terms < MIN_LIMIT
26
+ raise TruthyException, "The minimum number of terms is #{MIN_LIMIT}"
27
+ end
28
+
29
+ @number_of_terms = number_of_terms
30
+ @number_of_combinations = @@combinations[number_of_terms]
31
+
32
+ @cache = Hash.new
33
+ @formula = Array.new
34
+ @rows = Array.new
35
+
36
+ @using_sum_of_products = true
37
+ @using_product_of_sums = false
38
+
39
+ @number_of_zeros = 0
40
+ @number_of_ones = 0
41
+ end
42
+
43
+ def add_row(*terms)
44
+ table_has_enough_rows = @rows.size == @number_of_combinations
45
+
46
+ if table_has_enough_rows
47
+ raise TruthyException, "There should be only #{@number_of_combinations} rows."
48
+ end
49
+
50
+ right_number_of_terms = terms.size == @number_of_terms + 1
51
+
52
+ unless right_number_of_terms
53
+ raise TruthyException, "There should be only #{@number_of_terms} terms."
54
+ end
55
+
56
+ row = terms
57
+
58
+ unless row_is_valid? row
59
+ raise TruthyException, "The combination #{row} has been used already."
60
+ end
61
+
62
+ @cache = {}
63
+
64
+ row_output = row[-1]
65
+ change_algorithm = (@rows.size == 0).and(row_output == 0)
66
+
67
+ use_product_of_sums if change_algorithm
68
+
69
+ @rows << row
70
+ (row_output == 1) ? @number_of_ones += 1 : @number_of_zeros += 1
71
+
72
+ compute row
73
+ end
74
+
75
+ def check(*terms)
76
+ has_right_number_of_terms = terms.size == @number_of_terms
77
+
78
+ unless has_right_number_of_terms
79
+ raise TruthyException, "There should be only #{@number_of_terms} terms."
80
+ end
81
+
82
+ change_algorithm_if_needed
83
+
84
+ cache_code = TruthTable.get_row_cache_code terms
85
+ cache_result = @cache[cache_code]
86
+
87
+ return cache_result unless cache_result.nil?
88
+
89
+ terms_cursor = 0
90
+ partial_result = true
91
+ result = false
92
+
93
+ if @using_product_of_sums
94
+ partial_result = false
95
+ result = true
96
+ end
97
+
98
+ @formula.each do |t|
99
+ if @using_sum_of_products
100
+ partial_result = (t == SELF ? partial_result.and(terms[terms_cursor]) :
101
+ partial_result.and(!terms[terms_cursor]))
102
+ else
103
+ partial_result = (t == SELF ? partial_result.or(terms[terms_cursor]) :
104
+ partial_result.or(!terms[terms_cursor]))
105
+ end
106
+
107
+ terms_cursor += 1
108
+ next if terms_cursor != @number_of_terms
109
+ terms_cursor = 0
110
+
111
+ if (@using_sum_of_products)
112
+ return true if partial_result
113
+ result = result.or(partial_result)
114
+ partial_result = true
115
+ else
116
+ return false if not partial_result
117
+ result = result.and(partial_result)
118
+ partial_result = false
119
+ end
120
+ end
121
+
122
+ @cache[cache_code] = result
123
+ return result
124
+ end
125
+
126
+ def to_s
127
+ terms_cursor = 0
128
+ partial_result = ''
129
+ result = ''
130
+
131
+ @formula.each do |t|
132
+ if @using_sum_of_products
133
+ partial_result += (t == SELF ? "#{@@letters[terms_cursor]}." : "~#{@@letters[terms_cursor]}.")
134
+ else
135
+ partial_result += (t == SELF ? "#{@@letters[terms_cursor]}+" : "~#{@@letters[terms_cursor]}+")
136
+ end
137
+
138
+ terms_cursor += 1
139
+ next if terms_cursor != @number_of_terms
140
+ terms_cursor = 0
141
+
142
+ result += (@using_sum_of_products ? "(#{partial_result[0...-1]})+" : "(#{partial_result[0...-1]}).")
143
+ partial_result = ''
144
+ end
145
+
146
+ result[0...-1]
147
+ end
148
+
149
+ private
150
+
151
+ def row_is_valid?(row)
152
+ @rows.each do |existing_row|
153
+ is_equal = true
154
+
155
+ (0..existing_row.size - 1).each do |i|
156
+ is_equal = is_equal.and(row[i] == existing_row[i])
157
+ end
158
+
159
+ return false if is_equal
160
+ end
161
+
162
+ return true
163
+ end
164
+
165
+ def compute(row)
166
+ row_output = row[-1]
167
+
168
+ return if @using_sum_of_products.and(row_output != 1)
169
+ return if @using_product_of_sums.and(row_output != 0)
170
+
171
+ (0...row.size - 1).each do |i|
172
+ if @using_sum_of_products
173
+ @formula << (row[i] == 1 ? SELF : COMPLEMENT)
174
+ else
175
+ @formula << (row[i] == 1 ? COMPLEMENT : SELF)
176
+ end
177
+ end
178
+ end
179
+
180
+ def change_algorithm_if_needed
181
+ no_need_to_change = @using_sum_of_products.and(@number_of_zeros == 0).
182
+ or(@using_product_of_sums.and(@number_of_ones == 0))
183
+
184
+ return if no_need_to_change
185
+
186
+ more_zeros = @number_of_zeros > @number_of_ones
187
+
188
+ no_need_to_change = @using_sum_of_products.and(more_zeros).
189
+ or(@using_product_of_sums.and(!more_zeros))
190
+
191
+ return if no_need_to_change
192
+
193
+ more_zeros ? use_sum_of_products : use_product_of_sums
194
+
195
+ @formula = []
196
+ @cache = {}
197
+
198
+ @rows.each do |row|
199
+ compute row
200
+ end
201
+ end
202
+
203
+ def use_sum_of_products
204
+ @using_sum_of_products = true
205
+ @using_product_of_sums = false
206
+ end
207
+
208
+ def use_product_of_sums
209
+ @using_sum_of_products = false
210
+ @using_product_of_sums = true
211
+ end
212
+
213
+ def self.get_row_cache_code(terms)
214
+ code = ''
215
+ terms.each { |term| code += (term ? TRUE_VALUE : FALSE_VALUE) }
216
+ return code
217
+ end
218
+ end
219
+ end
@@ -0,0 +1,4 @@
1
+ module AdaTruthy
2
+ class TruthyException < StandardError
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module AdaTruthy
2
+ VERSION = "1.2.0"
3
+ end
data/lib/ada_truthy.rb CHANGED
@@ -1,4 +1,5 @@
1
- require_relative 'logical_gates/logical_gate_extension'
2
- require_relative 'truth_table/truth_table'
1
+ require_relative 'ada_truthy/version'
2
+ require_relative 'ada_truthy/logical_gates/logical_gate_extension'
3
+ require_relative 'ada_truthy/truth_table/truth_table'
3
4
 
4
5
 
metadata CHANGED
@@ -1,33 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ada_truthy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto W. P. Ribeiro
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-22 00:00:00.000000000 Z
11
+ date: 2023-03-31 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Create truth tables and let truthy handle the annoying part. Also, operate
14
- with logical gates.
15
- email: rober.will@hotmail.com
14
+ with logical gates like AND and OR.
15
+ email:
16
+ - rober.will@hotmail.com
16
17
  executables: []
17
18
  extensions: []
18
- extra_rdoc_files:
19
- - GEM_README.md
19
+ extra_rdoc_files: []
20
20
  files:
21
- - GEM_README.md
21
+ - ".idea/.gitignore"
22
+ - ".idea/modules.xml"
23
+ - ".idea/truthy.iml"
24
+ - ".idea/vcs.xml"
25
+ - Gemfile
26
+ - Rakefile
27
+ - ada_truthy.gemspec
28
+ - bin/console
29
+ - bin/setup
22
30
  - lib/ada_truthy.rb
23
- - lib/logical_gates/logical_gate.rb
24
- - lib/logical_gates/logical_gate_extension.rb
25
- - lib/truth_table/truth_table.rb
26
- - lib/truth_table/truthy_exception.rb
31
+ - lib/ada_truthy/logical_gates/logical_gate.rb
32
+ - lib/ada_truthy/logical_gates/logical_gate_extension.rb
33
+ - lib/ada_truthy/truth_table/truth_table.rb
34
+ - lib/ada_truthy/truth_table/truthy_exception.rb
35
+ - lib/ada_truthy/version.rb
27
36
  homepage: https://github.com/roberwil/truthy_gem
28
37
  licenses:
29
38
  - MIT
30
- metadata: {}
39
+ metadata:
40
+ homepage_uri: https://github.com/roberwil/truthy_gem
41
+ source_code_uri: https://github.com/roberwil/truthy_gem
42
+ changelog_uri: https://github.com/roberwil/truthy_gem/blob/main/CHANGELOG.md
31
43
  post_install_message:
32
44
  rdoc_options: []
33
45
  require_paths:
data/GEM_README.md DELETED
@@ -1,30 +0,0 @@
1
- # Truthy Gem
2
-
3
- ### What is truthy anyway?
4
-
5
- Well, think of a truth table you just invented, you put your 1s and 0s and **Truthy** figures out which formula works
6
- for the table.
7
-
8
- | A | B | C |
9
- |-----|-----|-----|
10
- | 0 | 0 | 1 |
11
- | 1 | 0 | 1 |
12
- | 1 | 1 | 0 |
13
- | 0 | 1 | 0 |
14
-
15
- If you create the above table with **Truthy**, it will know what to do so that your table makes sense.
16
- Also, **Truthy** has implementations for the following logical gates: `and`, `or`, `not`,
17
- `xor`, `nand`, `nor`, and `xnor`.
18
-
19
- ### Where can I use it?
20
-
21
- - Access matrices are a good example;
22
- - Other examples are just day-to-day comparisons you do with booleans in your code.
23
-
24
- Let your imagination make good use of Truthy.
25
-
26
- ### Where do I learn how to use it?
27
-
28
- Check the documentation [here](https://github.com/roberwil/truthy_gem/blob/main/README.md).
29
- Remember, **Truthy** is the way.
30
-
@@ -1,59 +0,0 @@
1
- class LogicalGate
2
- def self.not(a)
3
- return inot(a) if a.is_a? Integer
4
- return !a
5
- end
6
-
7
- def self.and(a, b, *others)
8
- return self.iand(a, b, others) if a.is_a? Integer
9
- return false if (others.include?(false) || !a || !b)
10
- return true
11
- end
12
-
13
- def self.nand(a, b, *others)
14
- self.not self.and(a, b, others)
15
- end
16
-
17
- def self.or(a, b, *others)
18
- return self.ior(a, b, others) if a.is_a? Integer
19
- return true if others.include?(true) || a || b
20
- return false
21
- end
22
-
23
- def self.nor(a, b, *others)
24
- self.not self.or(a, b, others)
25
- end
26
-
27
- def self.xor(a, b, *others)
28
- result = self.base_xor a, b
29
-
30
- others.each do |term|
31
- result = base_xor(result, term)
32
- end
33
-
34
- return result
35
- end
36
-
37
- def self.xnor(a, b, *others)
38
- return !self.xor(a, b, others)
39
- end
40
-
41
- private
42
- def self.base_xor(a, b)
43
- a != b
44
- end
45
-
46
- def self.inot(a)
47
- a == 1? 0 : 1
48
- end
49
-
50
- def self.iand(a, b, *others)
51
- return 0 if others.include?(0) || a == 0 || b == 0
52
- return 1
53
- end
54
-
55
- def self.ior(a, b, *others)
56
- return 1 if others.include?(1) || a == 1 || b == 1
57
- return 0
58
- end
59
- end
@@ -1,216 +0,0 @@
1
- require_relative 'truthy_exception'
2
- require_relative '../logical_gates/logical_gate_extension'
3
-
4
- class TruthTable
5
- @@letters = %w[A B C D E F G H I J]
6
-
7
- @@combinations = {
8
- 2 => 04, 3 => 8, 4 => 16,
9
- 5 => 32, 6 => 64, 7 => 128,
10
- 8 => 256, 9 => 512, 10 => 1024
11
- }
12
-
13
- MAX_LIMIT = 6
14
- MIN_LIMIT = 2
15
- SELF = 'S'
16
- COMPLEMENT = 'C'
17
- TRUE_VALUE = 'T'
18
- FALSE_VALUE = 'F'
19
-
20
- def initialize(number_of_terms)
21
- case number_of_terms
22
- when number_of_terms > MAX_LIMIT
23
- raise TruthyException, "The maximum number of terms is #{MAX_LIMIT}"
24
- when number_of_terms < MIN_LIMIT
25
- raise TruthyException, "The minimum number of terms is #{MIN_LIMIT}"
26
- end
27
-
28
- @number_of_terms = number_of_terms
29
- @number_of_combinations = @@combinations[number_of_terms]
30
-
31
- @cache = Hash.new
32
- @formula = Array.new
33
- @rows = Array.new
34
-
35
- @using_sum_of_products = true
36
- @using_product_of_sums = false
37
-
38
- @number_of_zeros = 0
39
- @number_of_ones = 0
40
- end
41
-
42
- def add_row(*terms)
43
- table_has_enough_rows = @rows.size == @number_of_combinations
44
-
45
- if table_has_enough_rows
46
- raise TruthyException, "There should be only #{@number_of_combinations} rows."
47
- end
48
-
49
- right_number_of_terms = terms.size == @number_of_terms + 1
50
-
51
- unless right_number_of_terms
52
- raise TruthyException, "There should be only #{@number_of_terms} terms."
53
- end
54
-
55
- row = terms
56
-
57
- unless row_is_valid? row
58
- raise TruthyException, "The combination #{row} has been used already."
59
- end
60
-
61
- @cache = {}
62
-
63
- row_output = row[-1]
64
- change_algorithm = (@rows.size == 0).and(row_output == 0)
65
-
66
- use_product_of_sums if change_algorithm
67
-
68
- @rows << row
69
- (row_output == 1)? @number_of_ones += 1 : @number_of_zeros += 1
70
-
71
- compute row
72
- end
73
-
74
- def check(*terms)
75
- has_right_number_of_terms = terms.size == @number_of_terms
76
-
77
- unless has_right_number_of_terms
78
- raise TruthyException, "There should be only #{@number_of_terms} terms."
79
- end
80
-
81
- change_algorithm_if_needed
82
-
83
- cache_code = TruthTable.get_row_cache_code terms
84
- cache_result = @cache[cache_code]
85
-
86
- return cache_result unless cache_result.nil?
87
-
88
- terms_cursor = 0
89
- partial_result = true
90
- result = false
91
-
92
- if @using_product_of_sums
93
- partial_result = false
94
- result = true
95
- end
96
-
97
- @formula.each do |t|
98
- if @using_sum_of_products
99
- partial_result = (t == SELF ? partial_result.and(terms[terms_cursor]) :
100
- partial_result.and(!terms[terms_cursor]))
101
- else
102
- partial_result = (t == SELF ? partial_result.or(terms[terms_cursor]) :
103
- partial_result.or(!terms[terms_cursor]))
104
- end
105
-
106
- terms_cursor += 1
107
- next if terms_cursor != @number_of_terms
108
- terms_cursor = 0
109
-
110
- if (@using_sum_of_products)
111
- return true if partial_result
112
- result = result.or(partial_result)
113
- partial_result = true
114
- else
115
- return false if not partial_result
116
- result = result.and(partial_result)
117
- partial_result = false
118
- end
119
- end
120
-
121
- @cache[cache_code] = result
122
- return result
123
- end
124
-
125
- def to_s
126
- terms_cursor = 0
127
- partial_result = ''
128
- result = ''
129
-
130
- @formula.each do |t|
131
- if @using_sum_of_products
132
- partial_result += (t == SELF ? "#{@@letters[terms_cursor]}." : "~#{@@letters[terms_cursor]}.")
133
- else
134
- partial_result += (t == SELF ? "#{@@letters[terms_cursor]}+" : "~#{@@letters[terms_cursor]}+")
135
- end
136
-
137
- terms_cursor += 1
138
- next if terms_cursor != @number_of_terms
139
- terms_cursor = 0
140
-
141
- result += (@using_sum_of_products? "(#{partial_result[0...-1]})+" : "(#{partial_result[0...-1]}).")
142
- partial_result = ''
143
- end
144
-
145
- result[0...-1]
146
- end
147
-
148
- private
149
- def row_is_valid?(row)
150
- @rows.each do |existing_row|
151
- is_equal = true
152
-
153
- (0..existing_row.size - 1).each do |i|
154
- is_equal = is_equal.and(row[i] == existing_row[i])
155
- end
156
-
157
- return false if is_equal
158
- end
159
-
160
- return true
161
- end
162
-
163
- def compute(row)
164
- row_output = row[-1]
165
-
166
- return if @using_sum_of_products.and(row_output != 1)
167
- return if @using_product_of_sums.and(row_output != 0)
168
-
169
- (0...row.size - 1).each do |i|
170
- if @using_sum_of_products
171
- @formula << (row[i] == 1 ? SELF : COMPLEMENT)
172
- else
173
- @formula << (row[i] == 1 ? COMPLEMENT : SELF)
174
- end
175
- end
176
- end
177
-
178
- def change_algorithm_if_needed
179
- no_need_to_change = @using_sum_of_products.and(@number_of_zeros == 0).
180
- or(@using_product_of_sums.and(@number_of_ones == 0))
181
-
182
- return if no_need_to_change
183
-
184
- more_zeros = @number_of_zeros > @number_of_ones
185
-
186
- no_need_to_change = @using_sum_of_products.and(more_zeros).
187
- or(@using_product_of_sums.and(!more_zeros))
188
-
189
- return if no_need_to_change
190
-
191
- more_zeros ? use_sum_of_products : use_product_of_sums
192
-
193
- @formula = []
194
- @cache = {}
195
-
196
- @rows.each do |row|
197
- compute row
198
- end
199
- end
200
-
201
- def use_sum_of_products
202
- @using_sum_of_products = true
203
- @using_product_of_sums = false
204
- end
205
-
206
- def use_product_of_sums
207
- @using_sum_of_products = false
208
- @using_product_of_sums = true
209
- end
210
-
211
- def self.get_row_cache_code(terms)
212
- code = ''
213
- terms.each { |term| code += (term ? TRUE_VALUE : FALSE_VALUE) }
214
- return code
215
- end
216
- end
@@ -1,2 +0,0 @@
1
- class TruthyException < StandardError
2
- end