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 +7 -0
- data/GEM_README.md +30 -0
- data/lib/ada_truthy.rb +4 -0
- data/lib/logical_gates/logical_gate.rb +59 -0
- data/lib/logical_gates/logical_gate_extension.rb +75 -0
- data/lib/truth_table/truth_table.rb +216 -0
- data/lib/truth_table/truthy_exception.rb +2 -0
- metadata +50 -0
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,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
|
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: []
|