ada_truthy 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []