lm 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/lm/bin_func.rb +48 -0
- data/lib/lm/implicant_chart.rb +90 -0
- data/lib/lm/minimizer.rb +53 -0
- data/lib/lm/output_string.rb +29 -0
- data/lib/lm/petrick.rb +73 -0
- data/lib/lm/pos.rb +79 -0
- data/lib/lm/product.rb +24 -0
- data/lib/lm/quine_mc_cluskey.rb +20 -0
- data/lib/lm/string_122_result_selector.rb +37 -0
- data/lib/lm/sum.rb +43 -0
- data/lib/lm/sum_of_products.rb +33 -0
- data/lib/lm/variable.rb +68 -0
- data/lib/lm/version.rb +5 -0
- data/lib/lm.rb +21 -0
- data/lm.gemspec +34 -0
- data/spec/lm_spec.rb +40 -0
- data/spec/spec_helper.rb +15 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 82e0500fd99881105260a6367a282628a4c9bf5365ddc717c219fe39e1df0f19
|
4
|
+
data.tar.gz: f69499c220e4a27a2a435a6820a708d458491bf0cde568d9fb9c4ddd277f13ed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af2de852aeaf14c17783868468dd34405ccde647db085cc2fd3c1999b91c6b4aac5ec608ed9a15116049840c436979e799f7c3894608c8dd798b727e61940ba1
|
7
|
+
data.tar.gz: e57c6b4f50c406ca6c1861fa9f530da28706619c3c92d1e1c9fe64e170fa195d3aec9179bfc55331afe238734d857b41a7fab8545a60a3c0cb7e24dc76307f61
|
data/Gemfile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "lm"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/lm/bin_func.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class BinFunc
|
5
|
+
def initialize(products)
|
6
|
+
@products = products.arr
|
7
|
+
end
|
8
|
+
|
9
|
+
def inputlen
|
10
|
+
@products.first.vars.count
|
11
|
+
end
|
12
|
+
|
13
|
+
def max
|
14
|
+
(1 << inputlen) - 1
|
15
|
+
end
|
16
|
+
|
17
|
+
def apply(product, bitstr)
|
18
|
+
raise "len mismatch" if bitstr.length != product.vars.length
|
19
|
+
|
20
|
+
result = 1
|
21
|
+
|
22
|
+
inputlen.times do |x|
|
23
|
+
next if product.vars[x].invalid?
|
24
|
+
|
25
|
+
val = bitstr[x].to_i
|
26
|
+
|
27
|
+
val = ~val if product.vars[x].value == "0"
|
28
|
+
|
29
|
+
result &= val
|
30
|
+
end
|
31
|
+
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
def evaluate(num)
|
36
|
+
raise "number too large" if num > max
|
37
|
+
|
38
|
+
bitstr = num.to_s(2).rjust(inputlen, "0")
|
39
|
+
|
40
|
+
result = 0
|
41
|
+
@products.each do |product|
|
42
|
+
result |= apply(product, bitstr)
|
43
|
+
end
|
44
|
+
|
45
|
+
result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class ImplicantChart
|
5
|
+
def initialize(chart, length:, step: 0)
|
6
|
+
@chart = chart
|
7
|
+
@step = step
|
8
|
+
@length = length
|
9
|
+
end
|
10
|
+
|
11
|
+
def buckets
|
12
|
+
@buckets ||= begin
|
13
|
+
rr = {}
|
14
|
+
@chart.each do |k, v|
|
15
|
+
ones = v.count("1")
|
16
|
+
rr[ones] ||= {}
|
17
|
+
rr[ones][k] = v
|
18
|
+
end
|
19
|
+
# p rr
|
20
|
+
rr
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def keys
|
25
|
+
Set.new(@chart.keys)
|
26
|
+
end
|
27
|
+
|
28
|
+
def reduced
|
29
|
+
rr = {}
|
30
|
+
touched = Set.new
|
31
|
+
@length.times do |x|
|
32
|
+
next if buckets[x].nil?
|
33
|
+
next if buckets[x + 1].nil?
|
34
|
+
|
35
|
+
buckets[x].each do |num, pattern|
|
36
|
+
buckets[x + 1].each do |num2, pattern2|
|
37
|
+
diffcount = 0
|
38
|
+
last = 0
|
39
|
+
@length.times do |col|
|
40
|
+
if pattern[col] == "-" && pattern2[col] != "-" ||
|
41
|
+
pattern2[col] == "-" && pattern[col] != "-"
|
42
|
+
diffcount += 2
|
43
|
+
last = col
|
44
|
+
end
|
45
|
+
next unless pattern[col] == "1" && pattern2[col] == "0" ||
|
46
|
+
pattern2[col] == "1" && pattern[col] == "0"
|
47
|
+
|
48
|
+
diffcount += 1
|
49
|
+
last = col
|
50
|
+
end
|
51
|
+
next unless diffcount == 1
|
52
|
+
|
53
|
+
str = pattern.dup
|
54
|
+
str[last] = "-"
|
55
|
+
rr["#{num},#{num2}".split(",").sort.join(",").to_str] = str
|
56
|
+
touched << num.to_s
|
57
|
+
touched << num2.to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
@chart.each do |k, v|
|
63
|
+
next if touched.include? k
|
64
|
+
|
65
|
+
rr[k] = v
|
66
|
+
end
|
67
|
+
ImplicantChart.new(rr, step: @step + 1, length: @length)
|
68
|
+
end
|
69
|
+
|
70
|
+
def soplist
|
71
|
+
rr = {}
|
72
|
+
@chart.each do |k, v|
|
73
|
+
rr[k] = Product.new(v)
|
74
|
+
end
|
75
|
+
rr
|
76
|
+
end
|
77
|
+
|
78
|
+
def variables
|
79
|
+
@variables ||= begin
|
80
|
+
vars = Set.new
|
81
|
+
@chart.each_key do |x|
|
82
|
+
x.split(",").each do |name|
|
83
|
+
vars << name
|
84
|
+
end
|
85
|
+
end
|
86
|
+
vars
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/lm/minimizer.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class Minimizer
|
5
|
+
def initialize(output_str)
|
6
|
+
@output_str = output_str
|
7
|
+
end
|
8
|
+
|
9
|
+
def output_string
|
10
|
+
OutputString.new(@output_str)
|
11
|
+
end
|
12
|
+
|
13
|
+
def canonical
|
14
|
+
output_string.sop
|
15
|
+
end
|
16
|
+
|
17
|
+
def qcm
|
18
|
+
QuineMcCluskey.new(canonical.implicants)
|
19
|
+
end
|
20
|
+
|
21
|
+
def implicants
|
22
|
+
qcm.prime_implicants
|
23
|
+
end
|
24
|
+
|
25
|
+
def pm
|
26
|
+
Petrick.new(implicants)
|
27
|
+
end
|
28
|
+
|
29
|
+
def pos
|
30
|
+
POS.new(pm.string122)
|
31
|
+
end
|
32
|
+
|
33
|
+
def reduced_sum
|
34
|
+
pos.expand.reduce
|
35
|
+
end
|
36
|
+
|
37
|
+
def calculator
|
38
|
+
String122ResultSelector.new(implicants, reduced_sum)
|
39
|
+
end
|
40
|
+
|
41
|
+
def shortest
|
42
|
+
calculator.shortest
|
43
|
+
end
|
44
|
+
|
45
|
+
def evaluate(input)
|
46
|
+
BinFunc.new(shortest).evaluate(input)
|
47
|
+
end
|
48
|
+
|
49
|
+
def canonical_evaluate(input)
|
50
|
+
BinFunc.new(output_string.sop).evaluate(input)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class OutputString
|
5
|
+
def initialize(str)
|
6
|
+
@str = str
|
7
|
+
end
|
8
|
+
|
9
|
+
def bitcount
|
10
|
+
Math.log(@str.length, 2).ceil
|
11
|
+
end
|
12
|
+
|
13
|
+
def sop
|
14
|
+
res = SumOfProducts.new
|
15
|
+
@str.length.times do |x|
|
16
|
+
bitbreak = x.to_s(2).rjust(bitcount, "0")
|
17
|
+
next if @str[x] == "0"
|
18
|
+
|
19
|
+
prod = Product.new(bitbreak)
|
20
|
+
res << prod
|
21
|
+
end
|
22
|
+
res
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s(v = nil)
|
26
|
+
sop.to_s(v)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/lm/petrick.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class Petrick
|
5
|
+
def initialize(chart)
|
6
|
+
@chart = chart
|
7
|
+
end
|
8
|
+
|
9
|
+
def grouplist
|
10
|
+
@grouplist ||= @chart.keys
|
11
|
+
end
|
12
|
+
|
13
|
+
# factors from the petrick table
|
14
|
+
def factors
|
15
|
+
factorlist = []
|
16
|
+
uncovered_columns.each do |var|
|
17
|
+
factor = []
|
18
|
+
grouplist.each_with_index do |group, idx|
|
19
|
+
vlist = Set.new(group.split(","))
|
20
|
+
factor << [idx] if vlist.include?(var)
|
21
|
+
end
|
22
|
+
|
23
|
+
factorlist << factor
|
24
|
+
end
|
25
|
+
factorlist + essential_rows.map { |x| [[x]] }
|
26
|
+
end
|
27
|
+
|
28
|
+
def essential_columns
|
29
|
+
@essential_columns ||= begin
|
30
|
+
varcounts = {}
|
31
|
+
grouplist.each_with_index do |group, _idx|
|
32
|
+
group.split(",").each do |v|
|
33
|
+
varcounts[v] ||= 0
|
34
|
+
varcounts[v] += 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
varcounts.select { |_k, v| v == 1 }.to_h.keys
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def essential_rows
|
42
|
+
@essential_rows ||= begin
|
43
|
+
rows = []
|
44
|
+
|
45
|
+
essential_columns.each do |x|
|
46
|
+
grouplist.each_with_index do |group, idx|
|
47
|
+
vars = Set.new(group.split(","))
|
48
|
+
if vars.include?(x)
|
49
|
+
rows << idx
|
50
|
+
break
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rows
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def uncovered_columns
|
59
|
+
@uncovered_columns ||= begin
|
60
|
+
touched = Set.new
|
61
|
+
essential_rows.each do |idx|
|
62
|
+
touched += grouplist.to_a[idx].split(",")
|
63
|
+
end
|
64
|
+
|
65
|
+
@chart.variables - touched
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def string122
|
70
|
+
factors.map { |sums| sums.map { |prducts| prducts.map { |x| (x.ord + 48).chr }.join("") }.join("+") }.join(",")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/lm/pos.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
# definitions
|
5
|
+
# A = factor
|
6
|
+
# AB = term
|
7
|
+
# AB+C = sum
|
8
|
+
# (AB + C)(D + E) = product of sums
|
9
|
+
# AB+C,D+E
|
10
|
+
|
11
|
+
class POS
|
12
|
+
def initialize(str)
|
13
|
+
@str = str
|
14
|
+
end
|
15
|
+
|
16
|
+
def sum_array
|
17
|
+
@sum_array ||= @str.split(",")
|
18
|
+
end
|
19
|
+
|
20
|
+
def termhash
|
21
|
+
@termhash ||= begin
|
22
|
+
res = {}
|
23
|
+
sum_array.each do |sum|
|
24
|
+
terms = sum.split("+")
|
25
|
+
terms.each do |term|
|
26
|
+
res[term] ||= Set.new
|
27
|
+
terms.each do |x|
|
28
|
+
next if x == term
|
29
|
+
|
30
|
+
res[term] << x
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
res
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def apply_factorize
|
39
|
+
newarray = []
|
40
|
+
seenkeys = Set.new
|
41
|
+
|
42
|
+
termhash.each do |key, value|
|
43
|
+
next if seenkeys.include? key
|
44
|
+
|
45
|
+
seenkeys << key
|
46
|
+
value.each do |factor|
|
47
|
+
seenkeys << factor
|
48
|
+
end
|
49
|
+
newarray << "#{key}+#{value.to_a.join("")}"
|
50
|
+
end
|
51
|
+
|
52
|
+
POS.new(newarray.join(","))
|
53
|
+
end
|
54
|
+
|
55
|
+
# return SOP
|
56
|
+
def expand
|
57
|
+
# puts "EXPAND"
|
58
|
+
arr = sum_array
|
59
|
+
|
60
|
+
loop do
|
61
|
+
break if arr.length == 1
|
62
|
+
|
63
|
+
aterms = arr[0].split("+")
|
64
|
+
bterms = arr[1].split("+")
|
65
|
+
|
66
|
+
newterms = aterms.product(bterms).map do |x|
|
67
|
+
x.join("").split("").uniq.join("")
|
68
|
+
end
|
69
|
+
|
70
|
+
newsum = newterms.join("+")
|
71
|
+
|
72
|
+
arr = [newsum] + arr[2..]
|
73
|
+
# p arr
|
74
|
+
end
|
75
|
+
|
76
|
+
Sum.new(arr.first)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/lm/product.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class Product
|
5
|
+
attr_reader :str
|
6
|
+
|
7
|
+
def initialize(str)
|
8
|
+
@str = str
|
9
|
+
end
|
10
|
+
|
11
|
+
def vars
|
12
|
+
@str.split("").each_with_index.map do |x, i|
|
13
|
+
Variable.new(x, i)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s(v = nil)
|
18
|
+
joiner = ""
|
19
|
+
|
20
|
+
joiner = " & " if v == :verilog || (v.is_a?(Hash) && v[:verilog])
|
21
|
+
vars.map { |x| x.to_s(v) }.compact.join(joiner)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class QuineMcCluskey
|
5
|
+
def initialize(chart)
|
6
|
+
@chart = chart
|
7
|
+
end
|
8
|
+
|
9
|
+
def prime_implicants
|
10
|
+
curchart = @chart
|
11
|
+
loop do
|
12
|
+
newchart = curchart.reduced
|
13
|
+
break if newchart.keys == curchart.keys
|
14
|
+
|
15
|
+
curchart = newchart
|
16
|
+
end
|
17
|
+
curchart
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class String122ResultSelector
|
5
|
+
def initialize(pm, sum)
|
6
|
+
@pm = pm
|
7
|
+
@sum = sum
|
8
|
+
end
|
9
|
+
|
10
|
+
def chart
|
11
|
+
@chart ||= @pm.soplist.map do |k, v|
|
12
|
+
{
|
13
|
+
columns: k,
|
14
|
+
product: v
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def sum_list
|
20
|
+
@sum.str.split("+").map do |term|
|
21
|
+
term.split("").map do |str122|
|
22
|
+
idx = str122.ord - 48
|
23
|
+
chart[idx][:product]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def sum_strings
|
29
|
+
sum_list.each_with_index.map { |x, i| { str: x.join("+"), idx: i } }
|
30
|
+
end
|
31
|
+
|
32
|
+
def shortest
|
33
|
+
idx = sum_strings.min_by { |x| x[:str].length }[:idx]
|
34
|
+
SumOfProducts.new(sum_list[idx])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/lm/sum.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class Sum
|
5
|
+
attr_reader :str
|
6
|
+
|
7
|
+
def initialize(str)
|
8
|
+
@str = str
|
9
|
+
end
|
10
|
+
|
11
|
+
def product_list
|
12
|
+
@str.split("+").map { |x| Set.new(x.split("")) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def by_length
|
16
|
+
product_list.sort(&:length)
|
17
|
+
end
|
18
|
+
|
19
|
+
def reduce
|
20
|
+
res = []
|
21
|
+
arr = by_length
|
22
|
+
|
23
|
+
loop do
|
24
|
+
cur = arr.shift
|
25
|
+
|
26
|
+
newarr = []
|
27
|
+
arr.each do |x|
|
28
|
+
# remove supersets (X + XY = X)
|
29
|
+
next if cur.subset?(x)
|
30
|
+
|
31
|
+
newarr << x
|
32
|
+
end
|
33
|
+
res << cur
|
34
|
+
arr = newarr
|
35
|
+
|
36
|
+
break if arr.length.zero?
|
37
|
+
end
|
38
|
+
|
39
|
+
res
|
40
|
+
Sum.new(res.map { |x| x.to_a.join("") }.join("+"))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class SumOfProducts
|
5
|
+
attr_reader :arr
|
6
|
+
|
7
|
+
def initialize(arr = [])
|
8
|
+
@arr = arr
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(value)
|
12
|
+
insert(value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def insert(product)
|
16
|
+
@arr << product
|
17
|
+
end
|
18
|
+
|
19
|
+
def implicants
|
20
|
+
result = {}
|
21
|
+
@arr.each do |x|
|
22
|
+
result[x.str.to_i(2).to_s] = x.str
|
23
|
+
end
|
24
|
+
ImplicantChart.new(result, length: @arr.first.str.length)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s(v = nil)
|
28
|
+
joiner = "+"
|
29
|
+
joiner = " | " if v == :verilog || (v.is_a?(Hash) && v[:verilog])
|
30
|
+
@arr.map { |x| x.to_s(v) }.join(joiner)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/lm/variable.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lm
|
4
|
+
class Variable
|
5
|
+
attr_reader :value
|
6
|
+
|
7
|
+
def initialize(value, pos)
|
8
|
+
@value = value
|
9
|
+
@pos = pos
|
10
|
+
end
|
11
|
+
|
12
|
+
def invalid?
|
13
|
+
@value != "1" && @value != "0"
|
14
|
+
end
|
15
|
+
|
16
|
+
def notop
|
17
|
+
@value == "0" ? "~" : ""
|
18
|
+
end
|
19
|
+
|
20
|
+
def bar
|
21
|
+
@value == "0" ? "\u0305" : ""
|
22
|
+
end
|
23
|
+
|
24
|
+
def subscript
|
25
|
+
result = ""
|
26
|
+
|
27
|
+
@pos.to_s.split("").each do |digit|
|
28
|
+
result += (0x2080 + digit.to_i).chr("UTF-8")
|
29
|
+
end
|
30
|
+
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
LETTERS = %(ABCDEFGHJKLMNPQRSTUVWXYZ)
|
35
|
+
|
36
|
+
def to_abc(letters = LETTERS)
|
37
|
+
return to_x if @pos >= letters.length
|
38
|
+
return "" if invalid?
|
39
|
+
|
40
|
+
letters[@pos] + bar
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_x(input = "X")
|
44
|
+
return "" if invalid?
|
45
|
+
|
46
|
+
input.to_s + bar + subscript
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_verilog(letter)
|
50
|
+
return nil if invalid?
|
51
|
+
|
52
|
+
"#{notop}#{letter}[#{@pos}]"
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s(input = nil)
|
56
|
+
input ||= LETTERS
|
57
|
+
if input.is_a?(String) && input.end_with?("#")
|
58
|
+
to_x(input[0])
|
59
|
+
elsif input == :verilog
|
60
|
+
to_verilog(x)
|
61
|
+
elsif input.is_a?(Hash) && input[:verilog]
|
62
|
+
to_verilog(input[:verilog])
|
63
|
+
else
|
64
|
+
to_abc(input)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/lm/version.rb
ADDED
data/lib/lm.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
|
5
|
+
module Lm
|
6
|
+
class Error < StandardError; end
|
7
|
+
end
|
8
|
+
|
9
|
+
require_relative "lm/version"
|
10
|
+
require_relative "lm/variable"
|
11
|
+
require_relative "lm/product"
|
12
|
+
require_relative "lm/implicant_chart"
|
13
|
+
require_relative "lm/quine_mc_cluskey"
|
14
|
+
require_relative "lm/sum_of_products"
|
15
|
+
require_relative "lm/petrick"
|
16
|
+
require_relative "lm/output_string"
|
17
|
+
require_relative "lm/pos"
|
18
|
+
require_relative "lm/sum"
|
19
|
+
require_relative "lm/string_122_result_selector"
|
20
|
+
require_relative "lm/bin_func"
|
21
|
+
require_relative "lm/minimizer"
|
data/lm.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/lm/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "lm"
|
7
|
+
spec.version = Lm::VERSION
|
8
|
+
spec.authors = ["David Siaw"]
|
9
|
+
spec.email = ["davidsiaw@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Logic Minimizer"
|
12
|
+
spec.description = "Logic Minimizer Library"
|
13
|
+
spec.homepage = "https://github.com/davidsiaw/lm"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 2.6.0"
|
16
|
+
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
|
+
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/davidsiaw/lm"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/davidsiaw/lm"
|
22
|
+
|
23
|
+
spec.files = Dir["{data,exe,lib,bin}/**/*"] + %w[Gemfile lm.gemspec]
|
24
|
+
spec.test_files = Dir["spec/**/*"]
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
# Uncomment to register a new dependency of your gem
|
30
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
31
|
+
|
32
|
+
# For more information and examples about making a new gem, check out our
|
33
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
34
|
+
end
|
data/spec/lm_spec.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Lm do
|
4
|
+
it "has a version number" do
|
5
|
+
expect(Lm::VERSION).not_to be nil
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns expected xor" do
|
9
|
+
min = Lm::Minimizer.new("0110")
|
10
|
+
expect(min.evaluate(0)).to eq 0
|
11
|
+
expect(min.evaluate(1)).to eq 1
|
12
|
+
expect(min.evaluate(2)).to eq 1
|
13
|
+
expect(min.evaluate(3)).to eq 0
|
14
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "~a[0] & a[1] | a[0] & ~a[1]"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns expected and" do
|
18
|
+
min = Lm::Minimizer.new("0001")
|
19
|
+
expect(min.evaluate(0)).to eq 0
|
20
|
+
expect(min.evaluate(1)).to eq 0
|
21
|
+
expect(min.evaluate(2)).to eq 0
|
22
|
+
expect(min.evaluate(3)).to eq 1
|
23
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "a[0] & a[1]"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns expected or" do
|
27
|
+
min = Lm::Minimizer.new("0111")
|
28
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "a[1] | a[0]"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns expected nand" do
|
32
|
+
min = Lm::Minimizer.new("1110")
|
33
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "~a[0] | ~a[1]"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "return canonical" do
|
37
|
+
min = Lm::Minimizer.new("1110")
|
38
|
+
expect(min.canonical.to_s(verilog: "a")).to eq "~a[0] & ~a[1] | ~a[0] & a[1] | a[0] & ~a[1]"
|
39
|
+
end
|
40
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lm"
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
# Enable flags like --only-failures and --next-failure
|
7
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
8
|
+
|
9
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
10
|
+
config.disable_monkey_patching!
|
11
|
+
|
12
|
+
config.expect_with :rspec do |c|
|
13
|
+
c.syntax = :expect
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Siaw
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-12-23 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Logic Minimizer Library
|
14
|
+
email:
|
15
|
+
- davidsiaw@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- Gemfile
|
21
|
+
- bin/console
|
22
|
+
- bin/setup
|
23
|
+
- lib/lm.rb
|
24
|
+
- lib/lm/bin_func.rb
|
25
|
+
- lib/lm/implicant_chart.rb
|
26
|
+
- lib/lm/minimizer.rb
|
27
|
+
- lib/lm/output_string.rb
|
28
|
+
- lib/lm/petrick.rb
|
29
|
+
- lib/lm/pos.rb
|
30
|
+
- lib/lm/product.rb
|
31
|
+
- lib/lm/quine_mc_cluskey.rb
|
32
|
+
- lib/lm/string_122_result_selector.rb
|
33
|
+
- lib/lm/sum.rb
|
34
|
+
- lib/lm/sum_of_products.rb
|
35
|
+
- lib/lm/variable.rb
|
36
|
+
- lib/lm/version.rb
|
37
|
+
- lm.gemspec
|
38
|
+
- spec/lm_spec.rb
|
39
|
+
- spec/spec_helper.rb
|
40
|
+
homepage: https://github.com/davidsiaw/lm
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata:
|
44
|
+
allowed_push_host: https://rubygems.org
|
45
|
+
homepage_uri: https://github.com/davidsiaw/lm
|
46
|
+
source_code_uri: https://github.com/davidsiaw/lm
|
47
|
+
changelog_uri: https://github.com/davidsiaw/lm
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 2.6.0
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubygems_version: 3.2.3
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: Logic Minimizer
|
67
|
+
test_files:
|
68
|
+
- spec/lm_spec.rb
|
69
|
+
- spec/spec_helper.rb
|