lm 0.1.0 → 0.1.1
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 +4 -4
- data/exe/lm +17 -0
- data/lib/lm/minimizer.rb +43 -1
- data/lib/lm/output_string.rb +6 -1
- data/lib/lm/petrick.rb +7 -1
- data/lib/lm/pos.rb +4 -7
- data/lib/lm/sum.rb +14 -2
- data/lib/lm/version.rb +1 -1
- data/spec/lm_spec.rb +20 -0
- data/spec/sum_spec.rb +57 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abf6ece1cf43b82167d54d7081335b3566d554015cb1bb2fd047fe8b1f660a9d
|
4
|
+
data.tar.gz: f87359a2ae880959e2f222040715f2cbb1f948d38423bcd8b4002252c4c0e066
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fab1cf7ae17461222f1522672ac5cfa59e4e435bfb38e9e80fda14ff9ac8d96c2ee31daf0c184a46efcc15392311068a22deb26b7c2fe4a1f69e3536ef46a77a
|
7
|
+
data.tar.gz: 14c83e23640306290f38f593f2474e90ee0e9690e23c592ea6792d093215fd2ab98ba77bf20c7a4e2c13119e2ab7641e066bd8f8cb4f2085ce592c6fea2562fe
|
data/exe/lm
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "lm"
|
5
|
+
|
6
|
+
args = ARGV[0]
|
7
|
+
|
8
|
+
if args.nil?
|
9
|
+
puts "USAGE: lm <bitpattern>"
|
10
|
+
puts "For example, to provide a bitpattern for an AND gate its 0001"
|
11
|
+
puts "The number of bits are inferred"
|
12
|
+
puts "You can use x for don't care, like lm 0xx1"
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
|
16
|
+
min = Lm::Minimizer.new(args)
|
17
|
+
puts min.shortest.to_s(verilog: "a")
|
data/lib/lm/minimizer.rb
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Lm
|
4
|
+
class Degenerate
|
5
|
+
def initialize(val)
|
6
|
+
@val = val
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s(_ = nil)
|
10
|
+
@val.to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
4
14
|
class Minimizer
|
5
15
|
def initialize(output_str)
|
6
16
|
@output_str = output_str
|
@@ -11,6 +21,8 @@ module Lm
|
|
11
21
|
end
|
12
22
|
|
13
23
|
def canonical
|
24
|
+
return degenerate if degenerate?
|
25
|
+
|
14
26
|
output_string.sop
|
15
27
|
end
|
16
28
|
|
@@ -31,22 +43,52 @@ module Lm
|
|
31
43
|
end
|
32
44
|
|
33
45
|
def reduced_sum
|
34
|
-
pos.expand
|
46
|
+
sum = pos.apply_factorize.expand
|
47
|
+
loop do
|
48
|
+
newsum = sum.reduce
|
49
|
+
return newsum if sum.to_s.length == newsum.to_s.length
|
50
|
+
|
51
|
+
sum = newsum
|
52
|
+
end
|
53
|
+
sum
|
35
54
|
end
|
36
55
|
|
37
56
|
def calculator
|
38
57
|
String122ResultSelector.new(implicants, reduced_sum)
|
39
58
|
end
|
40
59
|
|
60
|
+
def variation
|
61
|
+
@variation ||= @output_str.split("").uniq
|
62
|
+
end
|
63
|
+
|
64
|
+
# degenerate case
|
65
|
+
def degenerate?
|
66
|
+
variation.length == 1
|
67
|
+
end
|
68
|
+
|
69
|
+
def degenerate
|
70
|
+
Degenerate.new(variation.first)
|
71
|
+
end
|
72
|
+
|
41
73
|
def shortest
|
74
|
+
return degenerate if degenerate?
|
75
|
+
|
42
76
|
calculator.shortest
|
43
77
|
end
|
44
78
|
|
79
|
+
def inputlen
|
80
|
+
output_string.bitcount
|
81
|
+
end
|
82
|
+
|
45
83
|
def evaluate(input)
|
84
|
+
return degenerate.to_s.to_i if degenerate?
|
85
|
+
|
46
86
|
BinFunc.new(shortest).evaluate(input)
|
47
87
|
end
|
48
88
|
|
49
89
|
def canonical_evaluate(input)
|
90
|
+
return degenerate.to_s.to_i if degenerate?
|
91
|
+
|
50
92
|
BinFunc.new(output_string.sop).evaluate(input)
|
51
93
|
end
|
52
94
|
end
|
data/lib/lm/output_string.rb
CHANGED
@@ -4,10 +4,14 @@ module Lm
|
|
4
4
|
class OutputString
|
5
5
|
def initialize(str)
|
6
6
|
@str = str
|
7
|
+
|
8
|
+
return unless @str.length < 2
|
9
|
+
|
10
|
+
@str = @str.rjust(2, "0")
|
7
11
|
end
|
8
12
|
|
9
13
|
def bitcount
|
10
|
-
Math.log(@str.length, 2).ceil
|
14
|
+
[Math.log(@str.length, 2).ceil, 1].max
|
11
15
|
end
|
12
16
|
|
13
17
|
def sop
|
@@ -19,6 +23,7 @@ module Lm
|
|
19
23
|
prod = Product.new(bitbreak)
|
20
24
|
res << prod
|
21
25
|
end
|
26
|
+
|
22
27
|
res
|
23
28
|
end
|
24
29
|
|
data/lib/lm/petrick.rb
CHANGED
@@ -67,7 +67,13 @@ module Lm
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def string122
|
70
|
-
factors
|
70
|
+
factors
|
71
|
+
.map do |sums|
|
72
|
+
sums.map do |prducts|
|
73
|
+
prducts.map { |x| (x.ord + 48).chr }.join("")
|
74
|
+
end.join("+")
|
75
|
+
end
|
76
|
+
.join(",")
|
71
77
|
end
|
72
78
|
end
|
73
79
|
end
|
data/lib/lm/pos.rb
CHANGED
@@ -21,7 +21,7 @@ module Lm
|
|
21
21
|
@termhash ||= begin
|
22
22
|
res = {}
|
23
23
|
sum_array.each do |sum|
|
24
|
-
terms = sum.split("+")
|
24
|
+
terms = sum.split("+", 2)
|
25
25
|
terms.each do |term|
|
26
26
|
res[term] ||= Set.new
|
27
27
|
terms.each do |x|
|
@@ -40,13 +40,10 @@ module Lm
|
|
40
40
|
seenkeys = Set.new
|
41
41
|
|
42
42
|
termhash.each do |key, value|
|
43
|
-
next if seenkeys.include?
|
43
|
+
next if seenkeys.include?(([key] + value.to_a).sort.join("|").to_s)
|
44
44
|
|
45
|
-
seenkeys << key
|
46
|
-
value.
|
47
|
-
seenkeys << factor
|
48
|
-
end
|
49
|
-
newarray << "#{key}+#{value.to_a.join("")}"
|
45
|
+
seenkeys << ([key] + value.to_a).sort.join("|")
|
46
|
+
newarray << "#{key}+#{value.map { |x| Sum.new(x) }.inject(:multiply)}"
|
50
47
|
end
|
51
48
|
|
52
49
|
POS.new(newarray.join(","))
|
data/lib/lm/sum.rb
CHANGED
@@ -8,12 +8,21 @@ module Lm
|
|
8
8
|
@str = str
|
9
9
|
end
|
10
10
|
|
11
|
+
def multiply(other_sum)
|
12
|
+
raise "Not a sum" unless other_sum.is_a? Sum
|
13
|
+
|
14
|
+
newarr = product_list.map(&:to_a).product(other_sum.product_list.map(&:to_a))
|
15
|
+
|
16
|
+
newstr = newarr.map { |x| x.join("") }.join("+")
|
17
|
+
Sum.new(newstr)
|
18
|
+
end
|
19
|
+
|
11
20
|
def product_list
|
12
21
|
@str.split("+").map { |x| Set.new(x.split("")) }
|
13
22
|
end
|
14
23
|
|
15
24
|
def by_length
|
16
|
-
product_list.
|
25
|
+
product_list.sort_by(&:length)
|
17
26
|
end
|
18
27
|
|
19
28
|
def reduce
|
@@ -36,8 +45,11 @@ module Lm
|
|
36
45
|
break if arr.length.zero?
|
37
46
|
end
|
38
47
|
|
39
|
-
res
|
40
48
|
Sum.new(res.map { |x| x.to_a.join("") }.join("+"))
|
41
49
|
end
|
50
|
+
|
51
|
+
def to_s
|
52
|
+
@str
|
53
|
+
end
|
42
54
|
end
|
43
55
|
end
|
data/lib/lm/version.rb
CHANGED
data/spec/lm_spec.rb
CHANGED
@@ -37,4 +37,24 @@ RSpec.describe Lm do
|
|
37
37
|
min = Lm::Minimizer.new("1110")
|
38
38
|
expect(min.canonical.to_s(verilog: "a")).to eq "~a[0] & ~a[1] | ~a[0] & a[1] | a[0] & ~a[1]"
|
39
39
|
end
|
40
|
+
|
41
|
+
it "returns degenerate case 0" do
|
42
|
+
min = Lm::Minimizer.new("0")
|
43
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "0"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns degenerate case 00000" do
|
47
|
+
min = Lm::Minimizer.new("00000")
|
48
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "0"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns degenerate case 11" do
|
52
|
+
min = Lm::Minimizer.new("11")
|
53
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "1"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "returns degenerate case 1111111" do
|
57
|
+
min = Lm::Minimizer.new("1111111")
|
58
|
+
expect(min.shortest.to_s(verilog: "a")).to eq "1"
|
59
|
+
end
|
40
60
|
end
|
data/spec/sum_spec.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Lm::Sum do
|
4
|
+
describe "#multiply" do
|
5
|
+
it "does simple multiply" do
|
6
|
+
sop1 = Lm::Sum.new("1")
|
7
|
+
sop2 = Lm::Sum.new("2")
|
8
|
+
|
9
|
+
expect(sop1.multiply(sop2).product_list).to eq [Set.new(%w[1 2])]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "does distribute multiply" do
|
13
|
+
sop1 = Lm::Sum.new("1")
|
14
|
+
sop2 = Lm::Sum.new("2+3")
|
15
|
+
|
16
|
+
expect(sop1.multiply(sop2).product_list).to eq [Set.new(%w[1 2]), Set.new(%w[1 3])]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "does fully multiply" do
|
20
|
+
sop1 = Lm::Sum.new("1+4")
|
21
|
+
sop2 = Lm::Sum.new("2+3")
|
22
|
+
|
23
|
+
expect(sop1.multiply(sop2).product_list).to eq [
|
24
|
+
Set.new(%w[1 2]), Set.new(%w[1 3]),
|
25
|
+
Set.new(%w[4 2]), Set.new(%w[4 3])
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "does fully multiply with more" do
|
30
|
+
sop1 = Lm::Sum.new("1+4")
|
31
|
+
sop2 = Lm::Sum.new("2+3+5")
|
32
|
+
|
33
|
+
expect(sop1.multiply(sop2).product_list).to eq [
|
34
|
+
Set.new(%w[1 2]), Set.new(%w[1 3]), Set.new(%w[1 5]),
|
35
|
+
Set.new(%w[4 2]), Set.new(%w[4 3]), Set.new(%w[4 5])
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "does fully multiply inner" do
|
40
|
+
sop1 = Lm::Sum.new("1+45")
|
41
|
+
sop2 = Lm::Sum.new("2+3")
|
42
|
+
|
43
|
+
expect(sop1.multiply(sop2).product_list).to eq [
|
44
|
+
Set.new(%w[1 2]), Set.new(%w[1 3]),
|
45
|
+
Set.new(%w[4 5 2]), Set.new(%w[4 5 3])
|
46
|
+
]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#to_s" do
|
51
|
+
it "does the right thing" do
|
52
|
+
sop1 = Lm::Sum.new("1+45")
|
53
|
+
sop2 = Lm::Sum.new("2+3").multiply(sop1)
|
54
|
+
expect(sop2.to_s).to eq "21+245+31+345"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
metadata
CHANGED
@@ -1,25 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Siaw
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Logic Minimizer Library
|
14
14
|
email:
|
15
15
|
- davidsiaw@gmail.com
|
16
|
-
executables:
|
16
|
+
executables:
|
17
|
+
- lm
|
17
18
|
extensions: []
|
18
19
|
extra_rdoc_files: []
|
19
20
|
files:
|
20
21
|
- Gemfile
|
21
22
|
- bin/console
|
22
23
|
- bin/setup
|
24
|
+
- exe/lm
|
23
25
|
- lib/lm.rb
|
24
26
|
- lib/lm/bin_func.rb
|
25
27
|
- lib/lm/implicant_chart.rb
|
@@ -37,6 +39,7 @@ files:
|
|
37
39
|
- lm.gemspec
|
38
40
|
- spec/lm_spec.rb
|
39
41
|
- spec/spec_helper.rb
|
42
|
+
- spec/sum_spec.rb
|
40
43
|
homepage: https://github.com/davidsiaw/lm
|
41
44
|
licenses:
|
42
45
|
- MIT
|
@@ -67,3 +70,4 @@ summary: Logic Minimizer
|
|
67
70
|
test_files:
|
68
71
|
- spec/lm_spec.rb
|
69
72
|
- spec/spec_helper.rb
|
73
|
+
- spec/sum_spec.rb
|