ada_truthy 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5f60c11c32eb2f78bf12f596577d76cf7800f9f4a555c0bd68ab9ea2d9f5ddea
4
+ data.tar.gz: 86a813a004e5c51817a5bd7ab31d96bc8cfbed92e081d418b80f30d2dd06329a
5
+ SHA512:
6
+ metadata.gz: 1e3f39e7f20a550147c303383d4c4f1f6ab7c2066c53cfa914ec168acd5e0ff466e77f218e0b947a5f2a6a6a9b1e687abc550d645062dbd8bbbffe651a3b6245
7
+ data.tar.gz: 30065c106ffe083fa2e8f285d831a8bb97eaa586a57aa5e63fce4848ad8f32b61b8132a8534b565b765e09b0e3b81c83a1591bc21906496f4b9e482f476ffc39
data/GEM_README.md ADDED
@@ -0,0 +1,30 @@
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
+
data/lib/ada_truthy.rb ADDED
@@ -0,0 +1,4 @@
1
+ require_relative 'logical_gates/logical_gate_extension'
2
+ require_relative 'truth_table/truth_table'
3
+
4
+
@@ -0,0 +1,59 @@
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
@@ -0,0 +1,75 @@
1
+ require_relative 'logical_gate'
2
+
3
+ class TrueClass
4
+ def not
5
+ LogicalGate.not self
6
+ end
7
+
8
+ def or(b, *others)
9
+ LogicalGate.or self, b, others
10
+ end
11
+
12
+ def nor(b, *others)
13
+ LogicalGate.nor self, b, others
14
+ end
15
+
16
+ def and(b, *others)
17
+ LogicalGate.and self, b, others
18
+ end
19
+
20
+ def nand(b, *others)
21
+ LogicalGate.nand self, b, others
22
+ end
23
+
24
+ def xor(b, *others)
25
+ LogicalGate.xor self, b, others
26
+ end
27
+
28
+ def xnor(b, *others)
29
+ LogicalGate.xnor self, b, others
30
+ end
31
+ end
32
+
33
+ class FalseClass
34
+ def not
35
+ LogicalGate.not self
36
+ end
37
+
38
+ def or(b, *others)
39
+ LogicalGate.or self, b, others
40
+ end
41
+
42
+ def nor(b, *others)
43
+ LogicalGate.nor self, b, others
44
+ end
45
+
46
+ def and(b, *others)
47
+ LogicalGate.and self, b, others
48
+ end
49
+
50
+ def nand(b, *others)
51
+ LogicalGate.nand self, b, others
52
+ end
53
+
54
+ def xor(b, *others)
55
+ LogicalGate.xor self, b, others
56
+ end
57
+
58
+ def xnor(b, *others)
59
+ LogicalGate.xnor self, b, others
60
+ end
61
+ end
62
+
63
+ class Integer
64
+ def not
65
+ LogicalGate.not self
66
+ end
67
+
68
+ def or(b, *others)
69
+ LogicalGate.or self, b, others
70
+ end
71
+
72
+ def and(b, *others)
73
+ LogicalGate.and self, b, others
74
+ end
75
+ end
@@ -0,0 +1,216 @@
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
@@ -0,0 +1,2 @@
1
+ class TruthyException < StandardError
2
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ada_truthy
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Roberto W. P. Ribeiro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-03-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Create truth tables and let truthy handle the annoying part. Also, operate
14
+ with logical gates.
15
+ email: rober.will@hotmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - GEM_README.md
20
+ files:
21
+ - GEM_README.md
22
+ - 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
27
+ homepage: https://github.com/roberwil/truthy_gem
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 2.7.7
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.1.6
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Create truth tables and operate with logical gates.
50
+ test_files: []