falafel 0.0.0.2 → 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: 821f2ac8523791cce7c4632e69d67a4bee8f208b7e7cf8f1e1e88dbd82e0bc1f
4
- data.tar.gz: b92c2f37f9b2585a5aff6f87307378dbdeb6c452db5ff6dd738cd836f57b4a2a
3
+ metadata.gz: 796b681163a3d9d57b47cadcb95f1d5e2e9af1e97a0b841b2e31ddc9c725769b
4
+ data.tar.gz: 3811e2bc49acfee5aa9a4e4f27569df022fb68c2ddafbafa10b43a7c92afe4d8
5
5
  SHA512:
6
- metadata.gz: a40d294e74954d85c19abe0bcd80c222390b7f3703c6a87d471d8fb30ed89aadd0ab5297f7e02c4521c282e6bd55e31e70cee68482a0d36c2b0572c477e05263
7
- data.tar.gz: 1889ce0c9deb9585907fc663e20d73895051fd054a9289b591f7990a3c3494579ad5fbfce79f9e92153bb4882ca621f25e063e8546346015f15660614902a888
6
+ metadata.gz: 96bf15557a50f7a81c8a71d200a0876f7fc445d64d017d3c2011fa088457d61e05327e8ea39c7147d349049a8e8b3811a815c92e04f414109c4505782a8c6613
7
+ data.tar.gz: 45573ad63969221aed699f9412d45409c4f72a26c1ec3e83e3bcb4c5fba03c6fb9bdae80d61b3c0a046e4c25a66a00e7c64c00a1841142de675e7eaa45158876
data/lib/cfg.rb CHANGED
@@ -1,44 +1,96 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'cyk'
4
+ require_relative 'chomsky_nf'
5
+ require_relative 'epsilon_free'
6
+ require_relative 'chaining_free'
7
+
3
8
  # Samll CFG impletation
4
9
  # Generate words and check if words are the @lang
10
+ # generates random words
5
11
  class CFG
6
- attr_accessor :alphabet, :vars, :start_var, :rules
7
- attr_reader :rnd_words
8
- attr_writer :lang
12
+ attr_accessor :start_var, :rules
13
+ attr_reader :rules_ef, :rules_cf, :rnd_words, :reachables,
14
+ :rules_ef_res, :rules_cf_res, :chomsky_nf_rules,
15
+ :cyk_matrix, :is_in_l
9
16
 
10
17
  def initialize(alphabet, vars, start_var, rules)
11
- @alphabet = alphabet
12
- @vars = vars
13
- @start_var = start_var
14
- @rules = _rules rules
18
+ @start_var = start_var
19
+ @rules = _rules rules
20
+ @rnd_words = []
21
+ @reachables = []
22
+ @vars = vars
23
+ @alphabet = alphabet
24
+ end
25
+
26
+ def generate_words(count)
15
27
  @rnd_words = []
28
+
29
+ loop do
30
+ word = _expand @start_var
31
+
32
+ @rnd_words << word unless @rnd_words.include? word
33
+
34
+ break if @rnd_words.size == count
35
+ end
36
+ end
37
+
38
+ def var_reachable?
39
+ @rules[@start_var].each do |rule|
40
+ @vars.each { |var| @reachables << var if rule.include? var }
41
+ end
42
+ @reachables.uniq!
43
+ end
44
+
45
+ def var_productive?
46
+ ''
47
+ end
48
+
49
+ def var_reduced?
50
+ ''
51
+ end
52
+
53
+ def epsilon_free
54
+ e_free = EpsilonFree.new
55
+ @rules_ef_res = e_free.run @rules
56
+ @rules_ef = e_free.rebuild_rules @rules, @rules_ef_res
16
57
  end
17
58
 
18
- def generate_word
19
- word = _expand @start_var
59
+ def chaining_free
60
+ c_free = ChainingFree.new
61
+ @rules_cf_res = c_free.run @rules, @vars
62
+ @rules_cf = c_free.rebuild_rules @rules_cf_res
63
+ end
20
64
 
21
- return unless @lang.call word
65
+ def chomsky_nf(custom_rule)
66
+ chomsky = ChomskyNF.new
67
+ rules = chomsky.run custom_rule || @rules, @alphabet
22
68
 
23
- @rnd_words << word unless @rnd_words.include? word
69
+ @chomsky_nf_rules = chomsky.simplify rules
24
70
  end
25
71
 
26
- def dyck?(word)
27
- ->(w) { (w.count('a') - w.count('b')).zero? }.call word
72
+ def cyk_run(word)
73
+ cyk = CYK.new word, @chomsky_nf_rules
74
+
75
+ cyk.run
76
+
77
+ @cyk_matrix = cyk.matrix
78
+ @is_in_l = cyk.is_in_l
28
79
  end
29
80
 
30
81
  private
31
82
 
83
+ def _rules(rules)
84
+ rules.each_value { |k| k.each_with_index { |item, index| k[index] = item[0].is_a?(String) ? item[0].split('') : item } }
85
+ end
86
+
32
87
  def _expand(symbol)
33
88
  production = @rules[symbol]
34
89
 
35
90
  return symbol if production.nil?
36
91
 
37
- rhs = production.sample
38
- rhs.map { |s| _expand(s) }.join
39
- end
92
+ rhs = production.sample # pick up a random element from array
40
93
 
41
- def _rules(rules)
42
- rules.each_value { |k| k.each_with_index { |item, index| k[index] = item[0].is_a?(String) ? item[0].split('') : item } }
94
+ rhs.map { |s| _expand(s) }.join
43
95
  end
44
96
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ # remove chaining rules from CFG
4
+ class ChainingFree
5
+ def run(rules, vars)
6
+ @rules = rules
7
+ @vars = vars
8
+ c_r = _chaining_relation
9
+
10
+ # build transivity relation from _chaining_relation(K) as A
11
+ # remove _chaining_relation from rules
12
+ _rebuild_rules + c_r.map { |r| _transitivity_relation r }.reduce(:concat) - c_r
13
+ end
14
+
15
+ def rebuild_rules(current_rules)
16
+ res = {}
17
+
18
+ @vars.each { |v| res[v] = [] }
19
+
20
+ current_rules.each do |l, r|
21
+ res[l] << r.chars unless res[l].include? r.chars
22
+ end
23
+
24
+ res
25
+ end
26
+
27
+ private
28
+
29
+ def _chaining_relation
30
+ rules = _rebuild_rules
31
+
32
+ rules & @vars.product(@vars)
33
+ end
34
+
35
+ def _rebuild_rules
36
+ result = []
37
+ @rules.each do |var, rule|
38
+ rule.map do |r|
39
+ result << [var, r.join]
40
+ end
41
+ end
42
+
43
+ result
44
+ end
45
+
46
+ def _transitivity_relation(pair)
47
+ transitive_relation = [pair]
48
+
49
+ new_pairs = []
50
+
51
+ _rebuild_rules.each do |a, b|
52
+ next unless pair[1] == a && !transitive_relation.include?([pair[0], b])
53
+
54
+ new_pairs << [pair[0], b]
55
+ end
56
+
57
+ transitive_relation.concat new_pairs
58
+ end
59
+
60
+ def _new_pairs(rules)
61
+ rules.each do |a, b|
62
+ next unless pair[1] == a && !transitive_relation.include?([pair[0], b])
63
+
64
+ new_pairs << [pair[0], b]
65
+ end
66
+ end
67
+ end
data/lib/chomsky_nf.rb ADDED
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'chomsky_nf_simplifier'
4
+
5
+ # convert to Chomsky Normal Form
6
+ class ChomskyNF
7
+ def run(rules, alphabet)
8
+ new_rules = {}
9
+ @rules = rules
10
+ @alphabet = alphabet
11
+
12
+ # add cases like (A, a), (B, b)
13
+ _add_single_vars new_rules
14
+
15
+ # change rules like (X, aX) to (X, AX)
16
+ _handle_simple_rule new_rules
17
+
18
+ _handle_all_rule new_rules
19
+ end
20
+
21
+ def simplify(rules)
22
+ simplifier = ChomskyNFSimplifier.new
23
+
24
+ simplifier.run rules, @alphabet
25
+ end
26
+
27
+ private
28
+
29
+ def _add_single_vars(new_rules)
30
+ @rules.values.reduce(:concat).each do |rule|
31
+ rule.select { |var| var == var.downcase }.each do |r|
32
+ new_rules[r.upcase] = r
33
+ end
34
+ end
35
+ end
36
+
37
+ def _handle_simple_rule(new_rules)
38
+ @rules.each do |var, rule|
39
+ new_rules[var] = []
40
+ rule.each do |r|
41
+ next if r.empty?
42
+
43
+ new_rules[var] << r.map(&:upcase)
44
+ end
45
+ end
46
+ end
47
+
48
+ def _handle_all_rule(new_rules)
49
+ new_rules_buffer = {}
50
+
51
+ new_rules.each do |var, rules|
52
+ next if _is_character? rules
53
+
54
+ new_rules_buffer = _new_rules_buffer rules, var
55
+ end
56
+
57
+ new_rules.merge! new_rules_buffer
58
+ end
59
+
60
+ def _is_character?(value)
61
+ value.is_a?(String) && value.length == 1
62
+ end
63
+
64
+ def _new_rules_buffer(rules, var)
65
+ helper_vars = _helper_vars rules
66
+ helper_vars.merge! @alphabet.each_with_object({}) { |ele, meme| meme[ele.capitalize] = ele.capitalize }
67
+
68
+ _new_rules rules, var, helper_vars
69
+ end
70
+
71
+ def _check_simplify(rule, holder, current_var)
72
+ return false unless rule.size == 1
73
+
74
+ holder[current_var] << rule.last unless holder[current_var].include? rule
75
+
76
+ true
77
+ end
78
+
79
+ def _new_rules(rules, var, helper_vars)
80
+ holder = {}
81
+
82
+ rules.each do |rule|
83
+ rest = ''
84
+ rule.each_with_index do |head, index|
85
+ current_var = index.zero? ? var : rest
86
+ holder[current_var] ||= []
87
+
88
+ is_simple = _check_simplify rule, holder, current_var
89
+
90
+ break if is_simple
91
+
92
+ rest = _chomsky_nf_vars index, rule, helper_vars
93
+
94
+ nf_rest = "#{head}#{rest}"
95
+
96
+ if index + 2 == rule.size
97
+ if rest.nil?
98
+ rest = rule.last
99
+ nf_rest += rest
100
+ end
101
+
102
+ holder[current_var] << nf_rest unless holder[current_var].include? nf_rest
103
+
104
+ break
105
+ else
106
+ holder[current_var] << nf_rest unless holder[current_var].include? nf_rest
107
+ end
108
+ end
109
+ end
110
+
111
+ holder
112
+ end
113
+
114
+ def _chomsky_nf_vars(index, rule, helper_vars)
115
+ rule_size = rule.size
116
+ rest = rule[(index + 1)..rule_size].join
117
+
118
+ helper_vars.key(rest)
119
+ end
120
+
121
+ def _helper_vars(rules)
122
+ helper_vars = {}
123
+
124
+ rules.each do |rule|
125
+ rule.each_with_index do |_, index|
126
+ letter, rest = _chomsky_nf_helper_vars index, rule, helper_vars.keys
127
+
128
+ break if index + 2 == rule.size
129
+
130
+ next if helper_vars.values.include? rest
131
+
132
+ helper_vars[letter] = rest unless helper_vars.key?(letter) && rest.size > 1
133
+ end
134
+ end
135
+
136
+ helper_vars
137
+ end
138
+
139
+ def _chomsky_nf_helper_vars(index, rule, helper_vars)
140
+ rule_size = rule.size
141
+ letter = helper_vars.empty? ? _find_letter(index) : helper_vars.sort!.last.succ
142
+ rest = rule[(index + 1)..rule_size].join
143
+
144
+ [letter, rest]
145
+ end
146
+
147
+ def _find_letter(n)
148
+ result = 'H'
149
+ n.times { result = result.succ }
150
+
151
+ result
152
+ end
153
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ # simplify chomsky normal form
4
+ class ChomskyNFSimplifier
5
+ def run(new_rules, alphabet)
6
+ var_has_one_letter = _var_has_one_letter new_rules, alphabet
7
+
8
+ return new_rules if var_has_one_letter.empty?
9
+
10
+ rules = _find_modify_rules new_rules, var_has_one_letter
11
+
12
+ return new_rules if rules.empty?
13
+
14
+ missing_rules = _generate_missing_rules rules, var_has_one_letter
15
+
16
+ _add_missing_rules missing_rules, new_rules
17
+
18
+ new_rules
19
+ end
20
+
21
+ private
22
+
23
+ def _var_has_one_letter(new_rules, alphabet)
24
+ vars = {}
25
+
26
+ new_rules.each do |key, values|
27
+ next if values.size == 1
28
+
29
+ values.each do |val|
30
+ next unless val.size == 1 && alphabet.include?(val.downcase)
31
+
32
+ vars[key] ||= []
33
+ vars[key] << val
34
+ end
35
+ end
36
+
37
+ vars
38
+ end
39
+
40
+ def _find_modify_rules(new_rules, vars)
41
+ modify = {}
42
+
43
+ new_rules.each do |key, val|
44
+ next if val.is_a?(String)
45
+
46
+ val.each do |v|
47
+ vars.each_key do |k|
48
+ next unless v.include?(k)
49
+
50
+ res = val.select { |x| x.include? k }
51
+
52
+ modify[key] ||= []
53
+ modify[key] << res
54
+ end
55
+ end
56
+ end
57
+
58
+ modify
59
+ end
60
+
61
+ def _generate_missing_rules(rules, vars)
62
+ res = {}
63
+
64
+ rules.each do |var_rule, nfs|
65
+ nfs.flatten.each do |nf|
66
+ vars.each do |match_char, replacement_chars|
67
+ replacement_chars.each do |rc|
68
+ new_rules = _combinations nf, rc, match_char
69
+ res[var_rule] ||= []
70
+ res[var_rule] << new_rules
71
+ end
72
+ end
73
+ _check_special_case nf, res, var_rule, vars
74
+ end
75
+ end
76
+
77
+ res
78
+ end
79
+
80
+ def _combinations(original_string, replacement_char, match_char)
81
+ combinations = []
82
+
83
+ 0.upto(1) do |i|
84
+ 0.upto(1) do |j|
85
+ new_rule = original_string.dup
86
+ new_rule[0] = replacement_char if i == 1 && original_string[0] == match_char
87
+ new_rule[1] = replacement_char if j == 1 && original_string[1] == match_char
88
+ combinations << new_rule
89
+ end
90
+ end
91
+
92
+ combinations.uniq
93
+ end
94
+
95
+ def _add_missing_rules(missing_rules, new_rules)
96
+ missing_rules.each { |key, val| new_rules[key] = val.flatten.uniq! }
97
+ end
98
+
99
+ def _check_special_case(nf, res, var_rule, vars)
100
+ vars.each do |match_char, combi|
101
+ next unless nf == match_char * 2
102
+
103
+ missing_rules = combi.map { |lft| combi.map { |rgt| "#{lft}#{rgt}" } }.flatten
104
+
105
+ res[var_rule] << missing_rules
106
+ end
107
+
108
+ res
109
+ end
110
+ end
data/lib/cyk.rb ADDED
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Implemention of cyk algo.
4
+ class CYK
5
+ attr_reader :matrix, :is_in_l
6
+
7
+ def initialize(word, custom_rule)
8
+ @word = word
9
+ @rules = custom_rule.select { |_, val| val.is_a?(Array) }
10
+ @helper_vars = @rules.values.flatten
11
+ end
12
+
13
+ def run
14
+ _cyk_fill_diagonal
15
+ _cyk_fill_matrix
16
+ _is_in_l?
17
+ end
18
+
19
+ private
20
+
21
+ def _cyk_fill_diagonal
22
+ wrd_lng = @word.length
23
+ @matrix = wrd_lng.times.map { wrd_lng.times.map { [] } }
24
+
25
+ (0..wrd_lng - 1).each do |index|
26
+ @matrix[index][index] = @word[index].upcase
27
+ end
28
+ end
29
+
30
+ def _cyk_fill_matrix
31
+ @matrix.size.times do |limiter|
32
+ (0...@matrix.length - limiter).each do |i|
33
+ j = i + limiter
34
+
35
+ next if i == j
36
+
37
+ helper_var = _helper_var i, j
38
+
39
+ @matrix[i][j] = _add_to_matrix helper_var
40
+ end
41
+ end
42
+ end
43
+
44
+ def _helper_var(row, col)
45
+ res = '0'
46
+
47
+ (row..col - 1).step(1) do |h|
48
+ p_ = @matrix[row][h]
49
+ q_ = @matrix[h + 1][col]
50
+ res = "#{p_}#{q_}"
51
+
52
+ break if @helper_vars.include? res
53
+ end
54
+
55
+ res
56
+ end
57
+
58
+ def _add_to_matrix(rule)
59
+ res = '0'
60
+ return if rule == res
61
+
62
+ @rules.each do |key, vals|
63
+ vals.each do |val|
64
+ res = key if val == rule
65
+ end
66
+ end
67
+
68
+ res
69
+ end
70
+
71
+ def _is_in_l?
72
+ @is_in_l = @matrix.first.last == 'S'
73
+ end
74
+ end
data/lib/dfa.rb CHANGED
@@ -53,26 +53,29 @@ class DFA < Falafel
53
53
  (finals & states.keys).each_with_object({}) { |elt, memo| memo[elt] = states[elt] }
54
54
  end
55
55
 
56
- def _r(finals, states, ri)
57
- r = []
58
- @states.each_with_index do |p, _|
59
- @states.each_with_index do |q, _|
60
- if finals.include?(p) == finals.include?(q)
61
- @delta_star.each_key do |c|
62
- ri_set = _ri_set states, c, p, q
63
- r << (ri_set & ri).flatten if (ri_set & ri).any?
64
- end
65
- end
56
+ def _r(finals, states, steps)
57
+ r = []
58
+ last_r = steps["R#{steps.size - 1}"]
59
+
60
+ last_r.each do |pair|
61
+ @delta_star.each_key do |c|
62
+ pair_frst = pair[0]
63
+ pair_lst = pair[1]
64
+
65
+ ri_set = _ri_set states, c, states.key(pair_frst), states.key(pair_lst)
66
+
67
+ break unless last_r.include? ri_set
68
+
69
+ r << [pair_frst, pair_lst] unless r.include? [pair_frst, pair_lst]
66
70
  end
67
71
  end
68
- r.uniq!
69
72
 
70
73
  r
71
74
  end
72
75
 
73
76
  def _steps_builder(finals, states, steps)
74
77
  0.upto(1_000) do |l|
75
- r = _r finals, states, steps["R#{l}"]
78
+ r = _r finals, states, steps
76
79
  steps["R#{l + 1}"] = r
77
80
 
78
81
  return steps if steps["R#{l}"] == r
@@ -95,6 +98,6 @@ class DFA < Falafel
95
98
  lft = states[(_image [p], @delta_star[c])[0]]
96
99
  rgt = states[(_image [q], @delta_star[c])[0]]
97
100
 
98
- [[lft, rgt]]
101
+ [lft, rgt]
99
102
  end
100
103
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # used to clear a CFG from the epsilon rules
4
+ class EpsilonFree
5
+ def run(rules)
6
+ epsilon = _epsilon rules
7
+ rules_ef = {}
8
+
9
+ return if epsilon.empty?
10
+
11
+ epsilon.each do |e_class|
12
+ cleared_rules = _cleared_rules rules[e_class]
13
+ epsilon_free_word = cleared_rules.map(&:join)
14
+ grammer = _grammer_epsilon_free epsilon_free_word, e_class
15
+ rules_ef[e_class] = grammer
16
+ end
17
+
18
+ rules_ef
19
+ end
20
+
21
+ def rebuild_rules(current_rules, rules_epsilon_free)
22
+ missing_vars = current_rules.keys - rules_epsilon_free.keys
23
+
24
+ res = {}
25
+ rules_epsilon_free.each do |key, rules|
26
+ res[key] = []
27
+ rules.each do |rule|
28
+ res[key] << rule.chars
29
+ end
30
+ end
31
+
32
+ missing_vars.each { |v| res[v] = current_rules[v] }
33
+
34
+ res
35
+ end
36
+
37
+ private
38
+
39
+ def _epsilon(rules)
40
+ res = rules.map do |var, rule|
41
+ next unless rule.include? []
42
+
43
+ var
44
+ end
45
+ res.reject(&:nil?)
46
+ end
47
+
48
+ def _cleared_rules(rules)
49
+ rules.reject(&:empty?)
50
+ end
51
+
52
+ def _grammer_epsilon_free(epsilon_free_word, e_class)
53
+ rules_epsilon_location = _new_rules_epsilon_location epsilon_free_word, e_class
54
+
55
+ res = []
56
+ rules_epsilon_location.map do |rule, possibilities|
57
+ possibilities.each do |possibility|
58
+ res << _remove_e_class(possibility, rule.split(''))
59
+ end
60
+
61
+ res << epsilon_free_word.delete(e_class) if possibilities.size == 1
62
+ end
63
+
64
+ res
65
+ end
66
+
67
+ def _new_rules_epsilon_location(s_rule, e_class)
68
+ res = {}
69
+ s_rule.each do |rule|
70
+ s_index = []
71
+ rule.each_char.with_index { |char, index| s_index << index if char == e_class }
72
+ res[rule] = _power_set(s_index)
73
+ end
74
+
75
+ res
76
+ end
77
+
78
+ def _power_set(set)
79
+ if set.empty?
80
+ [[]]
81
+ else
82
+ element = set[0]
83
+ subsets = _power_set set[1..]
84
+ subsets + subsets.map { |subset| [element] + subset }
85
+ end
86
+ end
87
+
88
+ def _remove_e_class(possibility, cleared_rules)
89
+ return cleared_rules.join '' if possibility.empty?
90
+
91
+ new_rule = cleared_rules.join ''
92
+ possibility.reverse.each { |index| new_rule.slice! index }
93
+
94
+ new_rule
95
+ end
96
+ end
data/lib/falafel.rb CHANGED
@@ -2,9 +2,13 @@
2
2
 
3
3
  require_relative 'rx'
4
4
 
5
- # Convert NFA to DFA
5
+ # NFA to DFA
6
6
  # DFA to REG
7
7
  # Minimize DFA
8
+ # Remove epsilons from CFG
9
+ # Remove chaining from CFG
10
+ # Find a chomsky normal form fro CFG
11
+ # Apply CYK alogrithm on CFG and solve word problem
8
12
  class Falafel
9
13
  def self.new
10
14
  instance = allocate
@@ -86,7 +90,7 @@ class Falafel
86
90
  end
87
91
 
88
92
  def nfa_to_reg
89
- RX.new { |rx| rx.build @states, @delta_star }
93
+ RX.new { |rx| rx.build @states, @delta_star, @start, @finals }
90
94
  end
91
95
 
92
96
  def dfa_to_min(automat)
data/lib/rx.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  # Regex string builder
4
4
  class RX
5
+ attr_reader :final_reg
6
+
5
7
  def self.new
6
8
  instance = allocate
7
9
  yield instance
@@ -9,31 +11,52 @@ class RX
9
11
  instance
10
12
  end
11
13
 
12
- def build(states, delta_star)
14
+ def build(states, delta_star, start, finals)
13
15
  @states = states
14
16
  @delta_star = delta_star
17
+ @start = start
18
+ @finals = finals
15
19
  @empty = "\u2205"
16
20
  _to_reg
17
21
  end
18
22
 
23
+ def print_matrix
24
+ @steps.each do |key, value|
25
+ puts key
26
+ value.transpose.each do |column|
27
+ column.each do |element|
28
+ printf("\t|%-#{value.map { |c| c.max_by(&:length).length }.max}s", element)
29
+ end
30
+ puts '|'
31
+ end
32
+ end
33
+ _final_reg
34
+ end
35
+
36
+ def _final_reg
37
+ start = @start[0] - 1
38
+ final = @finals[0] - 1
39
+ lang = @steps["l#{@steps.size - 1}"]
40
+ @final_reg = lang[start][final]
41
+ end
42
+
19
43
  private
20
44
 
21
45
  def _to_reg
22
46
  l0 = _l0
23
- steps = {}
24
- steps['l0'] = l0
47
+ @steps = {}
48
+ @steps['l0'] = l0
25
49
 
26
50
  @states.size.times do |h|
27
51
  l = []
28
52
  @states.each_with_index do |_, p|
29
53
  l[p] = []
30
54
  @states.each_with_index do |_, q|
31
- l[p][q] = _l steps["l#{h}"], p, q, steps.size - 1
55
+ l[p][q] = _l @steps["l#{h}"], p, q, @steps.size - 1
32
56
  end
33
57
  end
34
- steps["l#{steps.size}"] = l
58
+ @steps["l#{@steps.size}"] = l
35
59
  end
36
- _print_matrix steps
37
60
  end
38
61
 
39
62
  def _l0
@@ -138,17 +161,4 @@ class RX
138
161
 
139
162
  rgt
140
163
  end
141
-
142
- def _print_matrix(steps)
143
- steps.each do |key, value|
144
- puts key
145
- max_width = value.map { |column| column.max_by(&:length).length }.max
146
- value.transpose.each do |column|
147
- column.each do |element|
148
- printf("\t|%-#{max_width}s", element)
149
- end
150
- puts '|'
151
- end
152
- end
153
- end
154
164
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: falafel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0.2
4
+ version: 0.0.1.1
5
5
  platform: ruby
6
6
  authors:
7
- - Abed A
7
+ - Abed Alkedda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-21 00:00:00.000000000 Z
11
+ date: 2023-08-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -17,12 +17,18 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - lib/cfg.rb
20
+ - lib/chaining_free.rb
21
+ - lib/chomsky_nf.rb
22
+ - lib/chomsky_nf_simplifier.rb
23
+ - lib/cyk.rb
20
24
  - lib/dfa.rb
25
+ - lib/epsilon_free.rb
21
26
  - lib/falafel.rb
22
27
  - lib/pump.rb
23
28
  - lib/rx.rb
24
- homepage:
25
- licenses: []
29
+ homepage: https://github.com/AbedAlkedda/AFS
30
+ licenses:
31
+ - Ruby
26
32
  metadata: {}
27
33
  post_install_message:
28
34
  rdoc_options: []
@@ -42,5 +48,5 @@ requirements: []
42
48
  rubygems_version: 3.3.26
43
49
  signing_key:
44
50
  specification_version: 4
45
- summary: Falafel is a gem to help you understand autotool better, hopefully
51
+ summary: Falafel is a gem to help you understand Automata better, hopefully
46
52
  test_files: []