lm 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82e0500fd99881105260a6367a282628a4c9bf5365ddc717c219fe39e1df0f19
4
- data.tar.gz: f69499c220e4a27a2a435a6820a708d458491bf0cde568d9fb9c4ddd277f13ed
3
+ metadata.gz: abf6ece1cf43b82167d54d7081335b3566d554015cb1bb2fd047fe8b1f660a9d
4
+ data.tar.gz: f87359a2ae880959e2f222040715f2cbb1f948d38423bcd8b4002252c4c0e066
5
5
  SHA512:
6
- metadata.gz: af2de852aeaf14c17783868468dd34405ccde647db085cc2fd3c1999b91c6b4aac5ec608ed9a15116049840c436979e799f7c3894608c8dd798b727e61940ba1
7
- data.tar.gz: e57c6b4f50c406ca6c1861fa9f530da28706619c3c92d1e1c9fe64e170fa195d3aec9179bfc55331afe238734d857b41a7fab8545a60a3c0cb7e24dc76307f61
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.reduce
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
@@ -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.map { |sums| sums.map { |prducts| prducts.map { |x| (x.ord + 48).chr }.join("") }.join("+") }.join(",")
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? key
43
+ next if seenkeys.include?(([key] + value.to_a).sort.join("|").to_s)
44
44
 
45
- seenkeys << key
46
- value.each do |factor|
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.sort(&:length)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lm
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
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.0
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-23 00:00:00.000000000 Z
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