lm 0.1.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: 82e0500fd99881105260a6367a282628a4c9bf5365ddc717c219fe39e1df0f19
4
+ data.tar.gz: f69499c220e4a27a2a435a6820a708d458491bf0cde568d9fb9c4ddd277f13ed
5
+ SHA512:
6
+ metadata.gz: af2de852aeaf14c17783868468dd34405ccde647db085cc2fd3c1999b91c6b4aac5ec608ed9a15116049840c436979e799f7c3894608c8dd798b727e61940ba1
7
+ data.tar.gz: e57c6b4f50c406ca6c1861fa9f530da28706619c3c92d1e1c9fe64e170fa195d3aec9179bfc55331afe238734d857b41a7fab8545a60a3c0cb7e24dc76307f61
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in lm.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "rubocop", "~> 1.21"
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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lm
4
+ VERSION = "0.1.0"
5
+ end
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
@@ -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